summaryrefslogtreecommitdiff
path: root/sc/source/filter
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter')
-rw-r--r--sc/source/filter/dif/difexp.cxx319
-rw-r--r--sc/source/filter/dif/difimp.cxx994
-rw-r--r--sc/source/filter/excel/colrowst.cxx364
-rw-r--r--sc/source/filter/excel/excdoc.cxx827
-rw-r--r--sc/source/filter/excel/excel.cxx298
-rw-r--r--sc/source/filter/excel/excform.cxx1944
-rw-r--r--sc/source/filter/excel/excform8.cxx1681
-rw-r--r--sc/source/filter/excel/excimp8.cxx859
-rw-r--r--sc/source/filter/excel/excrecds.cxx1060
-rw-r--r--sc/source/filter/excel/exctools.cxx296
-rw-r--r--sc/source/filter/excel/expop2.cxx151
-rw-r--r--sc/source/filter/excel/fontbuff.cxx165
-rw-r--r--sc/source/filter/excel/frmbase.cxx248
-rw-r--r--sc/source/filter/excel/impop.cxx1336
-rw-r--r--sc/source/filter/excel/namebuff.cxx346
-rw-r--r--sc/source/filter/excel/ooxml-export-TODO.txt148
-rw-r--r--sc/source/filter/excel/read.cxx1307
-rw-r--r--sc/source/filter/excel/tokstack.cxx881
-rw-r--r--sc/source/filter/excel/xechart.cxx3525
-rw-r--r--sc/source/filter/excel/xecontent.cxx1496
-rw-r--r--sc/source/filter/excel/xeescher.cxx1641
-rw-r--r--sc/source/filter/excel/xeformula.cxx2629
-rw-r--r--sc/source/filter/excel/xehelper.cxx1127
-rw-r--r--sc/source/filter/excel/xelink.cxx2367
-rw-r--r--sc/source/filter/excel/xename.cxx767
-rw-r--r--sc/source/filter/excel/xepage.cxx436
-rw-r--r--sc/source/filter/excel/xepivot.cxx1971
-rw-r--r--sc/source/filter/excel/xerecord.cxx304
-rw-r--r--sc/source/filter/excel/xeroot.cxx319
-rw-r--r--sc/source/filter/excel/xestream.cxx1221
-rw-r--r--sc/source/filter/excel/xestring.cxx606
-rw-r--r--sc/source/filter/excel/xestyle.cxx2860
-rw-r--r--sc/source/filter/excel/xetable.cxx2443
-rw-r--r--sc/source/filter/excel/xeview.cxx540
-rw-r--r--sc/source/filter/excel/xichart.cxx4332
-rw-r--r--sc/source/filter/excel/xicontent.cxx1329
-rw-r--r--sc/source/filter/excel/xiescher.cxx4206
-rw-r--r--sc/source/filter/excel/xiformula.cxx129
-rw-r--r--sc/source/filter/excel/xihelper.cxx893
-rw-r--r--sc/source/filter/excel/xilink.cxx952
-rw-r--r--sc/source/filter/excel/xiname.cxx279
-rw-r--r--sc/source/filter/excel/xipage.cxx392
-rw-r--r--sc/source/filter/excel/xipivot.cxx1678
-rw-r--r--sc/source/filter/excel/xiroot.cxx311
-rw-r--r--sc/source/filter/excel/xistream.cxx1142
-rw-r--r--sc/source/filter/excel/xistring.cxx215
-rw-r--r--sc/source/filter/excel/xistyle.cxx2000
-rw-r--r--sc/source/filter/excel/xiview.cxx309
-rw-r--r--sc/source/filter/excel/xladdress.cxx165
-rw-r--r--sc/source/filter/excel/xlchart.cxx1351
-rw-r--r--sc/source/filter/excel/xlescher.cxx382
-rw-r--r--sc/source/filter/excel/xlformula.cxx788
-rw-r--r--sc/source/filter/excel/xlpage.cxx277
-rw-r--r--sc/source/filter/excel/xlpivot.cxx1028
-rw-r--r--sc/source/filter/excel/xlroot.cxx440
-rw-r--r--sc/source/filter/excel/xlstyle.cxx1772
-rw-r--r--sc/source/filter/excel/xltoolbar.cxx447
-rw-r--r--sc/source/filter/excel/xltoolbar.hxx127
-rw-r--r--sc/source/filter/excel/xltools.cxx750
-rw-r--r--sc/source/filter/excel/xltracer.cxx266
-rw-r--r--sc/source/filter/excel/xlview.cxx117
-rw-r--r--sc/source/filter/ftools/fapihelper.cxx420
-rw-r--r--sc/source/filter/ftools/fprogressbar.cxx253
-rw-r--r--sc/source/filter/ftools/ftools.cxx410
-rw-r--r--sc/source/filter/html/htmlexp.cxx1338
-rw-r--r--sc/source/filter/html/htmlexp2.cxx251
-rw-r--r--sc/source/filter/html/htmlimp.cxx263
-rw-r--r--sc/source/filter/html/htmlpars.cxx3002
-rw-r--r--sc/source/filter/inc/XclExpChangeTrack.hxx679
-rw-r--r--sc/source/filter/inc/XclImpChangeTrack.hxx198
-rw-r--r--sc/source/filter/inc/biff.hxx66
-rw-r--r--sc/source/filter/inc/colrowst.hxx91
-rw-r--r--sc/source/filter/inc/decl.h46
-rw-r--r--sc/source/filter/inc/dif.hxx204
-rw-r--r--sc/source/filter/inc/eeimport.hxx71
-rw-r--r--sc/source/filter/inc/eeparser.hxx149
-rw-r--r--sc/source/filter/inc/excdefs.hxx108
-rw-r--r--sc/source/filter/inc/excdoc.hxx123
-rw-r--r--sc/source/filter/inc/excform.hxx162
-rw-r--r--sc/source/filter/inc/excimp8.hxx163
-rw-r--r--sc/source/filter/inc/excrecds.hxx511
-rw-r--r--sc/source/filter/inc/excscen.hxx89
-rw-r--r--sc/source/filter/inc/exp_op.hxx134
-rw-r--r--sc/source/filter/inc/expbase.hxx84
-rw-r--r--sc/source/filter/inc/fapihelper.hxx350
-rw-r--r--sc/source/filter/inc/filt_pch.hxx313
-rw-r--r--sc/source/filter/inc/fkttab.h48
-rw-r--r--sc/source/filter/inc/flttypes.hxx53
-rw-r--r--sc/source/filter/inc/formel.hxx202
-rw-r--r--sc/source/filter/inc/fprogressbar.hxx246
-rw-r--r--sc/source/filter/inc/ftools.hxx341
-rw-r--r--sc/source/filter/inc/funktion.h52
-rw-r--r--sc/source/filter/inc/htmlexp.hxx177
-rw-r--r--sc/source/filter/inc/htmlimp.hxx55
-rw-r--r--sc/source/filter/inc/htmlpars.hxx640
-rw-r--r--sc/source/filter/inc/imp_op.hxx209
-rw-r--r--sc/source/filter/inc/lotattr.hxx159
-rw-r--r--sc/source/filter/inc/lotfntbf.hxx114
-rw-r--r--sc/source/filter/inc/lotform.hxx134
-rw-r--r--sc/source/filter/inc/lotimpop.hxx171
-rw-r--r--sc/source/filter/inc/lotrange.hxx169
-rw-r--r--sc/source/filter/inc/namebuff.hxx358
-rw-r--r--sc/source/filter/inc/op.h72
-rw-r--r--sc/source/filter/inc/optab.h54
-rw-r--r--sc/source/filter/inc/otlnbuff.hxx62
-rw-r--r--sc/source/filter/inc/qpro.hxx61
-rw-r--r--sc/source/filter/inc/qproform.hxx89
-rw-r--r--sc/source/filter/inc/qprostyle.hxx72
-rw-r--r--sc/source/filter/inc/root.hxx121
-rw-r--r--sc/source/filter/inc/rtfexp.hxx54
-rw-r--r--sc/source/filter/inc/rtfimp.hxx44
-rw-r--r--sc/source/filter/inc/rtfparse.hxx92
-rw-r--r--sc/source/filter/inc/scflt.hxx766
-rw-r--r--sc/source/filter/inc/scfobj.hxx47
-rw-r--r--sc/source/filter/inc/scmem.h39
-rw-r--r--sc/source/filter/inc/tokstack.hxx416
-rw-r--r--sc/source/filter/inc/tool.h166
-rw-r--r--sc/source/filter/inc/xcl97dum.hxx93
-rw-r--r--sc/source/filter/inc/xcl97esc.hxx214
-rw-r--r--sc/source/filter/inc/xcl97rec.hxx627
-rw-r--r--sc/source/filter/inc/xechart.hxx1287
-rw-r--r--sc/source/filter/inc/xecontent.hxx356
-rw-r--r--sc/source/filter/inc/xeescher.hxx485
-rw-r--r--sc/source/filter/inc/xeformula.hxx100
-rw-r--r--sc/source/filter/inc/xehelper.hxx451
-rw-r--r--sc/source/filter/inc/xelink.hxx222
-rw-r--r--sc/source/filter/inc/xename.hxx92
-rw-r--r--sc/source/filter/inc/xepage.hxx139
-rw-r--r--sc/source/filter/inc/xepivot.hxx488
-rw-r--r--sc/source/filter/inc/xerecord.hxx422
-rw-r--r--sc/source/filter/inc/xeroot.hxx182
-rw-r--r--sc/source/filter/inc/xestream.hxx361
-rw-r--r--sc/source/filter/inc/xestring.hxx301
-rw-r--r--sc/source/filter/inc/xestyle.hxx742
-rw-r--r--sc/source/filter/inc/xetable.hxx1070
-rw-r--r--sc/source/filter/inc/xeview.hxx182
-rw-r--r--sc/source/filter/inc/xichart.hxx1526
-rw-r--r--sc/source/filter/inc/xicontent.hxx348
-rw-r--r--sc/source/filter/inc/xiescher.hxx1315
-rw-r--r--sc/source/filter/inc/xiformula.hxx71
-rw-r--r--sc/source/filter/inc/xihelper.hxx355
-rw-r--r--sc/source/filter/inc/xilink.hxx235
-rw-r--r--sc/source/filter/inc/xiname.hxx102
-rw-r--r--sc/source/filter/inc/xipage.hxx84
-rw-r--r--sc/source/filter/inc/xipivot.hxx467
-rw-r--r--sc/source/filter/inc/xiroot.hxx228
-rw-r--r--sc/source/filter/inc/xistream.hxx532
-rw-r--r--sc/source/filter/inc/xistring.hxx123
-rw-r--r--sc/source/filter/inc/xistyle.hxx683
-rw-r--r--sc/source/filter/inc/xiview.hxx97
-rw-r--r--sc/source/filter/inc/xladdress.hxx199
-rw-r--r--sc/source/filter/inc/xlchart.hxx1525
-rw-r--r--sc/source/filter/inc/xlconst.hxx266
-rw-r--r--sc/source/filter/inc/xlcontent.hxx196
-rw-r--r--sc/source/filter/inc/xlescher.hxx462
-rw-r--r--sc/source/filter/inc/xlformula.hxx572
-rw-r--r--sc/source/filter/inc/xllink.hxx95
-rw-r--r--sc/source/filter/inc/xlname.hxx77
-rw-r--r--sc/source/filter/inc/xlpage.hxx163
-rw-r--r--sc/source/filter/inc/xlpivot.hxx784
-rw-r--r--sc/source/filter/inc/xlroot.hxx300
-rw-r--r--sc/source/filter/inc/xlstream.hxx55
-rw-r--r--sc/source/filter/inc/xlstring.hxx99
-rw-r--r--sc/source/filter/inc/xlstyle.hxx623
-rw-r--r--sc/source/filter/inc/xltable.hxx180
-rw-r--r--sc/source/filter/inc/xltools.hxx280
-rw-r--r--sc/source/filter/inc/xltracer.hxx149
-rw-r--r--sc/source/filter/inc/xlview.hxx181
-rw-r--r--sc/source/filter/lotus/expop.cxx414
-rw-r--r--sc/source/filter/lotus/export.cxx60
-rw-r--r--sc/source/filter/lotus/filter.cxx250
-rw-r--r--sc/source/filter/lotus/lotattr.cxx273
-rw-r--r--sc/source/filter/lotus/lotform.cxx2076
-rw-r--r--sc/source/filter/lotus/lotimpop.cxx475
-rw-r--r--sc/source/filter/lotus/lotread.cxx326
-rw-r--r--sc/source/filter/lotus/lotus.cxx104
-rw-r--r--sc/source/filter/lotus/memory.cxx142
-rw-r--r--sc/source/filter/lotus/op.cxx668
-rw-r--r--sc/source/filter/lotus/optab.cxx251
-rw-r--r--sc/source/filter/lotus/tool.cxx654
-rw-r--r--sc/source/filter/qpro/biff.cxx106
-rw-r--r--sc/source/filter/qpro/qpro.cxx233
-rw-r--r--sc/source/filter/qpro/qproform.cxx749
-rw-r--r--sc/source/filter/qpro/qprostyle.cxx171
-rw-r--r--sc/source/filter/rtf/eeimpars.cxx645
-rw-r--r--sc/source/filter/rtf/expbase.cxx108
-rw-r--r--sc/source/filter/rtf/rtfexp.cxx277
-rw-r--r--sc/source/filter/rtf/rtfimp.cxx77
-rw-r--r--sc/source/filter/rtf/rtfparse.cxx434
-rw-r--r--sc/source/filter/starcalc/scflt.cxx2406
-rw-r--r--sc/source/filter/starcalc/scfobj.cxx106
-rw-r--r--sc/source/filter/xcl97/XclExpChangeTrack.cxx1706
-rw-r--r--sc/source/filter/xcl97/XclImpChangeTrack.cxx504
-rw-r--r--sc/source/filter/xcl97/xcl97dum.cxx165
-rw-r--r--sc/source/filter/xcl97/xcl97esc.cxx554
-rw-r--r--sc/source/filter/xcl97/xcl97rec.cxx1752
-rw-r--r--sc/source/filter/xml/XMLCalculationSettingsContext.cxx275
-rw-r--r--sc/source/filter/xml/XMLCalculationSettingsContext.hxx114
-rw-r--r--sc/source/filter/xml/XMLCellRangeSourceContext.cxx135
-rw-r--r--sc/source/filter/xml/XMLCellRangeSourceContext.hxx82
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx765
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx101
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx938
-rw-r--r--sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx252
-rw-r--r--sc/source/filter/xml/XMLCodeNameProvider.cxx208
-rw-r--r--sc/source/filter/xml/XMLCodeNameProvider.hxx73
-rw-r--r--sc/source/filter/xml/XMLColumnRowGroupExport.cxx189
-rw-r--r--sc/source/filter/xml/XMLColumnRowGroupExport.hxx75
-rw-r--r--sc/source/filter/xml/XMLConsolidationContext.cxx161
-rw-r--r--sc/source/filter/xml/XMLConsolidationContext.hxx75
-rw-r--r--sc/source/filter/xml/XMLConverter.cxx665
-rw-r--r--sc/source/filter/xml/XMLConverter.hxx176
-rw-r--r--sc/source/filter/xml/XMLDDELinksContext.cxx495
-rw-r--r--sc/source/filter/xml/XMLDDELinksContext.hxx233
-rw-r--r--sc/source/filter/xml/XMLDetectiveContext.cxx266
-rw-r--r--sc/source/filter/xml/XMLDetectiveContext.hxx177
-rw-r--r--sc/source/filter/xml/XMLEmptyContext.cxx66
-rw-r--r--sc/source/filter/xml/XMLEmptyContext.hxx60
-rw-r--r--sc/source/filter/xml/XMLExportDDELinks.cxx198
-rw-r--r--sc/source/filter/xml/XMLExportDDELinks.hxx55
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.cxx903
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.hxx82
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.cxx1223
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.hxx64
-rw-r--r--sc/source/filter/xml/XMLExportIterator.cxx895
-rw-r--r--sc/source/filter/xml/XMLExportIterator.hxx417
-rw-r--r--sc/source/filter/xml/XMLExportSharedData.cxx166
-rw-r--r--sc/source/filter/xml/XMLExportSharedData.hxx92
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.cxx1280
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.hxx305
-rw-r--r--sc/source/filter/xml/XMLStylesImportHelper.cxx577
-rw-r--r--sc/source/filter/xml/XMLStylesImportHelper.hxx197
-rw-r--r--sc/source/filter/xml/XMLTableHeaderFooterContext.cxx272
-rw-r--r--sc/source/filter/xml/XMLTableHeaderFooterContext.hxx117
-rw-r--r--sc/source/filter/xml/XMLTableMasterPageExport.cxx180
-rw-r--r--sc/source/filter/xml/XMLTableMasterPageExport.hxx68
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.cxx222
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.hxx65
-rw-r--r--sc/source/filter/xml/XMLTableShapeResizer.cxx160
-rw-r--r--sc/source/filter/xml/XMLTableShapeResizer.hxx71
-rw-r--r--sc/source/filter/xml/XMLTableShapesContext.cxx89
-rw-r--r--sc/source/filter/xml/XMLTableShapesContext.hxx58
-rw-r--r--sc/source/filter/xml/XMLTableSourceContext.cxx147
-rw-r--r--sc/source/filter/xml/XMLTableSourceContext.hxx66
-rw-r--r--sc/source/filter/xml/XMLTextPContext.cxx226
-rw-r--r--sc/source/filter/xml/XMLTextPContext.hxx75
-rw-r--r--sc/source/filter/xml/XMLTrackedChangesContext.cxx2008
-rw-r--r--sc/source/filter/xml/XMLTrackedChangesContext.hxx64
-rw-r--r--sc/source/filter/xml/cachedattraccess.cxx72
-rw-r--r--sc/source/filter/xml/cachedattraccess.hxx66
-rw-r--r--sc/source/filter/xml/sheetdata.cxx285
-rw-r--r--sc/source/filter/xml/xmlannoi.cxx211
-rw-r--r--sc/source/filter/xml/xmlannoi.hxx124
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx312
-rw-r--r--sc/source/filter/xml/xmlbodyi.hxx67
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx1132
-rw-r--r--sc/source/filter/xml/xmlcelli.hxx132
-rw-r--r--sc/source/filter/xml/xmlcoli.cxx312
-rw-r--r--sc/source/filter/xml/xmlcoli.hxx96
-rw-r--r--sc/source/filter/xml/xmlconti.cxx110
-rw-r--r--sc/source/filter/xml/xmlconti.hxx66
-rw-r--r--sc/source/filter/xml/xmlcvali.cxx699
-rw-r--r--sc/source/filter/xml/xmlcvali.hxx64
-rw-r--r--sc/source/filter/xml/xmldpimp.cxx1851
-rw-r--r--sc/source/filter/xml/xmldpimp.hxx698
-rw-r--r--sc/source/filter/xml/xmldrani.cxx1216
-rw-r--r--sc/source/filter/xml/xmldrani.hxx371
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx4459
-rw-r--r--sc/source/filter/xml/xmlexprt.hxx287
-rw-r--r--sc/source/filter/xml/xmlexternaltabi.cxx440
-rw-r--r--sc/source/filter/xml/xmlexternaltabi.hxx179
-rw-r--r--sc/source/filter/xml/xmlfilti.cxx787
-rw-r--r--sc/source/filter/xml/xmlfilti.hxx313
-rw-r--r--sc/source/filter/xml/xmlfonte.cxx155
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx3187
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx1061
-rw-r--r--sc/source/filter/xml/xmllabri.cxx147
-rw-r--r--sc/source/filter/xml/xmllabri.hxx93
-rw-r--r--sc/source/filter/xml/xmlnexpi.cxx245
-rw-r--r--sc/source/filter/xml/xmlnexpi.hxx156
-rw-r--r--sc/source/filter/xml/xmlrowi.cxx362
-rw-r--r--sc/source/filter/xml/xmlrowi.hxx96
-rw-r--r--sc/source/filter/xml/xmlsceni.cxx177
-rw-r--r--sc/source/filter/xml/xmlsceni.hxx73
-rw-r--r--sc/source/filter/xml/xmlsorti.cxx281
-rw-r--r--sc/source/filter/xml/xmlsorti.hxx109
-rw-r--r--sc/source/filter/xml/xmlstyle.cxx1952
-rw-r--r--sc/source/filter/xml/xmlstyle.hxx363
-rw-r--r--sc/source/filter/xml/xmlstyli.cxx1092
-rw-r--r--sc/source/filter/xml/xmlstyli.hxx331
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx831
-rw-r--r--sc/source/filter/xml/xmlsubti.hxx208
-rw-r--r--sc/source/filter/xml/xmltabi.cxx506
-rw-r--r--sc/source/filter/xml/xmltabi.hxx103
-rw-r--r--sc/source/filter/xml/xmlwrap.cxx968
295 files changed, 156954 insertions, 0 deletions
diff --git a/sc/source/filter/dif/difexp.cxx b/sc/source/filter/dif/difexp.cxx
new file mode 100644
index 000000000000..9ebf05f31080
--- /dev/null
+++ b/sc/source/filter/dif/difexp.cxx
@@ -0,0 +1,319 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <rtl/math.hxx>
+
+#include <stdio.h>
+
+#include "dif.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "progress.hxx"
+#include <rtl/tencinfo.h>
+#include "ftools.hxx"
+
+FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc,
+ const ScAddress& rOutPos, const CharSet eNach, sal_uInt32 nDifOption )
+{
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow );
+ ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() );
+ ScAddress aStart( rOutPos );
+
+ aStart.PutInOrder( aEnd );
+
+ return ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach, nDifOption );
+}
+
+
+FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc,
+ const ScRange&rRange, const CharSet eCharSet, sal_uInt32 nDifOption )
+{
+ DBG_ASSERT( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range unsortiert!" );
+ DBG_ASSERTWARNING( rRange.aStart.Tab() == rRange.aEnd.Tab(),
+ "ScExportDif(): nur eine Tabelle bidde!" );
+
+ const CharSet eStreamCharSet = rOut.GetStreamCharSet();
+ if ( eStreamCharSet != eCharSet )
+ rOut.SetStreamCharSet( eCharSet );
+
+ sal_Unicode cStrDelim('"');
+ ByteString aStrDelimEncoded; // only used if not Unicode
+ UniString aStrDelimDecoded; // only used if context encoding
+ sal_Bool bContextOrNotAsciiEncoding;
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ rOut.StartWritingUnicodeText();
+ bContextOrNotAsciiEncoding = false;
+ }
+ else
+ {
+ aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
+ rtl_TextEncodingInfo aInfo;
+ aInfo.StructSize = sizeof(aInfo);
+ if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
+ {
+ bContextOrNotAsciiEncoding =
+ (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
+ ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
+ if ( bContextOrNotAsciiEncoding )
+ aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
+ }
+ else
+ bContextOrNotAsciiEncoding = false;
+ }
+
+ const sal_Char* p2DoubleQuotes_LF = "\"\"\n";
+ const sal_Char* pSpecDataType_LF = "-1,0\n";
+ const sal_Char* pEmptyData = "1,0\n\"\"\n";
+ const sal_Char* pStringData = "1,0\n";
+ const sal_Char* pNumData = "0,";
+ const sal_Char* pNumDataERROR = "0,0\nERROR\n";
+
+ FltError eRet = eERR_OK;
+ String aOS;
+ String aString;
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1;
+ SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ double fVal;
+
+ const sal_Bool bPlain = ( nDifOption == SC_DIFOPT_PLAIN );
+
+ ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), nNumRows );
+
+ aPrgrsBar.SetState( 0 );
+
+ // TABLE
+ DBG_ASSERT( pDoc->HasTable( nTab ), "*ScExportDif(): Tabelle nicht vorhanden!" );
+
+ aOS = pKeyTABLE;
+ aOS.AppendAscii( "\n0,1\n\"" );
+
+ pDoc->GetName( nTab, aString );
+ aOS += aString;
+ aOS.AppendAscii( "\"\n" );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // VECTORS
+ aOS = pKeyVECTORS;
+ aOS.AppendAscii( "\n0," );
+ aOS += String::CreateFromInt32( nNumCols );
+ aOS += sal_Unicode('\n');
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // TUPLES
+ aOS = pKeyTUPLES;
+ aOS.AppendAscii( "\n0," );
+ aOS += String::CreateFromInt32( nNumRows );
+ aOS += sal_Unicode('\n');
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // DATA
+ aOS = pKeyDATA;
+ aOS.AppendAscii( "\n0,0\n" );
+ aOS.AppendAscii( p2DoubleQuotes_LF );
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ ScBaseCell* pAkt;
+
+ for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ )
+ {
+ aOS.AssignAscii( pSpecDataType_LF );
+ aOS += pKeyBOT;
+ aOS += sal_Unicode('\n');
+ rOut.WriteUnicodeOrByteText( aOS );
+ for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ )
+ {
+ bool bWriteStringData = false;
+ pDoc->GetCell( nColCnt, nRowCnt, nTab, pAkt );
+ if( pAkt )
+ {
+ switch( pAkt->GetCellType() )
+ {
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ aOS.AssignAscii( pEmptyData );
+ break;
+ case CELLTYPE_VALUE:
+ aOS.AssignAscii( pNumData );
+ if( bPlain )
+ {
+ fVal = ( ( ScValueCell * ) pAkt )->GetValue();
+ aOS += String( ::rtl::math::doubleToUString(
+ fVal, rtl_math_StringFormat_G, 14, '.',
+ sal_True));
+ }
+ else
+ {
+ pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
+ aOS += aString;
+ }
+ aOS.AppendAscii( "\nV\n" );
+ break;
+ case CELLTYPE_EDIT:
+ ( ( ScEditCell* ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ break;
+ case CELLTYPE_STRING:
+ ( ( ScStringCell* ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ break;
+ case CELLTYPE_FORMULA:
+ if ( ((ScFormulaCell*)pAkt)->GetErrCode() )
+ aOS.AssignAscii( pNumDataERROR );
+ else if( pAkt->HasValueData() )
+ {
+ aOS.AssignAscii( pNumData );
+ if( bPlain )
+ {
+ fVal = ( ( ScFormulaCell * ) pAkt )->GetValue();
+ aOS += String( ::rtl::math::doubleToUString(
+ fVal, rtl_math_StringFormat_G, 14,
+ '.', sal_True));
+ }
+ else
+ {
+ pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
+ aOS += aString;
+ }
+ aOS.AppendAscii( "\nV\n" );
+ }
+ else if( pAkt->HasStringData() )
+ {
+ ( ( ScFormulaCell * ) pAkt )->GetString( aString );
+ bWriteStringData = true;
+ }
+ else
+ aOS.AssignAscii( pNumDataERROR );
+
+ break;
+ default:;
+ }
+ }
+ else
+ aOS.AssignAscii( pEmptyData );
+
+ if ( !bWriteStringData )
+ rOut.WriteUnicodeOrByteText( aOS );
+ else
+ {
+ // for an explanation why this complicated, see
+ // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
+ // In fact we should create a common method if this would be
+ // needed just one more time..
+ aOS.AssignAscii( pStringData );
+ rOut.WriteUnicodeOrByteText( aOS, eCharSet );
+ if ( eCharSet == RTL_TEXTENCODING_UNICODE )
+ {
+ xub_StrLen nPos = aString.Search( cStrDelim );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aString.Insert( cStrDelim, nPos );
+ nPos = aString.Search( cStrDelim, nPos+2 );
+ }
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rOut.WriteUnicodeText( aString );
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else if ( bContextOrNotAsciiEncoding )
+ {
+ // to byte encoding
+ ByteString aStrEnc( aString, eCharSet );
+ // back to Unicode
+ UniString aStrDec( aStrEnc, eCharSet );
+ // search on re-decoded string
+ xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrDec.Insert( aStrDelimDecoded, nPos );
+ nPos = aStrDec.Search( aStrDelimDecoded,
+ nPos+1+aStrDelimDecoded.Len() );
+ }
+ // write byte re-encoded
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ rOut.WriteUnicodeOrByteText( aStrDec, eCharSet );
+ rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
+ }
+ else
+ {
+ ByteString aStrEnc( aString, eCharSet );
+ // search on encoded string
+ xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
+ while ( nPos != STRING_NOTFOUND )
+ {
+ aStrEnc.Insert( aStrDelimEncoded, nPos );
+ nPos = aStrEnc.Search( aStrDelimEncoded,
+ nPos+1+aStrDelimEncoded.Len() );
+ }
+ // write byte encoded
+ rOut.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ rOut.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
+ rOut.Write( aStrDelimEncoded.GetBuffer(),
+ aStrDelimEncoded.Len() );
+ }
+ rOut.WriteUniOrByteChar( '\n', eCharSet );
+ }
+ }
+ aPrgrsBar.SetState( nRowCnt );
+ }
+
+ aOS.AssignAscii( pSpecDataType_LF );
+ aOS += pKeyEOD;
+ aOS += sal_Unicode('\n');
+ rOut.WriteUnicodeOrByteText( aOS );
+
+ // restore original value
+ rOut.SetStreamCharSet( eStreamCharSet );
+
+ return eRet;
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/dif/difimp.cxx b/sc/source/filter/dif/difimp.cxx
new file mode 100644
index 000000000000..18d0c532fff9
--- /dev/null
+++ b/sc/source/filter/dif/difimp.cxx
@@ -0,0 +1,994 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <math.h>
+
+#include <svl/zforlist.hxx>
+#include <tools/debug.hxx>
+
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "dif.hxx"
+#include "docpool.hxx"
+#include "document.hxx"
+#include "filter.hxx"
+#include "fprogressbar.hxx"
+#include "ftools.hxx"
+#include "patattr.hxx"
+#include "scerrors.hxx"
+#include "scitems.hxx"
+
+const sal_Unicode pKeyTABLE[] = { 'T', 'A', 'B', 'L', 'E', 0 };
+const sal_Unicode pKeyVECTORS[] = { 'V', 'E', 'C', 'T', 'O', 'R', 'S', 0 };
+const sal_Unicode pKeyTUPLES[] = { 'T', 'U', 'P', 'L', 'E', 'S', 0 };
+const sal_Unicode pKeyDATA[] = { 'D', 'A', 'T', 'A', 0 };
+const sal_Unicode pKeyBOT[] = { 'B', 'O', 'T', 0 };
+const sal_Unicode pKeyEOD[] = { 'E', 'O', 'D', 0 };
+const sal_Unicode pKeyERROR[] = { 'E', 'R', 'R', 'O', 'R', 0 };
+const sal_Unicode pKeyTRUE[] = { 'T', 'R', 'U', 'E', 0 };
+const sal_Unicode pKeyFALSE[] = { 'F', 'A', 'L', 'S', 'E', 0 };
+const sal_Unicode pKeyNA[] = { 'N', 'A', 0 };
+const sal_Unicode pKeyV[] = { 'V', 0 };
+const sal_Unicode pKey1_0[] = { '1', ',', '0', 0 };
+
+
+FltError ScFormatFilterPluginImpl::ScImportDif( SvStream& rIn, ScDocument* pDoc, const ScAddress& rInsPos,
+ const CharSet eVon, sal_uInt32 nDifOption )
+{
+ DifParser aDifParser( rIn, nDifOption, *pDoc, eVon );
+
+ const sal_Bool bPlain = aDifParser.IsPlain();
+
+ SCTAB nBaseTab = rInsPos.Tab();
+
+ TOPIC eTopic = T_UNKNOWN;
+ sal_Bool bSyntErrWarn = false;
+ sal_Bool bOverflowWarn = false;
+
+ String& rData = aDifParser.aData;
+ sal_Bool bData = false;
+
+ rIn.Seek( 0 );
+
+ ScfStreamProgressBar aPrgrsBar( rIn, pDoc->GetDocumentShell() );
+
+ while( eTopic != T_DATA && eTopic != T_END )
+ {
+ eTopic = aDifParser.GetNextTopic();
+
+ aPrgrsBar.Progress();
+
+ bData = rData.Len() > 0;
+
+ switch( eTopic )
+ {
+ case T_TABLE:
+ {
+ if( aDifParser.nVector != 0 || aDifParser.nVal != 1 )
+ bSyntErrWarn = sal_True;
+ if( bData )
+ pDoc->RenameTab( nBaseTab, rData );
+ }
+ break;
+ case T_VECTORS:
+ {
+ if( aDifParser.nVector != 0 )
+ bSyntErrWarn = true;
+ }
+ break;
+ case T_TUPLES:
+ {
+ if( aDifParser.nVector != 0 )
+ bSyntErrWarn = true;
+ }
+ break;
+ case T_DATA:
+ {
+ if( aDifParser.nVector != 0 || aDifParser.nVal != 0 )
+ bSyntErrWarn = sal_True;
+ }
+ break;
+ case T_LABEL:
+ case T_COMMENT:
+ case T_SIZE:
+ case T_PERIODICITY:
+ case T_MAJORSTART:
+ case T_MINORSTART:
+ case T_TRUELENGTH:
+ case T_UINITS:
+ case T_DISPLAYUNITS:
+ case T_END:
+ case T_UNKNOWN:
+ break;
+ default:
+ DBG_ERRORFILE( "ScImportDif - missing enum" );
+ }
+
+ }
+
+
+ if( eTopic == T_DATA )
+ { // Ab hier kommen die Daten
+ SCCOL nBaseCol = rInsPos.Col();
+
+ SCCOL nColCnt = SCCOL_MAX;
+ SCROW nRowCnt = rInsPos.Row();
+ DifAttrCache aAttrCache( bPlain );
+
+ DATASET eAkt = D_UNKNOWN;
+
+ while( eAkt != D_EOD )
+ {
+ eAkt = aDifParser.GetNextDataset();
+
+ aPrgrsBar.Progress();
+
+ switch( eAkt )
+ {
+ case D_BOT:
+ if( nColCnt < SCCOL_MAX )
+ nRowCnt++;
+ nColCnt = nBaseCol;
+ break;
+ case D_EOD:
+ break;
+ case D_NUMERIC: // Numbercell
+ if( nColCnt == SCCOL_MAX )
+ nColCnt = nBaseCol;
+
+ if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
+ {
+ ScBaseCell* pCell;
+ if( DifParser::IsV( rData.GetBuffer() ) )
+ {
+ pCell = new ScValueCell( aDifParser.fVal );
+ if( !bPlain )
+ aAttrCache.SetNumFormat( nColCnt, nRowCnt,
+ aDifParser.nNumFormat );
+ }
+ else if( rData == pKeyTRUE || rData == pKeyFALSE )
+ {
+ pCell = new ScValueCell( aDifParser.fVal );
+ if( bPlain )
+ aAttrCache.SetLogical( nColCnt, nRowCnt );
+ else
+ aAttrCache.SetNumFormat( nColCnt, nRowCnt,
+ aDifParser.nNumFormat );
+ }
+ else if( rData == pKeyNA || rData == pKeyERROR )
+ pCell = new ScStringCell( rData );
+ else
+ {
+ String aTmp( RTL_CONSTASCII_USTRINGPARAM( "#IND: " ));
+ aTmp += rData;
+ aTmp += sal_Unicode('?');
+ pCell = new ScStringCell( aTmp );
+ }
+
+ pDoc->PutCell( nColCnt, nRowCnt, nBaseTab, pCell, ( sal_Bool ) sal_True );
+ }
+ else
+ bOverflowWarn = sal_True;
+
+ nColCnt++;
+ break;
+ case D_STRING: // Textcell
+ if( nColCnt == SCCOL_MAX )
+ nColCnt = nBaseCol;
+
+ if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
+ {
+ if( rData.Len() > 0 )
+ {
+ pDoc->PutCell( nColCnt, nRowCnt, nBaseTab,
+ ScBaseCell::CreateTextCell( rData, pDoc ), ( sal_Bool ) sal_True );
+ }
+ }
+ else
+ bOverflowWarn = sal_True;
+
+ nColCnt++;
+ break;
+ case D_UNKNOWN:
+ break;
+ case D_SYNT_ERROR:
+ break;
+ default:
+ OSL_FAIL( "ScImportDif - missing enum" );
+ }
+ }
+
+ aAttrCache.Apply( *pDoc, nBaseTab );
+ }
+ else
+ return eERR_FORMAT;
+
+ if( bSyntErrWarn )
+ //###############################################
+ // ACHTUNG: Hier fehlt noch die richtige Warnung!
+ return eERR_RNGOVRFLW;
+ //###############################################
+ else if( bOverflowWarn )
+ return eERR_RNGOVRFLW;
+ else
+ return eERR_OK;
+}
+
+
+DifParser::DifParser( SvStream& rNewIn, const sal_uInt32 nOption, ScDocument& rDoc, CharSet e ) :
+ rIn( rNewIn )
+{
+ eCharSet = e;
+ if ( rIn.GetStreamCharSet() != eCharSet )
+ {
+ DBG_ERRORFILE( "CharSet passed overrides and modifies StreamCharSet" );
+ rIn.SetStreamCharSet( eCharSet );
+ }
+ rIn.StartReadingUnicodeText( eCharSet );
+
+ bPlain = ( nOption == SC_DIFOPT_PLAIN );
+
+ if( bPlain )
+ pNumFormatter = NULL;
+ else
+ pNumFormatter = rDoc.GetFormatTable();
+}
+
+
+TOPIC DifParser::GetNextTopic( void )
+{
+ enum STATE { S_VectorVal, S_Data, S_END, S_START, S_UNKNOWN, S_ERROR_L2 };
+
+ static const sal_Unicode pKeyLABEL[] = { 'L', 'A', 'B', 'E', 'L', 0 };
+ static const sal_Unicode pKeyCOMMENT[] = { 'C', 'O', 'M', 'M', 'E', 'N', 'T', 0 };
+ static const sal_Unicode pKeySIZE[] = { 'S', 'I', 'Z', 'E', 0 };
+ static const sal_Unicode pKeyPERIODICITY[] = { 'P', 'E', 'R', 'I', 'O', 'D', 'I', 'C', 'I', 'T', 'Y', 0 };
+ static const sal_Unicode pKeyMAJORSTART[] = { 'M', 'A', 'J', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
+ static const sal_Unicode pKeyMINORSTART[] = { 'M', 'I', 'N', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
+ static const sal_Unicode pKeyTRUELENGTH[] = { 'T', 'R', 'U', 'E', 'L', 'E', 'N', 'G', 'T', 'H', 0 };
+ static const sal_Unicode pKeyUINITS[] = { 'U', 'I', 'N', 'I', 'T', 'S', 0 };
+ static const sal_Unicode pKeyDISPLAYUNITS[] = { 'D', 'I', 'S', 'P', 'L', 'A', 'Y', 'U', 'N', 'I', 'T', 'S', 0 };
+ static const sal_Unicode pKeyUNKNOWN[] = { 0 };
+
+ static const sal_Unicode* ppKeys[] =
+ {
+ pKeyTABLE, // 0
+ pKeyVECTORS,
+ pKeyTUPLES,
+ pKeyDATA,
+ pKeyLABEL,
+ pKeyCOMMENT, // 5
+ pKeySIZE,
+ pKeyPERIODICITY,
+ pKeyMAJORSTART,
+ pKeyMINORSTART,
+ pKeyTRUELENGTH, // 10
+ pKeyUINITS,
+ pKeyDISPLAYUNITS,
+ pKeyUNKNOWN // 13
+ };
+
+ static const TOPIC pTopics[] =
+ {
+ T_TABLE, // 0
+ T_VECTORS,
+ T_TUPLES,
+ T_DATA,
+ T_LABEL,
+ T_COMMENT, // 5
+ T_SIZE,
+ T_PERIODICITY,
+ T_MAJORSTART,
+ T_MINORSTART,
+ T_TRUELENGTH, // 10
+ T_UINITS,
+ T_DISPLAYUNITS,
+ T_UNKNOWN // 13
+ };
+
+ STATE eS = S_START;
+ String aLine;
+
+ nVector = 0;
+ nVal = 0;
+ TOPIC eRet = T_UNKNOWN;
+
+ while( eS != S_END )
+ {
+ if( !ReadNextLine( aLine ) )
+ {
+ eS = S_END;
+ eRet = T_END;
+ }
+
+ switch( eS )
+ {
+ case S_START:
+ {
+ const sal_Unicode* pRef;
+ sal_uInt16 nCnt = 0;
+ sal_Bool bSearch = sal_True;
+
+ pRef = ppKeys[ nCnt ];
+
+ while( bSearch )
+ {
+ if( aLine == pRef )
+ {
+ eRet = pTopics[ nCnt ];
+ bSearch = false;
+ }
+ else
+ {
+ nCnt++;
+ pRef = ppKeys[ nCnt ];
+ if( !*pRef )
+ bSearch = false;
+ }
+ }
+
+ if( *pRef )
+ eS = S_VectorVal;
+ else
+ eS = S_UNKNOWN;
+ }
+ break;
+ case S_VectorVal:
+ {
+ const sal_Unicode* pCur = aLine.GetBuffer();
+
+ pCur = ScanIntVal( pCur, nVector );
+
+ if( pCur && *pCur == ',' )
+ {
+ pCur++;
+ ScanIntVal( pCur, nVal );
+ eS = S_Data;
+ }
+ else
+ eS = S_ERROR_L2;
+ }
+ break;
+ case S_Data:
+ DBG_ASSERT( aLine.Len() >= 2,
+ "+GetNextTopic(): <String> ist zu kurz!" );
+ if( aLine.Len() > 2 )
+ aData = aLine.Copy( 1, aLine.Len() - 2 );
+ else
+ aData.Erase();
+ eS = S_END;
+ break;
+ case S_END:
+ DBG_ERRORFILE( "DifParser::GetNextTopic - unexpected state" );
+ break;
+ case S_UNKNOWN:
+ // 2 Zeilen ueberlesen
+ ReadNextLine( aLine );
+ case S_ERROR_L2: // Fehler in Line 2 aufgetreten
+ // eine Zeile ueberlesen
+ ReadNextLine( aLine );
+ eS = S_END;
+ break;
+ default:
+ DBG_ERRORFILE( "DifParser::GetNextTopic - missing enum" );
+ }
+ }
+
+ return eRet;
+}
+
+
+static void lcl_DeEscapeQuotesDif( String& rString )
+{
+ // Special handling for DIF import: Escaped (duplicated) quotes are resolved.
+ // Single quote characters are left in place because older versions didn't
+ // escape quotes in strings (and Excel doesn't when using the clipboard).
+ // The quotes around the string are removed before this function is called.
+
+ static const sal_Unicode aDQ[] = { '"', '"', 0 };
+ xub_StrLen nPos = 0;
+ while ( (nPos = rString.Search( aDQ, nPos )) != STRING_NOTFOUND )
+ {
+ rString.Erase( nPos, 1 );
+ ++nPos;
+ }
+}
+
+// Determine if passed in string is numeric data and set fVal/nNumFormat if so
+DATASET DifParser::GetNumberDataset( const sal_Unicode* pPossibleNumericData )
+{
+ DATASET eRet = D_SYNT_ERROR;
+ if( bPlain )
+ {
+ if( ScanFloatVal( pPossibleNumericData ) )
+ eRet = D_NUMERIC;
+ else
+ eRet = D_SYNT_ERROR;
+ }
+ else
+ { // ...und zur Strafe mit'm Numberformatter...
+ DBG_ASSERT( pNumFormatter, "-DifParser::GetNextDataset(): No Formatter, more fun!" );
+ String aTestVal( pPossibleNumericData );
+ sal_uInt32 nFormat = 0;
+ double fTmpVal;
+ if( pNumFormatter->IsNumberFormat( aTestVal, nFormat, fTmpVal ) )
+ {
+ fVal = fTmpVal;
+ nNumFormat = nFormat;
+ eRet = D_NUMERIC;
+ }
+ else
+ eRet = D_SYNT_ERROR;
+ }
+ return eRet;
+}
+
+bool DifParser::ReadNextLine( String& rStr )
+{
+ if( aLookAheadLine.Len() == 0 )
+ {
+ return rIn.ReadUniOrByteStringLine( rStr );
+ }
+ else
+ {
+ rStr = aLookAheadLine;
+ aLookAheadLine.Erase();
+ return true;
+ }
+}
+
+// Look ahead in the stream to determine if the next line is the first line of
+// a valid data record structure
+bool DifParser::LookAhead()
+{
+ const sal_Unicode* pAktBuffer;
+ bool bValidStructure = false;
+
+ DBG_ASSERT( aLookAheadLine.Len() == 0, "*DifParser::LookAhead(): LookAhead called twice in a row" );
+ rIn.ReadUniOrByteStringLine( aLookAheadLine );
+
+ pAktBuffer = aLookAheadLine.GetBuffer();
+
+ switch( *pAktBuffer )
+ {
+ case '-': // Special Datatype
+ pAktBuffer++;
+
+ if( Is1_0( pAktBuffer ) )
+ {
+ bValidStructure = true;
+ }
+ break;
+ case '0': // Numeric Data
+ pAktBuffer++;
+ if( *pAktBuffer == ',' )
+ {
+ pAktBuffer++;
+ bValidStructure = ( GetNumberDataset(pAktBuffer) != D_SYNT_ERROR );
+ }
+ break;
+ case '1': // String Data
+ if( Is1_0( aLookAheadLine.GetBuffer() ) )
+ {
+ bValidStructure = true;
+ }
+ break;
+ }
+ return bValidStructure;
+}
+
+DATASET DifParser::GetNextDataset( void )
+{
+ DATASET eRet = D_UNKNOWN;
+ String aLine;
+ const sal_Unicode* pAktBuffer;
+
+ ReadNextLine( aLine );
+
+ pAktBuffer = aLine.GetBuffer();
+
+ switch( *pAktBuffer )
+ {
+ case '-': // Special Datatype
+ pAktBuffer++;
+
+ if( Is1_0( pAktBuffer ) )
+ {
+ ReadNextLine( aLine );
+ if( IsBOT( aLine.GetBuffer() ) )
+ eRet = D_BOT;
+ else if( IsEOD( aLine.GetBuffer() ) )
+ eRet = D_EOD;
+ }
+ break;
+ case '0': // Numeric Data
+ pAktBuffer++; // Wert in fVal, 2. Zeile in aData
+ if( *pAktBuffer == ',' )
+ {
+ pAktBuffer++;
+ eRet = GetNumberDataset(pAktBuffer);
+ ReadNextLine( aData );
+ if ( eRet == D_SYNT_ERROR )
+ { // for broken records write "#ERR: data" to cell
+ String aTmp( RTL_CONSTASCII_USTRINGPARAM( "#ERR: " ));
+ aTmp += pAktBuffer;
+ aTmp.AppendAscii( " (" );
+ aTmp += aData;
+ aTmp += sal_Unicode(')');
+ aData = aTmp;
+ eRet = D_STRING;
+ }
+ }
+ break;
+ case '1': // String Data
+ if( Is1_0( aLine.GetBuffer() ) )
+ {
+ ReadNextLine( aLine );
+ xub_StrLen nLineLength = aLine.Len();
+ const sal_Unicode* pLine = aLine.GetBuffer();
+
+ if( nLineLength >= 1 && *pLine == '"' )
+ {
+ // Quotes are not always escaped (duplicated), see lcl_DeEscapeQuotesDif
+ // A look ahead into the next line is needed in order to deal with
+ // multiline strings containing quotes
+ if( LookAhead() )
+ {
+ // Single line string
+ if( nLineLength >= 2 && pLine[nLineLength - 1] == '"' )
+ {
+ aData = aLine.Copy( 1, nLineLength - 2 );
+ lcl_DeEscapeQuotesDif( aData );
+ eRet = D_STRING;
+ }
+ }
+ else
+ {
+ // Multiline string
+ aData = aLine.Copy( 1 );
+ bool bContinue = true;
+ while ( bContinue )
+ {
+ aData.Append( '\n' );
+ bContinue = !rIn.IsEof() && ReadNextLine( aLine );
+ if( bContinue )
+ {
+ nLineLength = aLine.Len();
+ if( nLineLength >= 1 )
+ {
+ pLine = aLine.GetBuffer();
+ bContinue = !LookAhead();
+ if( bContinue )
+ {
+ aData.Append( aLine );
+ }
+ else if( pLine[nLineLength - 1] == '"' )
+ {
+ aData.Append( pLine, nLineLength - 1 );
+ lcl_DeEscapeQuotesDif( aData );
+ eRet = D_STRING;
+ }
+ }
+ }
+ };
+ }
+ }
+ }
+ break;
+ }
+
+ if( eRet == D_UNKNOWN )
+ ReadNextLine( aLine );
+
+ if( rIn.IsEof() )
+ eRet = D_EOD;
+
+ return eRet;
+}
+
+
+const sal_Unicode* DifParser::ScanIntVal( const sal_Unicode* pStart, sal_uInt32& rRet )
+{
+ // eat leading whitespace, not specified, but seen in the wild
+ while (*pStart == ' ' || *pStart == '\t')
+ ++pStart;
+
+ sal_Unicode cAkt = *pStart;
+
+ if( IsNumber( cAkt ) )
+ rRet = ( sal_uInt32 ) ( cAkt - '0' );
+ else
+ return NULL;
+
+ pStart++;
+ cAkt = *pStart;
+
+ while( IsNumber( cAkt ) && rRet < ( 0xFFFFFFFF / 10 ) )
+ {
+ rRet *= 10;
+ rRet += ( sal_uInt32 ) ( cAkt - '0' );
+
+ pStart++;
+ cAkt = *pStart;
+ }
+
+ return pStart;
+}
+
+
+sal_Bool DifParser::ScanFloatVal( const sal_Unicode* pStart )
+ {
+ double fNewVal = 0.0;
+ sal_Bool bNeg = false;
+ double fFracPos = 1.0;
+ sal_Int32 nExp = 0;
+ sal_Bool bExpNeg = false;
+ sal_Bool bExpOverflow = false;
+ static const sal_uInt16 nExpLimit = 4096; // ACHTUNG: muss genauer ermittelt werden!
+
+ sal_Unicode cAkt;
+ sal_Bool bRet = false;
+
+ enum STATE { S_FIRST, S_PRE, S_POST, S_EXP_FIRST, S_EXP, S_END, S_FINDEND };
+
+ STATE eS = S_FIRST;
+
+ fNewVal = 0.0;
+
+ while( eS != S_END )
+ {
+ cAkt = *pStart;
+ switch( eS )
+ {
+ case S_FIRST:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal *= 10;
+ fNewVal += cAkt - '0';
+ eS = S_PRE;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case ' ':
+ case '\t':
+ case '+':
+ break;
+ case '-':
+ bNeg = !bNeg;
+ break;
+ case '.':
+ case ',': //!
+ eS = S_POST;
+ fFracPos = 0.1;
+ break;
+ default:
+ eS = S_END;
+ }
+ }
+ break;
+ case S_PRE:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal *= 10;
+ fNewVal += cAkt - '0';
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case '.':
+ case ',': //!
+ eS = S_POST;
+ fFracPos = 0.1;
+ break;
+ case 'e':
+ case 'E':
+ eS = S_EXP;
+ break;
+ case 0x00: // IsNumberEnding( cAkt )
+ bRet = sal_True; // no
+ default: // break!
+ eS = S_END;
+ }
+ }
+ break;
+ case S_POST:
+ if( IsNumber( cAkt ) )
+ {
+ fNewVal += fFracPos * ( cAkt - '0' );
+ fFracPos /= 10.0;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case 'e':
+ case 'E':
+ eS = S_EXP_FIRST;
+ break;
+ case 0x00: // IsNumberEnding( cAkt )
+ bRet = sal_True; // no
+ default: // break!
+ eS = S_END;
+ }
+ }
+ break;
+ case S_EXP_FIRST:
+ if( IsNumber( cAkt ) )
+ {
+ if( nExp < nExpLimit )
+ {
+ nExp *= 10;
+ nExp += ( sal_uInt16 ) ( cAkt - '0' );
+ }
+ eS = S_EXP;
+ }
+ else
+ {
+ switch( cAkt )
+ {
+ case '+':
+ break;
+ case '-':
+ bExpNeg = !bExpNeg;
+ break;
+ default:
+ eS = S_END;
+ }
+ }
+ break;
+ case S_EXP:
+ if( IsNumber( cAkt ) )
+ {
+ if( nExp < ( 0xFFFF / 10 ) )
+ {
+ nExp *= 10;
+ nExp += ( sal_uInt16 ) ( cAkt - '0' );
+ }
+ else
+ {
+ bExpOverflow = sal_True;
+ eS = S_FINDEND;
+ }
+ }
+ else
+ {
+ bRet = IsNumberEnding( cAkt );
+ eS = S_END;
+ }
+ break;
+ case S_FINDEND:
+ if( IsNumberEnding( cAkt ) )
+ {
+ bRet = sal_True; // damit sinnvoll weitergeparst werden kann
+ eS = S_END;
+ }
+ break;
+ case S_END:
+ DBG_ERRORFILE( "DifParser::ScanFloatVal - unexpected state" );
+ break;
+ default:
+ DBG_ERRORFILE( "DifParser::ScanFloatVal - missing enum" );
+ }
+ pStart++;
+ }
+
+ if( bRet )
+ {
+ if( bExpOverflow )
+ return false; // ACHTUNG: hier muss noch differenziert werden
+
+ if( bNeg )
+ fNewVal *= 1.0;
+
+ if( bExpNeg )
+ nExp *= -1;
+
+ if( nExp != 0 )
+ fNewVal *= pow( 10.0, ( double ) nExp );
+ fVal = fNewVal;
+ }
+
+ return bRet;
+}
+
+DifColumn::DifColumn ()
+ : pAkt(NULL)
+{
+}
+
+void DifColumn::SetLogical( SCROW nRow )
+{
+ DBG_ASSERT( ValidRow(nRow), "*DifColumn::SetLogical(): Row zu gross!" );
+
+ if( pAkt )
+ {
+ DBG_ASSERT( nRow > 0, "*DifColumn::SetLogical(): weitere koennen nicht 0 sein!" );
+
+ nRow--;
+
+ if( pAkt->nEnd == nRow )
+ pAkt->nEnd++;
+ else
+ pAkt = NULL;
+ }
+ else
+ {
+ pAkt = new ENTRY;
+ pAkt->nStart = pAkt->nEnd = nRow;
+
+ aEntries.push_back(pAkt);
+ }
+}
+
+
+void DifColumn::SetNumFormat( SCROW nRow, const sal_uInt32 nNumFormat )
+{
+ DBG_ASSERT( ValidRow(nRow), "*DifColumn::SetNumFormat(): Row zu gross!" );
+
+ if( nNumFormat > 0 )
+ {
+ if(pAkt)
+ {
+ DBG_ASSERT( nRow > 0,
+ "*DifColumn::SetNumFormat(): weitere koennen nicht 0 sein!" );
+ DBG_ASSERT( nRow > pAkt->nEnd,
+ "*DifColumn::SetNumFormat(): Noch 'mal von vorne?" );
+
+ if( pAkt->nNumFormat == nNumFormat && pAkt->nEnd == nRow - 1 )
+ pAkt->nEnd = nRow;
+ else
+ NewEntry( nRow, nNumFormat );
+ }
+ else
+ NewEntry(nRow,nNumFormat );
+ }
+ else
+ pAkt = NULL;
+}
+
+
+void DifColumn::NewEntry( const SCROW nPos, const sal_uInt32 nNumFormat )
+{
+ pAkt = new ENTRY;
+ pAkt->nStart = pAkt->nEnd = nPos;
+ pAkt->nNumFormat = nNumFormat;
+
+ aEntries.push_back(pAkt);
+}
+
+
+void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab, const ScPatternAttr& rPattAttr )
+{
+ for (boost::ptr_vector<ENTRY>::const_iterator it = aEntries.begin(); it != aEntries.end(); ++it)
+ rDoc.ApplyPatternAreaTab( nCol, it->nStart, nCol, it->nEnd, nTab, rPattAttr );
+}
+
+
+void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab )
+{
+ ScPatternAttr aAttr( rDoc.GetPool() );
+ SfxItemSet &rItemSet = aAttr.GetItemSet();
+
+ for (boost::ptr_vector<ENTRY>::const_iterator it = aEntries.begin(); it != aEntries.end(); ++it)
+ {
+ DBG_ASSERT( it->nNumFormat > 0,
+ "+DifColumn::Apply(): Numberformat darf hier nicht 0 sein!" );
+
+ rItemSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, it->nNumFormat ) );
+
+ rDoc.ApplyPatternAreaTab( nCol, it->nStart, nCol, it->nEnd, nTab, aAttr );
+
+ rItemSet.ClearItem();
+ }
+}
+
+
+DifAttrCache::DifAttrCache( const sal_Bool bNewPlain )
+{
+ bPlain = bNewPlain;
+ ppCols = new DifColumn *[ MAXCOL + 1 ];
+ for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
+ ppCols[ nCnt ] = NULL;
+}
+
+
+DifAttrCache::~DifAttrCache()
+{
+ for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
+ {
+ if( ppCols[ nCnt ] )
+ delete ppCols[ nCnt ];
+ }
+}
+
+void DifAttrCache::SetLogical( const SCCOL nCol, const SCROW nRow )
+{
+ DBG_ASSERT( ValidCol(nCol), "-DifAttrCache::SetLogical(): Col zu gross!" );
+ DBG_ASSERT( bPlain, "*DifAttrCache::SetLogical(): muss Plain sein!" );
+
+ if( !ppCols[ nCol ] )
+ ppCols[ nCol ] = new DifColumn;
+
+ ppCols[ nCol ]->SetLogical( nRow );
+}
+
+void DifAttrCache::SetNumFormat( const SCCOL nCol, const SCROW nRow, const sal_uInt32 nNumFormat )
+{
+ DBG_ASSERT( ValidCol(nCol), "-DifAttrCache::SetNumFormat(): Col zu gross!" );
+ DBG_ASSERT( !bPlain, "*DifAttrCache::SetNumFormat(): sollte nicht Plain sein!" );
+
+ if( !ppCols[ nCol ] )
+ ppCols[ nCol ] = new DifColumn;
+
+ ppCols[ nCol ]->SetNumFormat( nRow, nNumFormat );
+}
+
+
+void DifAttrCache::Apply( ScDocument& rDoc, SCTAB nTab )
+{
+ if( bPlain )
+ {
+ ScPatternAttr* pPatt = NULL;
+
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ {
+ if( ppCols[ nCol ] )
+ {
+ if( !pPatt )
+ {
+ pPatt = new ScPatternAttr( rDoc.GetPool() );
+ pPatt->GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
+ rDoc.GetFormatTable()->GetStandardFormat( NUMBERFORMAT_LOGICAL ) ) );
+ }
+
+ ppCols[ nCol ]->Apply( rDoc, nCol, nTab, *pPatt );
+ }
+ }
+
+ if( pPatt )
+ delete pPatt;
+ }
+ else
+ {
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ {
+ if( ppCols[ nCol ] )
+ ppCols[ nCol ]->Apply( rDoc, nCol, nTab );
+ }
+ }
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx
new file mode 100644
index 000000000000..17270c14fc00
--- /dev/null
+++ b/sc/source/filter/excel/colrowst.cxx
@@ -0,0 +1,364 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "colrowst.hxx"
+
+#include <string.h>
+
+#include "document.hxx"
+#include "root.hxx"
+#include "ftools.hxx"
+#include "xltable.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+#include "queryparam.hxx"
+
+// for filter manager
+#include "excimp8.hxx"
+
+// ============================================================================
+
+const sal_uInt8 EXC_COLROW_USED = 0x01;
+const sal_uInt8 EXC_COLROW_DEFAULT = 0x02;
+const sal_uInt8 EXC_COLROW_HIDDEN = 0x04;
+const sal_uInt8 EXC_COLROW_MAN = 0x08;
+
+// ============================================================================
+
+XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maWidths( MAXCOLCOUNT, 0 ),
+ maColFlags( MAXCOLCOUNT, 0 ),
+ maRowHeights(0, MAXROWCOUNT, 0),
+ maRowFlags(0, MAXROWCOUNT, 0),
+ maHiddenRows(0, MAXROWCOUNT, false),
+ mnLastScRow( -1 ),
+ mnDefWidth( STD_COL_WIDTH ),
+ mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ),
+ mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mbHasStdWidthRec( false ),
+ mbHasDefHeight( false ),
+ mbDirty( true )
+{
+}
+
+XclImpColRowSettings::~XclImpColRowSettings()
+{
+}
+
+void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec )
+{
+ if( bStdWidthRec )
+ {
+ // STANDARDWIDTH record overrides DEFCOLWIDTH record
+ mnDefWidth = nDefWidth;
+ mbHasStdWidthRec = true;
+ }
+ else if( !mbHasStdWidthRec )
+ {
+ // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists
+ mnDefWidth = nDefWidth;
+ }
+}
+
+void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nWidth )
+{
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetColWidthRange - invalid column range" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ if (nScCol2 == 256)
+ // In BIFF8, the column range is 0-255, and the use of 256 probably
+ // means the range should extend to the max column if the loading app
+ // support columns beyond 255.
+ nScCol2 = MAXCOL;
+
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ ::std::fill( maWidths.begin() + nScCol1, maWidths.begin() + nScCol2 + 1, nWidth );
+ for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
+ ::set_flag( *aIt, EXC_COLROW_USED );
+}
+
+void XclImpColRowSettings::HideCol( SCCOL nScCol )
+{
+ if( ValidCol( nScCol ) )
+ ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+}
+
+void XclImpColRowSettings::HideColRange( SCCOL nScCol1, SCCOL nScCol2 )
+{
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::HideColRange - invalid column range" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
+ ::set_flag( *aIt, EXC_COLROW_HIDDEN );
+}
+
+void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags )
+{
+ mnDefHeight = nDefHeight;
+ mnDefRowFlags = nFlags;
+ if( mnDefHeight == 0 )
+ {
+ mnDefHeight = static_cast< sal_uInt16 >( STD_ROW_HEIGHT );
+ ::set_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
+ }
+ mbHasDefHeight = true;
+}
+
+void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight )
+{
+ if (!ValidRow(nScRow))
+ return;
+
+ sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
+ bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
+ maRowHeights.insert_back(nScRow, nScRow+1, nRawHeight);
+ sal_uInt8 nFlagVal = 0;
+ if (!maRowFlags.search(nScRow, nFlagVal).second)
+ return;
+
+ ::set_flag(nFlagVal, EXC_COLROW_USED);
+ ::set_flag(nFlagVal, EXC_COLROW_DEFAULT, bDefHeight);
+
+ if (!bDefHeight && nRawHeight == 0)
+ maHiddenRows.insert_back(nScRow, nScRow+1, true);
+
+ maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
+
+ if (nScRow > mnLastScRow)
+ mnLastScRow = nScRow;
+}
+
+void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags )
+{
+ if (!ValidRow(nScRow))
+ return;
+
+ SetHeight(nScRow, nHeight);
+
+ sal_uInt8 nFlagVal = 0;
+ if (!maRowFlags.search(nScRow, nFlagVal).second)
+ return;
+
+ if (::get_flag(nFlags, EXC_ROW_UNSYNCED))
+ ::set_flag(nFlagVal, EXC_COLROW_MAN);
+
+ maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
+
+ if (::get_flag(nFlags, EXC_ROW_HIDDEN))
+ maHiddenRows.insert_back(nScRow, nScRow+1, true);
+}
+
+void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow )
+{
+ if (!ValidRow(nScRow))
+ return;
+
+ sal_uInt8 nFlagVal = 0;
+ if (!maRowFlags.search(nScRow, nFlagVal).second)
+ return;
+
+ ::set_flag(nFlagVal, EXC_COLROW_MAN);
+ maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
+}
+
+void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex )
+{
+ /* assign the default column formatting here to ensure that
+ explicit cell formatting is not overwritten. */
+ DBG_ASSERT( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetDefaultXF - invalid column index" );
+ nScCol2 = ::std::min( nScCol2, MAXCOL );
+ nScCol1 = ::std::min( nScCol1, nScCol2 );
+ XclImpXFRangeBuffer& rXFRangeBuffer = GetXFRangeBuffer();
+ for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
+ rXFRangeBuffer.SetColumnDefXF( nScCol, nXFIndex );
+}
+
+void XclImpColRowSettings::Convert( SCTAB nScTab )
+{
+ if( !mbDirty )
+ return;
+
+ ScDocument& rDoc = GetDoc();
+ rDoc.IncSizeRecalcLevel( nScTab );
+
+ // column widths ----------------------------------------------------------
+
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ {
+ sal_uInt16 nWidth = ::get_flag( maColFlags[ nScCol ], EXC_COLROW_USED ) ? maWidths[ nScCol ] : mnDefWidth;
+ /* Hidden columns: remember hidden state, but do not set hidden state
+ in document here. Needed for #i11776#, no HIDDEN flags in the
+ document, until filters and outlines are inserted. */
+ if( nWidth == 0 )
+ {
+ ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+ nWidth = mnDefWidth;
+ }
+ rDoc.SetColWidthOnly( nScCol, nScTab, nWidth );
+ }
+
+ // row heights ------------------------------------------------------------
+
+ // #i54252# set default row height
+ rDoc.SetRowHeightOnly( 0, MAXROW, nScTab, mnDefHeight );
+ if( ::get_flag( mnDefRowFlags, EXC_DEFROW_UNSYNCED ) )
+ // first access to row flags, do not ask for old flags
+ rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE );
+
+ maRowHeights.build_tree();
+ if (!maRowHeights.is_tree_valid())
+ return;
+
+ RowFlagsType::const_iterator itrFlags = maRowFlags.begin(), itrFlagsEnd = maRowFlags.end();
+ SCROW nPrevRow = -1;
+ sal_uInt8 nPrevFlags = 0;
+ for (; itrFlags != itrFlagsEnd; ++itrFlags)
+ {
+ SCROW nRow = itrFlags->first;
+ sal_uInt8 nFlags = itrFlags->second;
+ if (nPrevRow >= 0)
+ {
+ sal_uInt16 nHeight = 0;
+
+ if (::get_flag(nPrevFlags, EXC_COLROW_USED))
+ {
+ if (::get_flag(nPrevFlags, EXC_COLROW_DEFAULT))
+ {
+ nHeight = mnDefHeight;
+ rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
+ }
+ else
+ {
+ for (SCROW i = nPrevRow; i <= nRow - 1; ++i)
+ {
+ SCROW nLast;
+ if (!maRowHeights.search_tree(i, nHeight, NULL, &nLast))
+ {
+ // search failed for some reason
+ return;
+ }
+
+ if (nLast > nRow)
+ nLast = nRow;
+
+ rDoc.SetRowHeightOnly(i, nLast-1, nScTab, nHeight);
+ i = nLast-1;
+ }
+ }
+
+ if (::get_flag(nPrevFlags, EXC_COLROW_MAN))
+ rDoc.SetManualHeight(nPrevRow, nRow-1, nScTab, true);
+ }
+ else
+ {
+ nHeight = mnDefHeight;
+ rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
+ }
+ }
+
+ nPrevRow = nRow;
+ nPrevFlags = nFlags;
+ }
+
+ // ------------------------------------------------------------------------
+
+ mbDirty = false;
+ rDoc.DecSizeRecalcLevel( nScTab );
+}
+
+void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+{
+ ScDocument& rDoc = GetDoc();
+
+ // hide the columns
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ if( ::get_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ) )
+ rDoc.ShowCol( nScCol, nScTab, false );
+
+ // #i38093# rows hidden by filter need extra flag
+ SCROW nFirstFilterScRow = SCROW_MAX;
+ SCROW nLastFilterScRow = SCROW_MAX;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ const XclImpAutoFilterData* pFilter = GetFilterManager().GetByTab( nScTab );
+ // #i70026# use IsFiltered() to set the CR_FILTERED flag for active filters only
+ if( pFilter && pFilter->IsActive() && pFilter->IsFiltered() )
+ {
+ nFirstFilterScRow = pFilter->StartRow();
+ nLastFilterScRow = pFilter->EndRow();
+ }
+ }
+
+ // In case the excel row limit is lower than calc's, use the visibility of
+ // the last row and extend it to calc's last row.
+ SCROW nLastXLRow = GetRoot().GetXclMaxPos().Row();
+ if (nLastXLRow < MAXROW)
+ {
+ bool bHidden = false;
+ if (!maHiddenRows.search(nLastXLRow, bHidden).second)
+ return;
+
+ maHiddenRows.insert_back(nLastXLRow, MAXROWCOUNT, bHidden);
+ }
+
+ SCROW nPrevRow = -1;
+ bool bPrevHidden = false;
+ RowHiddenType::const_iterator itr = maHiddenRows.begin(), itrEnd = maHiddenRows.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ SCROW nRow = itr->first;
+ bool bHidden = itr->second;
+ if (nPrevRow >= 0)
+ {
+ if (bPrevHidden)
+ {
+ rDoc.ShowRows(nPrevRow, nRow-1, nScTab, false);
+ // #i38093# rows hidden by filter need extra flag
+ if (nFirstFilterScRow <= nPrevRow && nPrevRow <= nLastFilterScRow)
+ {
+ SCROW nLast = ::std::min(nRow-1, nLastFilterScRow);
+ rDoc.SetRowFiltered(nPrevRow, nLast, nScTab, true);
+ }
+ }
+ }
+
+ nPrevRow = nRow;
+ bPrevHidden = bHidden;
+ }
+
+ // #i47438# if default row format is hidden, hide remaining rows
+ if( ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ) && (mnLastScRow < MAXROW) )
+ rDoc.ShowRows( mnLastScRow + 1, MAXROW, nScTab, false );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
new file mode 100644
index 000000000000..dad9397d488f
--- /dev/null
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -0,0 +1,827 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zformat.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustring.hxx>
+
+#include "cell.hxx"
+#include "dociter.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "progress.hxx"
+#include "conditio.hxx"
+#include "dpobject.hxx"
+#include "attrib.hxx"
+#include "scextopt.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "olinetab.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "patattr.hxx"
+#include "docoptio.hxx"
+#include "tabprotection.hxx"
+
+#include "excdoc.hxx"
+#include "namebuff.hxx"
+
+#include "xcl97rec.hxx"
+#include "xcl97esc.hxx"
+#include "xetable.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xepage.hxx"
+#include "xeview.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+#include "xepivot.hxx"
+#include "XclExpChangeTrack.hxx"
+
+#include <math.h>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <oox/token/tokens.hxx>
+#include <boost/shared_ptr.hpp>
+
+using ::rtl::OString;
+using namespace oox;
+
+static String lcl_GetVbaTabName( SCTAB n )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM( "__VBA__" ) );
+ aRet += String::CreateFromInt32( static_cast<sal_uInt16>(n) );
+ return aRet;
+}
+
+
+static void lcl_AddBookviews( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
+ aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
+}
+
+static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ ScDocument& rDoc = self.GetDoc();
+
+ aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
+ // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
+ // concurrentCalc, concurrentManualCount,
+ // forceFullCalc, fullCalcOnLoad, fullPrecision
+ aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
+ aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
+ aRecList.AppendNewRecord( new XclIteration( rDoc ) );
+ aRecList.AppendNewRecord( new XclDelta( rDoc ) );
+ aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
+ aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
+}
+
+static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& self )
+{
+ aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
+
+ const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
+ aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
+ aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
+ }
+
+ aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
+}
+
+static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab )
+{
+ // Scenarios
+ aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
+ // filter
+ aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
+}
+
+
+ExcTable::ExcTable( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnScTab( SCTAB_GLOBAL ),
+ nExcTab( EXC_NOTAB ),
+ pTabNames( new NameBuffer( 0, 16 ) )
+{
+}
+
+
+ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
+ XclExpRoot( rRoot ),
+ mnScTab( nScTab ),
+ nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
+ pTabNames( new NameBuffer( 0, 16 ) )
+{
+}
+
+
+ExcTable::~ExcTable()
+{
+ delete pTabNames;
+}
+
+
+void ExcTable::Add( XclExpRecordBase* pRec )
+{
+ DBG_ASSERT( pRec, "-ExcTable::Add(): pRec ist NULL!" );
+ aRecList.AppendNewRecord( pRec );
+}
+
+
+void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
+{
+ InitializeGlobals();
+
+ RootData& rR = GetOldRoot();
+ ScDocument& rDoc = GetDoc();
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+
+ if ( GetBiff() <= EXC_BIFF5 )
+ Add( new ExcBofW );
+ else
+ Add( new ExcBofW8 );
+
+ SCTAB nC;
+ String aTmpString;
+ SCTAB nScTabCount = rTabInfo.GetScTabCount();
+ sal_uInt16 nExcTabCount = rTabInfo.GetXclTabCount();
+ sal_uInt16 nCodenames = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
+
+ SfxObjectShell* pShell = GetDocShell();
+ sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0;
+ bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly();
+
+ if( (nWriteProtHash > 0) || bRecommendReadOnly )
+ Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) );
+
+ // TODO: correct codepage for BIFF5?
+ sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE );
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) );
+ Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
+ Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) );
+ Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) );
+ Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) );
+ Add( new ExcDummy_00 );
+ }
+ else
+ {
+ if( IsDocumentEncrypted() )
+ Add( new XclExpFileEncryption( GetRoot() ) );
+ Add( new XclExpInterfaceHdr( nCodePage ) );
+ Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
+ Add( new XclExpInterfaceEnd );
+ Add( new XclExpWriteAccess );
+ }
+
+ Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) );
+ Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) );
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpBoolRecord( EXC_ID_DSF, false ) );
+ Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) );
+ rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
+ Add( rR.pTabId );
+ if( HasVbaStorage() )
+ {
+ Add( new XclObproj );
+ const String& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
+ if( rCodeName.Len() )
+ Add( new XclCodename( rCodeName ) );
+ }
+ }
+
+ Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) );
+
+ // erst Namen- und Tabellen-Eintraege aufbauen
+ String aName;
+
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ rDoc.GetName( nC, aTmpString );
+ *pTabNames << aTmpString;
+ }
+
+ if ( GetBiff() <= EXC_BIFF5 )
+ {
+ // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
+ }
+
+ // document protection options
+ if( GetOutput() == EXC_OUTPUT_BINARY )
+ {
+ lcl_AddWorkbookProtection( aRecList, *this );
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpProt4Rev );
+ Add( new XclExpProt4RevPass );
+ }
+
+ lcl_AddBookviews( aRecList, *this );
+ }
+
+ Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
+ if ( GetBiff() == EXC_BIFF8 && GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
+ Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
+ }
+
+ if ( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
+ Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
+ }
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new ExcDummy_040 );
+ Add( new Exc1904( rDoc ) );
+ Add( new ExcDummy_041 );
+ }
+ else
+ {
+ // BIFF8
+ Add( new Exc1904( rDoc ) );
+ Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
+ Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
+ Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
+ // OOXTODO: The following /workbook/workbookPr attributes are mapped
+ // to various BIFF records that are not currently supported:
+ //
+ // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
+ // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
+ // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
+ // XML_codeName: "Calc"
+ // XML_defaultThemeVersion: ???
+ // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
+ // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
+ // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
+ // XML_publishItems: NAMEPUBLISH 893h: fPublished
+ // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
+ // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
+ // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
+ // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
+ // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
+ }
+ Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
+
+ // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
+ }
+ else
+ {
+ aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
+ }
+
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ // Bundlesheet
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+ }
+ else
+ {
+ // Pivot Cache
+ GetPivotTableManager().CreatePivotTables();
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
+
+ // Change tracking
+ if( rDoc.GetChangeTrack() )
+ {
+ rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
+ Add( rR.pUserBViewList );
+ }
+
+ // Natural Language Formulas Flag
+ aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ lcl_AddWorkbookProtection( aRecList, *this );
+ lcl_AddBookviews( aRecList, *this );
+ }
+
+ // Bundlesheet
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
+ for( nC = 0 ; nC < nScTabCount ; nC++ )
+ if( rTabInfo.IsExportTab( nC ) )
+ {
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
+
+ for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
+ {
+ aTmpString = lcl_GetVbaTabName( nAdd );
+ ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
+ aRecList.AppendRecord( xBoundsheet );
+ rBoundsheetList.AppendRecord( xBoundsheet );
+ }
+
+ // COUNTRY - in BIFF8 in workbook globals
+ Add( new XclExpCountry( GetRoot() ) );
+ // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ lcl_AddCalcPr( aRecList, *this );
+
+ Add( new XclExpRecalcId );
+
+ // MSODRAWINGGROUP per-document data
+ aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
+ // Shared string table: SST, EXTSST
+ aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
+
+ Add( new XclExpBookExt );
+ }
+
+ Add( new ExcEof );
+}
+
+
+void ExcTable::FillAsTable( SCTAB nCodeNameIdx )
+{
+ InitializeTable( mnScTab );
+
+ RootData& rR = GetOldRoot();
+ XclBiff eBiff = GetBiff();
+ ScDocument& rDoc = GetDoc();
+
+ DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
+ DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
+
+ // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
+ if( eBiff == EXC_BIFF8 )
+ GetObjectManager().StartSheet();
+
+ // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
+
+ if( GetOutput() != EXC_OUTPUT_BINARY )
+ {
+ FillAsXmlTable( nCodeNameIdx );
+ return;
+ }
+
+
+ // WSBOOL needs data from page settings, create it here, add it later
+ boost::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
+ bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
+
+ if( eBiff <= EXC_BIFF5 )
+ {
+ Add( new ExcBof );
+ Add( new ExcDummy_02a );
+ }
+ else
+ {
+ Add( new ExcBof8 );
+ lcl_AddCalcPr( aRecList, *this );
+ }
+
+ // GUTS (count & size of outline icons)
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
+ // DEFROWHEIGHT, created by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
+
+ // COUNTRY - in BIFF5/7 in every worksheet
+ if( eBiff <= EXC_BIFF5 )
+ Add( new XclExpCountry( GetRoot() ) );
+
+ Add( new XclExpWsbool( bFitToPages ) );
+
+ // page settings (SETUP and various other records)
+ aRecList.AppendRecord( xPageSett );
+
+ const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
+ if (pTabProtect && pTabProtect->isProtected())
+ {
+ Add( new XclExpProtection(true) );
+ Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
+ Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
+ Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
+ }
+
+ // local link table: EXTERNCOUNT, EXTERNSHEET
+ if( eBiff <= EXC_BIFF5 )
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+
+ if ( eBiff == EXC_BIFF8 )
+ lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
+
+ // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ aRecList.AppendRecord( mxCellTable );
+
+ // MERGEDCELLS record, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
+ // label ranges
+ if( eBiff == EXC_BIFF8 )
+ Add( new XclExpLabelranges( GetRoot() ) );
+ // data validation (DVAL and list of DV records), generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
+
+ if( eBiff == EXC_BIFF8 )
+ {
+ // all MSODRAWING and OBJ stuff of this sheet goes here
+ aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
+ // pivot tables
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
+ }
+
+ // list of NOTE records, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_NOTE ) );
+
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+
+ if( eBiff == EXC_BIFF8 )
+ {
+ // sheet protection options
+ Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
+
+ // web queries
+ Add( new XclExpWebQueryBuffer( GetRoot() ) );
+
+ // conditional formats
+ Add( new XclExpCondFormatBuffer( GetRoot() ) );
+
+ if( HasVbaStorage() )
+ if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+ }
+
+ // list of HLINK records, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
+
+ // change tracking
+ if( rR.pUserBViewList )
+ {
+ for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
+ {
+ Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
+ Add( new XclExpUsersViewEnd );
+ }
+ }
+
+ // EOF
+ Add( new ExcEof );
+}
+
+void ExcTable::FillAsXmlTable( SCTAB nCodeNameIdx )
+{
+ RootData& rR = GetOldRoot();
+
+ // WSBOOL needs data from page settings, create it here, add it later
+ boost::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
+ bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
+
+ Add( new ExcBof8 );
+
+ Add( new XclExpWsbool( bFitToPages, mnScTab, &GetFilterManager() ) );
+
+ // GUTS (count & size of outline icons)
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
+ // DEFROWHEIGHT, created by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
+
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
+
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+
+ // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
+ aRecList.AppendRecord( mxCellTable );
+
+ // label ranges
+ Add( new XclExpLabelranges( GetRoot() ) );
+
+ // DFF not needed in MSOOXML export
+// GetObjectManager().AddSdrPage();
+// //! close Escher group shape and ESCHER_DgContainer
+// //! opened by XclExpObjList ctor MSODRAWING
+// rR.pObjRecs->EndSheet();
+// // all MSODRAWING and OBJ stuff of this sheet goes here
+// Add( rR.pObjRecs );
+
+ // pivot tables
+ aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
+
+ // list of NOTE records, generated by the cell table
+ XclExpRecordRef xNotes = mxCellTable->CreateRecord( EXC_ID_NOTE );
+ XclExpRecordList< XclExpNote >* xNoteList = dynamic_cast< XclExpRecordList< XclExpNote >* >( xNotes.get() );
+ if( xNoteList != NULL )
+ aRecList.AppendNewRecord( new XclExpComments( mnScTab, *xNoteList ) );
+
+ // web queries
+ Add( new XclExpWebQueryBuffer( GetRoot() ) );
+
+ lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
+
+ // MERGEDCELLS record, generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
+
+ // conditional formats
+ Add( new XclExpCondFormatBuffer( GetRoot() ) );
+
+ if( HasVbaStorage() )
+ if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+
+ // data validation (DVAL and list of DV records), generated by the cell table
+ aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
+
+ // list of HLINK records, generated by the cell table
+ XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
+ XclExpHyperlinkList* xHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
+ if( xHyperlinkList != NULL && !xHyperlinkList->IsEmpty() )
+ {
+ aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
+ aRecList.AppendRecord( xHyperlinks );
+ aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
+ }
+
+ aRecList.AppendRecord( xPageSett );
+
+ // change tracking
+ if( rR.pUserBViewList )
+ {
+ for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
+ {
+ Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
+ Add( new XclExpUsersViewEnd );
+ }
+ }
+
+ // all MSODRAWING and OBJ stuff of this sheet goes here
+ aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
+
+ // EOF
+ Add( new ExcEof );
+}
+
+
+void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx )
+{
+ InitializeTable( mnScTab );
+
+ if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
+ {
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new ExcBof );
+ }
+ else
+ {
+ Add( new ExcBof8 );
+ Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
+ }
+ // sheet view settings: WINDOW2, SCL, PANE, SELECTION
+ aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
+ Add( new ExcEof );
+ }
+}
+
+
+void ExcTable::Write( XclExpStream& rStrm )
+{
+ SetCurrScTab( mnScTab );
+ if( mxCellTable.get() )
+ mxCellTable->Finalize();
+ aRecList.Save( rStrm );
+}
+
+
+void ExcTable::WriteXml( XclExpXmlStream& rStrm )
+{
+ if (GetTabInfo().IsExportTab( mnScTab ) )
+ {
+ // worksheet export
+ String sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
+
+ sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
+
+ rStrm.PushStream( pWorksheet );
+
+ pWorksheet->startElement( XML_worksheet,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+ }
+
+ SetCurrScTab( mnScTab );
+ if( mxCellTable.get() )
+ mxCellTable->Finalize();
+ aRecList.SaveXml( rStrm );
+
+ if (GetTabInfo().IsExportTab( mnScTab ) )
+ {
+ rStrm.GetCurrentStream()->endElement( XML_worksheet );
+ rStrm.PopStream();
+ }
+}
+
+
+ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ aHeader( rRoot ),
+ pExpChangeTrack( NULL )
+{
+}
+
+
+ExcDocument::~ExcDocument()
+{
+ maTableList.RemoveAllRecords(); //! for the following assertion
+ delete pExpChangeTrack;
+}
+
+
+void ExcDocument::ReadDoc( void )
+{
+ InitializeConvert();
+
+ aHeader.FillAsHeader( maBoundsheetList );
+
+ SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
+ SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
+
+ for( ; nScTab < nScTabCount; ++nScTab )
+ {
+ if( GetTabInfo().IsExportTab( nScTab ) )
+ {
+ ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
+ maTableList.AppendRecord( xTab );
+ xTab->FillAsTable( nCodeNameIdx );
+ ++nCodeNameIdx;
+ }
+ }
+ for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
+ {
+ ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
+ maTableList.AppendRecord( xTab );
+ xTab->FillAsEmptyTable( nCodeNameIdx );
+ }
+
+ if ( GetBiff() == EXC_BIFF8 )
+ {
+ // complete temporary Escher stream
+ GetObjectManager().EndDocument();
+
+ // change tracking
+ if ( GetDoc().GetChangeTrack() )
+ pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
+ }
+}
+
+
+void ExcDocument::Write( SvStream& rSvStrm )
+{
+ if( !maTableList.IsEmpty() )
+ {
+ InitializeSave();
+
+ XclExpStream aXclStrm( rSvStrm, GetRoot() );
+
+ aHeader.Write( aXclStrm );
+
+ OSL_ENSURE( maTableList.GetSize() == maBoundsheetList.GetSize(),
+ "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
+
+ for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
+ {
+ // set current stream position in BOUNDSHEET record
+ ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
+ if( xBoundsheet.get() )
+ xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
+ // write the table
+ maTableList.GetRecord( nTab )->Write( aXclStrm );
+ }
+
+ // write the table stream positions into the BOUNDSHEET records
+ for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
+ maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
+ }
+ if( pExpChangeTrack )
+ pExpChangeTrack->Write();
+}
+
+void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+
+ rStrm.exportDocumentProperties( xDocProps );
+
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_workbook,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+ rWorkbook->singleElement( XML_fileVersion,
+ XML_appName, "Calc",
+ // OOXTODO: XML_codeName
+ // OOXTODO: XML_lastEdited
+ // OOXTODO: XML_lowestEdited
+ // OOXTODO: XML_rupBuild
+ FSEND );
+
+ if( !maTableList.IsEmpty() )
+ {
+ InitializeSave();
+
+ aHeader.WriteXml( rStrm );
+
+ for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
+ {
+ // write the table
+ maTableList.GetRecord( nTab )->WriteXml( rStrm );
+ }
+ }
+
+ if( pExpChangeTrack )
+ pExpChangeTrack->WriteXml( rStrm );
+
+ rWorkbook->endElement( XML_workbook );
+ rWorkbook.reset();
+
+ rStrm.commitStorage();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
new file mode 100644
index 000000000000..4bd3654caa64
--- /dev/null
+++ b/sc/source/filter/excel/excel.cxx
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/request.hxx>
+#include <sot/storage.hxx>
+#include <sot/exchange.hxx>
+#include <tools/globname.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include "scitems.hxx"
+#include <svl/stritem.hxx>
+#include "filter.hxx"
+#include "document.hxx"
+#include "xistream.hxx"
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+#include "exp_op.hxx"
+
+
+FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
+{
+ // check the passed Calc document
+ DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
+ if( !pDocument ) return eERR_INTERN; // should not happen
+
+ /* Import all BIFF versions regardless on eFormat, needed for import of
+ external cells (file type detection returns Excel4.0). */
+ if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
+ {
+ DBG_ERRORFILE( "::ScImportExcel - wrong file format specification" );
+ return eERR_FORMAT;
+ }
+
+ // check the input stream from medium
+ SvStream* pMedStrm = rMedium.GetInStream();
+ DBG_ASSERT( pMedStrm, "::ScImportExcel - medium without input stream" );
+ if( !pMedStrm ) return eERR_OPEN; // should not happen
+
+#if OSL_DEBUG_LEVEL > 0
+ using namespace ::com::sun::star;
+ using namespace ::comphelper;
+
+ /* Environment variable "OOO_OOXBIFFFILTER":
+ - "1" = use new OOX filter for import;
+ - undef/other = use old sc filter for import (OOX only as file dumper). */
+ const sal_Char* pcFileName = ::getenv( "OOO_OOXBIFFFILTER" );
+ bool bUseOoxFilter = pcFileName && (*pcFileName == '1') && (*(pcFileName + 1) == 0);
+ if( SfxObjectShell* pDocShell = pDocument->GetDocumentShell() ) try
+ {
+ uno::Reference< lang::XComponent > xComponent( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+
+ uno::Sequence< beans::NamedValue > aArgSeq( 1 );
+ aArgSeq[ 0 ].Name = CREATE_OUSTRING( "UseBiffFilter" );
+ aArgSeq[ 0 ].Value <<= bUseOoxFilter;
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= getProcessServiceFactory();
+ aArgs[ 1 ] <<= aArgSeq;
+ uno::Reference< document::XImporter > xImporter( ScfApiHelper::CreateInstanceWithArgs(
+ CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelBiffFilter" ), aArgs ), uno::UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComponent );
+
+ MediaDescriptor aMediaDesc;
+ SfxItemSet* pItemSet = rMedium.GetItemSet();
+ if( pItemSet )
+ {
+ SFX_ITEMSET_ARG( pItemSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, false);
+ if( pFileNameItem )
+ aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pFileNameItem->GetValue() );
+
+ SFX_ITEMSET_ARG( pItemSet, pPasswordItem, SfxStringItem, SID_PASSWORD, false);
+ if( pPasswordItem )
+ aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pPasswordItem->GetValue() );
+
+ SFX_ITEMSET_ARG( pItemSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false);
+ if( pEncryptionDataItem )
+ aMediaDesc[ MediaDescriptor::PROP_ENCRYPTIONDATA() ] = pEncryptionDataItem->GetValue();
+ }
+ aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream();
+ aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler();
+
+ // call the filter
+ uno::Reference< document::XFilter > xFilter( xImporter, uno::UNO_QUERY_THROW );
+ bool bResult = xFilter->filter( aMediaDesc.getAsConstPropertyValueList() );
+
+ // if filter returns false, document is invalid, or dumper has disabled import -> exit here
+ if( !bResult )
+ return ERRCODE_ABORT;
+
+ // if OOX filter has been used, exit with OK code
+ if( bUseOoxFilter )
+ return eERR_OK;
+ }
+ catch( uno::Exception& )
+ {
+ if( bUseOoxFilter )
+ return ERRCODE_ABORT;
+ // else ignore exception and import the document with this filter
+ }
+#endif
+
+ SvStream* pBookStrm = 0; // The "Book"/"Workbook" stream containing main data.
+ XclBiff eBiff = EXC_BIFF_UNKNOWN; // The BIFF version of the main stream.
+
+ // try to open an OLE storage
+ SotStorageRef xRootStrg;
+ SotStorageStreamRef xStrgStrm;
+ if( SotStorage::IsStorageFile( pMedStrm ) )
+ {
+ xRootStrg = new SotStorage( pMedStrm, false );
+ if( xRootStrg->GetError() )
+ xRootStrg = 0;
+ }
+
+ // try to open "Book" or "Workbook" stream in OLE storage
+ if( xRootStrg.Is() )
+ {
+ // try to open the "Book" stream
+ SotStorageStreamRef xBookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
+ XclBiff eBookBiff = xBookStrm.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm ) : EXC_BIFF_UNKNOWN;
+
+ // try to open the "Workbook" stream
+ SotStorageStreamRef xWorkbookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
+ XclBiff eWorkbookBiff = xWorkbookStrm.Is() ? XclImpStream::DetectBiffVersion( *xWorkbookStrm ) : EXC_BIFF_UNKNOWN;
+
+ // decide which stream to use
+ if( (eWorkbookBiff != EXC_BIFF_UNKNOWN) && ((eBookBiff == EXC_BIFF_UNKNOWN) || (eWorkbookBiff > eBookBiff)) )
+ {
+ /* Only "Workbook" stream exists; or both streams exist,
+ and "Workbook" has higher BIFF version than "Book" stream. */
+ xStrgStrm = xWorkbookStrm;
+ eBiff = eWorkbookBiff;
+ }
+ else if( eBookBiff != EXC_BIFF_UNKNOWN )
+ {
+ /* Only "Book" stream exists; or both streams exist,
+ and "Book" has higher BIFF version than "Workbook" stream. */
+ xStrgStrm = xBookStrm;
+ eBiff = eBookBiff;
+ }
+
+ pBookStrm = xStrgStrm;
+ }
+
+ // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
+ if( !pBookStrm )
+ {
+ eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
+ if( eBiff != EXC_BIFF_UNKNOWN )
+ pBookStrm = pMedStrm;
+ }
+
+ // try to import the file
+ FltError eRet = eERR_UNKN_BIFF;
+ if( pBookStrm )
+ {
+ pBookStrm->SetBufferSize( 0x8000 ); // still needed?
+
+ XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
+ ::std::auto_ptr< ImportExcel > xFilter;
+ switch( eBiff )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
+ break;
+ case EXC_BIFF8:
+ xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
+ }
+
+ return eRet;
+}
+
+
+static FltError lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
+ SvStream* pMedStrm, sal_Bool bBiff8, CharSet eNach )
+{
+ // try to open an OLE storage
+ SotStorageRef xRootStrg = new SotStorage( pMedStrm, false );
+ if( xRootStrg->GetError() ) return eERR_OPEN;
+
+ // create BIFF dependent strings
+ String aStrmName, aClipName, aClassName;
+ if( bBiff8 )
+ {
+ aStrmName = EXC_STREAM_WORKBOOK;
+ aClipName = CREATE_STRING( "Biff8" );
+ aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
+ }
+ else
+ {
+ aStrmName = EXC_STREAM_BOOK;
+ aClipName = CREATE_STRING( "Biff5" );
+ aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
+ }
+
+ // open the "Book"/"Workbook" stream
+ SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
+ if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;
+
+ xStrgStrm->SetBufferSize( 0x8000 ); // still needed?
+
+ FltError eRet = eERR_UNKN_BIFF;
+ XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
+ if ( bBiff8 )
+ {
+ ExportBiff8 aFilter( aExpData, *xStrgStrm );
+ eRet = aFilter.Write();
+ }
+ else
+ {
+ ExportBiff5 aFilter( aExpData, *xStrgStrm );
+ eRet = aFilter.Write();
+ }
+
+ if( eRet == eERR_RNGOVRFLW )
+ eRet = SCWARN_EXPORT_MAXROW;
+
+ SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
+ sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
+ xRootStrg->SetClass( aGlobName, nClip, aClassName );
+
+ xStrgStrm->Commit();
+ xRootStrg->Commit();
+
+ return eRet;
+}
+
+FltError ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
+ ExportFormatExcel eFormat, CharSet eNach )
+{
+ if( eFormat != ExpBiff5 && eFormat != ExpBiff8 )
+ return eERR_NI;
+
+ // check the passed Calc document
+ DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
+ if( !pDocument ) return eERR_INTERN; // should not happen
+
+ // check the output stream from medium
+ SvStream* pMedStrm = rMedium.GetOutStream();
+ DBG_ASSERT( pMedStrm, "::ScExportExcel5 - medium without output stream" );
+ if( !pMedStrm ) return eERR_OPEN; // should not happen
+
+ FltError eRet = eERR_UNKN_BIFF;
+ if( eFormat == ExpBiff5 || eFormat == ExpBiff8 )
+ eRet = lcl_ExportExcelBiff( rMedium, pDocument, pMedStrm, eFormat == ExpBiff8, eNach );
+
+ return eRet;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
new file mode 100644
index 000000000000..949cb0fb0615
--- /dev/null
+++ b/sc/source/filter/excel/excform.cxx
@@ -0,0 +1,1944 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "excform.hxx"
+#include <osl/endian.h>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "global.hxx"
+#include "formula/errorcodes.hxx"
+
+#include "imp_op.hxx"
+#include "root.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+
+using ::std::vector;
+
+const sal_uInt16 ExcelToSc::nRowMask = 0x3FFF;
+const sal_uInt16 ExcelToSc::nLastInd = 399;
+
+
+
+
+void ImportExcel::Formula25()
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXF = 0, nFormLen;
+ double fCurVal;
+ sal_uInt8 nFlag0;
+ sal_Bool bShrFmla;
+
+ aIn >> aXclPos;
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// BIFF2
+ sal_uInt8 nDummy;
+
+ aIn.Ignore( 3 );
+
+ aIn >> fCurVal;
+ aIn.Ignore( 1 );
+ aIn >> nDummy;
+ nFormLen = nDummy;
+ bShrFmla = false;
+ }
+ else
+ {// BIFF5
+ aIn >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 5 );
+
+ aIn >> nFormLen;
+
+ bShrFmla = nFlag0 & 0x08; // shared or not shared
+ }
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla );
+}
+
+
+void ImportExcel::Formula3()
+{
+ Formula4();
+}
+
+
+void ImportExcel::Formula4()
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXF, nFormLen;
+ double fCurVal;
+ sal_uInt8 nFlag0;
+
+ aIn >> aXclPos >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 1 );
+ aIn >> nFormLen;
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, false );
+}
+
+
+void ImportExcel::Formula( const XclAddress& rXclPos,
+ sal_uInt16 nXF, sal_uInt16 nFormLen, double& rCurVal, sal_Bool bShrFmla )
+{
+ ConvErr eErr = ConvOK;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis = 0;
+ sal_Bool bConvert;
+
+ pFormConv->Reset( aScPos );
+
+ if( bShrFmla )
+ bConvert = !pFormConv->GetShrFmla( pErgebnis, maStrm, nFormLen );
+ else
+ bConvert = sal_True;
+
+ if( bConvert )
+ eErr = pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ ScFormulaCell* pZelle = NULL;
+
+ if( pErgebnis )
+ {
+ pZelle = new ScFormulaCell( pD, aScPos, pErgebnis );
+ pD->PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pZelle, (sal_Bool)sal_True );
+ }
+ else
+ {
+ CellType eCellType;
+ ScBaseCell* pBaseCell;
+ pD->GetCellType( aScPos.Col(), aScPos.Row(), aScPos.Tab(), eCellType );
+ if( eCellType == CELLTYPE_FORMULA )
+ {
+ pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell );
+ pZelle = ( ScFormulaCell* ) pBaseCell;
+ if( pZelle )
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ }
+ }
+
+ if( pZelle )
+ {
+ if( eErr != ConvOK )
+ ExcelToSc::SetError( *pZelle, eErr );
+ (void)rCurVal;
+ }
+
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ }
+}
+
+
+
+
+ExcelToSc::ExcelToSc( const XclImpRoot& rRoot ) :
+ ExcelConverterBase( 512 ),
+ XclImpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() )
+{
+}
+
+ExcelToSc::~ExcelToSc()
+{
+}
+
+void ExcelToSc::GetDummy( const ScTokenArray*& pErgebnis )
+{
+ aPool.Store( CREATE_STRING( "Dummy()" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+}
+
+
+// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
+// otherwise it will seek to the first byte after the additional content (eg
+// inline arrays) following <nFormulaLen>
+ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ sal_uInt8 nOp, nLen, nByte;
+ sal_uInt16 nUINT16;
+ sal_Int16 nINT16;
+ double fDouble;
+ String aString;
+ sal_Bool bError = false;
+ sal_Bool bArrayFormula = false;
+ TokenId nMerk0;
+ const sal_Bool bRangeName = eFT == FT_RangeName;
+ const sal_Bool bSharedFormula = eFT == FT_SharedFormula;
+ const sal_Bool bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ ExtensionTypeVec aExtensions;
+
+ bExternName = false;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ {
+ aPool.Store( CREATE_STRING( "-/-" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ return ConvOK;
+ }
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nUINT16 = 3;
+
+ if( meBiff != EXC_BIFF2 )
+ nUINT16++;
+
+ aIn.Ignore( nUINT16 );
+
+ bArrayFormula = sal_True;
+ break;
+ case 0x03: // Addition [312 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocAdd << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x04: // Subtraction [313 264]
+ // SECOMD-TOP minus TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocSub << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x05: // Multiplication [313 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocMul << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x06: // Division [313 264]
+ // divide TOP by SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocDiv << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x07: // Exponetiation [313 265]
+ // raise SECOND-TOP to power of TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocPow << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x08: // Concatenation [313 265]
+ // append TOP to SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocAmpersand << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x09: // Less Than [313 265]
+ // SECOND-TOP < TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLess << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ // SECOND-TOP <= TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLessEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0B: // Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreaterEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0D: // Greater Than [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreater << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0E: // Not Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocNotEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0F: // Intersection [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocIntersect << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x10: // Union [314 265]
+ // ocSep behelfsweise statt 'ocUnion'
+ aStack >> nMerk0;
+ aPool << aStack << ocSep << nMerk0;
+ // doesn't fit exactly, but is more Excel-like
+ aPool >> aStack;
+ break;
+ case 0x11: // Range [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocRange << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x12: // Unary Plus [312 264]
+ aPool << ocAdd << aStack;
+ aPool >> aStack;
+ break;
+ case 0x13: // Unary Minus [312 264]
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+ case 0x14: // Percent Sign [312 264]
+ aPool << aStack << ocPercentSign;
+ aPool >> aStack;
+ break;
+ case 0x15: // Parenthesis [326 278]
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x16: // Missing Argument [314 266]
+ aPool << ocMissing;
+ aPool >> aStack;
+ GetTracer().TraceFormulaMissingArg();
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ aString = aIn.ReadRawByteString( nLen );
+
+ aStack << aPool.Store( aString );
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt16 nData, nFakt;
+ sal_uInt8 nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ else if( nOpt & 0x10 ) // AttrSum
+ DoMulArgs( ocSum, 1 );
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 7 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 10 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 3 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 4 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ aIn >> nByte;
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+ aPool >> aStack;
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ aIn >> nByte;
+ if( nByte == 0 )
+ aPool << ocFalse << ocOpen << ocClose;
+ else
+ aPool << ocTrue << ocOpen << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn >> nUINT16;
+ aStack << aPool.Store( ( double ) nUINT16 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn >> fDouble;
+ aStack << aPool.Store( fDouble );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn >> nByte >> nUINT16;
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 );
+ if( bAllowArrays )
+ {
+ aStack << aPool.StoreMatrix();
+ aExtensions.push_back( EXTENSION_ARRAY );
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ {
+ sal_uInt16 nXclFunc;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ {
+ sal_uInt16 nXclFunc;
+ sal_uInt8 nParamCount;
+ aIn >> nParamCount;
+ nParamCount &= 0x7F;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ {
+ aIn >> nUINT16;
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 5 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 8 ); break;
+ case EXC_BIFF5: aIn.Ignore( 12 ); break;
+ default:
+ OSL_FAIL(
+ "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ const XclImpName* pName = GetNameManager().GetName( nUINT16 );
+ if(pName && !pName->GetScRangeData())
+ aStack << aPool.Store( ocMacro, pName->GetXclName() );
+ else
+ aStack << aPool.StoreName(nUINT16, true);
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( sal_True );
+ aSRD.SetRowDeleted( sal_True );
+ }
+
+ aStack << aPool.Store( aSRD );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ {
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt8 nColFirst, nColLast;
+ ScSingleRefData& rSRef1 = aCRD.Ref1;
+ ScSingleRefData& rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( sal_True );
+ rSRef2.SetTabRel( sal_True );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ // no information which part is deleted, set all
+ rSRef1.SetColDeleted( sal_True );
+ rSRef1.SetRowDeleted( sal_True );
+ rSRef2.SetColDeleted( sal_True );
+ rSRef2.SetRowDeleted( sal_True );
+ }
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ aExtensions.push_back( EXTENSION_MEMAREA );
+ // fall through
+
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 4 : 6 );
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( sal_True );
+ aCRD.Ref2.SetTabRel( sal_True );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 1 : 2 );
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aString.AssignAscii( "COMM_EQU_FUNC" );
+ aIn >> nByte;
+ aString += String::CreateFromInt32( nByte );
+ aIn >> nByte;
+ aStack << aPool.Store( aString );
+ DoMulArgs( ocPush, nByte + 1 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ aIn >> nINT16;
+ aIn.Ignore( 8 );
+ aIn >> nUINT16;
+ if( nINT16 >= 0 )
+ {
+ const ExtName* pExtName = rR.pExtNameBuff->GetNameByIndex( nINT16, nUINT16 );
+ if( pExtName && pExtName->IsDDE() &&
+ rR.pExtSheetBuff->IsLink( ( sal_uInt16 ) nINT16 ) )
+ {
+ String aAppl, aExtDoc;
+ TokenId nPar1, nPar2;
+
+ rR.pExtSheetBuff->GetLink( ( sal_uInt16 ) nINT16 , aAppl, aExtDoc );
+ nPar1 = aPool.Store( aAppl );
+ nPar2 = aPool.Store( aExtDoc );
+ nMerk0 = aPool.Store( pExtName->aName );
+ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
+ << nMerk0 << ocClose;
+
+ GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT, ScMatrixRef() );
+ }
+ else
+ aPool << ocBad;
+
+ aPool >> aStack;
+ }
+ else
+ aStack << aPool.StoreName( nUINT16, true );
+ aIn.Ignore( 12 );
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ {
+ sal_uInt16 nTabFirst, nTabLast, nRow;
+ sal_Int16 nExtSheet;
+ sal_uInt8 nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ { // von extern
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ { // in aktuellem Workbook
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( sal_True );
+ aSRD.SetTabRel( false );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( sal_True );
+ aSRD.SetRowDeleted( sal_True );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ aSRD.SetTabDeleted( sal_True );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ aCRD.Ref2.SetTabDeleted( !ValidTab(static_cast<SCTAB>(nTabLast)) );
+ aStack << aPool.Store( aCRD );
+ }
+ else
+ aStack << aPool.Store( aSRD );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ {
+ sal_uInt16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ sal_Int16 nExtSheet;
+ sal_uInt8 nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData& rR1 = aCRD.Ref1;
+ ScSingleRefData& rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( sal_True );
+ rR1.SetTabRel( false );
+ rR2.SetFlag3D( nTabFirst != nTabLast );
+ rR2.SetTabRel( false );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ // no information which part is deleted, set all
+ rR1.SetColDeleted( sal_True );
+ rR1.SetRowDeleted( sal_True );
+ rR2.SetColDeleted( sal_True );
+ rR2.SetRowDeleted( sal_True );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ rR1.SetTabDeleted( sal_True );
+ if ( !ValidTab(static_cast<SCTAB>(nTabLast)) )
+ rR2.SetTabDeleted( sal_True );
+
+ aStack << aPool.Store( aCRD );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ default: bError = sal_True;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( aIn.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else if( bExternName )
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrExternal;
+ }
+ else if( bArrayFormula )
+ {
+ pErgebnis = NULL;
+ eRet = ConvOK;
+ }
+ else
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ aIn.Seek( nEndPos );
+
+ if( eRet == ConvOK )
+ ReadExtensions( aExtensions, aIn );
+
+ return eRet;
+}
+
+
+// stream seeks to first byte after <nFormulaLen>
+ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen,
+ SCsTAB nTab, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ sal_uInt8 nOp, nLen;
+ sal_Size nIgnore;
+ sal_uInt16 nUINT16;
+ sal_uInt8 nByte;
+ sal_Bool bError = false;
+ sal_Bool bArrayFormula = false;
+ const sal_Bool bRangeName = eFT == FT_RangeName;
+ const sal_Bool bSharedFormula = eFT == FT_SharedFormula;
+ const sal_Bool bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ aCRD.Ref1.nTab = aCRD.Ref2.nTab = aEingPos.Tab();
+
+ bExternName = false;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ return ConvOK;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+ nIgnore = 0;
+
+ // always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ bArrayFormula = sal_True;
+ break;
+ case 0x02: // Data Table [325 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ break;
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ nIgnore = nLen;
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt16 nData, nFakt;
+ sal_uInt8 nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 3; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 4; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nIgnore = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ nIgnore = 2;
+ break;
+ case 0x1F: // Number [315 266]
+ nIgnore = 8;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nIgnore = (meBiff == EXC_BIFF2) ? 6 : 7;
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 1 : 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 2 : 3;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: nIgnore = 14; break;
+ default: OSL_FAIL( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ rRangeList.Append( aSRD, nTab );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ {
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt8 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( sal_True );
+ rSRef2.SetTabRel( sal_True );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ nIgnore = (meBiff == EXC_BIFF2) ? 4 : 6;
+ break;
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nIgnore = 3;
+ break;
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nIgnore = 6;
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ rRangeList.Append( aSRD, nTab );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( sal_True );
+ aCRD.Ref2.SetTabRel( sal_True );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ nIgnore = (meBiff == EXC_BIFF2) ? 1 : 2;
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nIgnore = 2;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nIgnore = 24;
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ {
+ sal_uInt16 nTabFirst, nTabLast, nRow;
+ sal_Int16 nExtSheet;
+ sal_uInt8 nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ sal_Bool b3D = ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName;
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( b3D );
+ aSRD.SetTabRel( false );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aSRD;
+ aCRD.Ref2.nCol = aSRD.nCol;
+ aCRD.Ref2.nRow = aSRD.nRow;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ b3D = ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() );
+ aCRD.Ref2.SetFlag3D( b3D );
+ aCRD.Ref2.SetTabRel( false );
+ rRangeList.Append( aCRD, nTab );
+ }
+ else
+ rRangeList.Append( aSRD, nTab );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ {
+ sal_uInt16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ sal_Int16 nExtSheet;
+ sal_uInt8 nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName );
+ rR1.SetTabRel( false );
+ rR2.SetFlag3D( ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() ) || bRangeName );
+ rR2.SetTabRel( false );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nIgnore = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nIgnore = 20;
+ break;
+ default: bError = sal_True;
+ }
+ bError |= !aIn.IsValid();
+
+ aIn.Ignore( nIgnore );
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ eRet = ConvErrNi;
+ else if( aIn.GetRecPos() != nEndPos )
+ eRet = ConvErrCount;
+ else if( bExternName )
+ eRet = ConvErrExternal;
+ else if( bArrayFormula )
+ eRet = ConvOK;
+ else
+ eRet = ConvOK;
+
+ aIn.Seek( nEndPos );
+ return eRet;
+}
+
+ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/,
+ const String& /*rUrl*/, const vector<String>& /*rTabNames*/ )
+{
+ // not implemented ...
+ return ConvErrNi;
+}
+
+sal_Bool ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 );
+ if( GetBiff() != EXC_BIFF5 )
+ return false;
+
+ sal_uInt8 nOp;
+ sal_uInt16 nRow1, nRow2;
+ sal_uInt8 nCol1, nCol2;
+ SCTAB nTab1, nTab2;
+ sal_uInt16 nTabFirst, nTabLast;
+ sal_Int16 nRefIdx;
+
+ sal_Size nSeek;
+ sal_Size nEndPos = rStrm.GetRecPos() + nLen;
+
+ while( rStrm.IsValid() && (rStrm.GetRecPos() < nEndPos) )
+ {
+ rStrm >> nOp;
+ nSeek = 0;
+
+ switch( nOp )
+ {
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ rStrm >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ // Area Reference Within a Shared Formula[ 274]
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+
+ goto _3d_common;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ _3d_common:
+ nTab1 = static_cast< SCTAB >( nTabFirst );
+ nTab2 = static_cast< SCTAB >( nTabLast );
+
+ // skip references to deleted sheets
+ if( (nRefIdx >= 0) || !ValidTab( nTab1 ) || (nTab1 != nTab2) )
+ break;
+
+ goto _common;
+ _common:
+ // do not check abs/rel flags, linked controls have set them!
+// if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
+ {
+ ScRange aScRange;
+ nRow1 &= 0x3FFF;
+ nRow2 &= 0x3FFF;
+ if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
+ rRangeList.Append( aScRange );
+ }
+ break;
+
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nSeek = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nSeek = 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nSeek = 3;
+ break;
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nSeek = 4;
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nSeek = 6;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nSeek = 7;
+ break;
+ case 0x1F: // Number [315 266]
+ nSeek = 8;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ nSeek = 14;
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nSeek = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nSeek = 20;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nSeek = 24;
+ break;
+ case 0x17: // String Constant [314 266]
+ nSeek = rStrm.ReaduInt8();
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt8 nOpt;
+ sal_uInt16 nData;
+ rStrm >> nOpt >> nData;
+ if( nOpt & 0x04 )
+ nSeek = nData * 2 + 2;
+ }
+ break;
+ }
+
+ rStrm.Ignore( nSeek );
+ }
+ rStrm.Seek( nEndPos );
+
+ return !rRangeList.empty();
+}
+
+void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz )
+{
+ TokenId eParam[ 256 ];
+ sal_Int32 nLauf;
+
+ if( eId == ocCeil || eId == ocFloor )
+ {
+ aStack << aPool.Store( 1.0 ); // default, da in Excel nicht vorhanden
+ nAnz++;
+ }
+
+ for( nLauf = 0; aStack.HasMoreTokens() && (nLauf < nAnz); nLauf++ )
+ aStack >> eParam[ nLauf ];
+ // #i70925# reduce parameter count, if no more tokens available on token stack
+ if( nLauf < nAnz )
+ nAnz = static_cast< sal_uInt8 >( nLauf );
+
+ if( nAnz > 0 && eId == ocExternal )
+ {
+ TokenId n = eParam[ nAnz - 1 ];
+//##### GRUETZE FUER BASIC-FUNCS RICHTEN!
+ if( const String* pExt = aPool.GetExternal( n ) )
+ {
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclMacroName( *pExt ) )
+ aPool << pFuncInfo->meOpCode;
+ else
+ aPool << n;
+ nAnz--;
+ }
+ else
+ aPool << eId;
+ }
+ else
+ aPool << eId;
+
+ aPool << ocOpen;
+
+ if( nAnz > 0 )
+ {
+ // attention: 0 = last parameter, nAnz-1 = first parameter
+ sal_Int16 nNull = -1; // skip this parameter
+ sal_Int16 nSkipEnd = -1; // skip all parameters <= nSkipEnd
+
+ sal_Int16 nLast = nAnz - 1;
+
+ // Funktionen, bei denen Parameter wegfallen muessen
+ if( eId == ocPercentrank && nAnz == 3 )
+ nSkipEnd = 0; // letzten Parameter bei Bedarf weglassen
+
+ // Joost-Spezialfaelle
+ else if( eId == ocIf )
+ {
+ sal_uInt16 nNullParam = 0;
+ for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ {
+ if( aPool.IsSingleOp( eParam[ nLauf ], ocMissing ) )
+ {
+ if( !nNullParam )
+ nNullParam = (sal_uInt16) aPool.Store( ( double ) 0.0 );
+ eParam[ nLauf ] = nNullParam;
+ }
+ }
+ }
+
+ // [Parameter{;Parameter}]
+ if( nLast > nSkipEnd )
+ {
+ aPool << eParam[ nLast ];
+ for( nLauf = nLast - 1 ; nLauf > nSkipEnd ; nLauf-- )
+ {
+ if( nLauf != nNull )
+ aPool << ocSep << eParam[ nLauf ];
+ }
+ }
+ }
+ aPool << ocClose;
+
+ aPool >> aStack;
+}
+
+
+void ExcelToSc::ExcRelToScRel( sal_uInt16 nRow, sal_uInt8 nCol, ScSingleRefData &rSRD, const sal_Bool bName )
+{
+ if( bName )
+ {
+ // C O L
+ if( nRow & 0x4000 )
+ {// rel Col
+ rSRD.SetColRel( sal_True );
+ rSRD.nRelCol = static_cast<SCsCOL>(static_cast<sal_Int8>(nCol));
+ }
+ else
+ {// abs Col
+ rSRD.SetColRel( false );
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+ }
+
+ // R O W
+ if( nRow & 0x8000 )
+ {// rel Row
+ rSRD.SetRowRel( sal_True );
+ if( nRow & 0x2000 ) // Bit 13 gesetzt?
+ // -> Row negativ
+ rSRD.nRelRow = static_cast<SCsROW>(static_cast<sal_Int16>(nRow | 0xC000));
+ else
+ // -> Row positiv
+ rSRD.nRelRow = static_cast<SCsROW>(nRow & nRowMask);
+ }
+ else
+ {// abs Row
+ rSRD.SetRowRel( false );
+ rSRD.nRow = static_cast<SCROW>(nRow & nRowMask);
+ }
+
+ // T A B
+ // abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab();
+ }
+ else
+ {
+ // C O L
+ rSRD.SetColRel( ( nRow & 0x4000 ) > 0 );
+ rSRD.nCol = static_cast<SCsCOL>(nCol);
+
+ // R O W
+ rSRD.SetRowRel( ( nRow & 0x8000 ) > 0 );
+ rSRD.nRow = static_cast<SCsROW>(nRow & nRowMask);
+
+ if ( rSRD.IsColRel() )
+ rSRD.nRelCol = rSRD.nCol - aEingPos.Col();
+ if ( rSRD.IsRowRel() )
+ rSRD.nRelRow = rSRD.nRow - aEingPos.Row();
+
+ // T A B
+ // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
+ }
+}
+
+
+const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
+{
+ sal_uInt16 nError;
+ aPool.Reset();
+ aStack.Reset();
+
+ DefTokenId eOc;
+
+ switch( eType )
+ {
+ case xlErrNull: eOc = ocStop; nError = errNoCode; break;
+ case xlErrDiv0: eOc = ocStop; nError = errDivisionByZero; break;
+ case xlErrValue: eOc = ocStop; nError = errNoValue; break;
+ case xlErrRef: eOc = ocStop; nError = errNoRef; break;
+ case xlErrName: eOc = ocStop; nError = errNoName; break;
+ case xlErrNum: eOc = ocStop; nError = errIllegalFPOperation; break;
+ case xlErrNA: eOc = ocNotAvail; nError = NOTAVAILABLE; break;
+ case xlErrTrue: eOc = ocTrue; nError = 0; break;
+ case xlErrFalse: eOc = ocFalse; nError = 0; break;
+ case xlErrUnknown: eOc = ocStop; nError = errUnknownState; break;
+ default:
+ OSL_FAIL( "ExcelToSc::GetBoolErr - wrong enum!" );
+ eOc = ocNoName;
+ nError = errUnknownState;
+ }
+
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+
+ aPool >> aStack;
+
+ const ScTokenArray* pErgebnis = aPool[ aStack.Get() ];
+ if( nError )
+ ( ( ScTokenArray* ) pErgebnis )->SetCodeError( nError );
+
+ ( ( ScTokenArray* ) pErgebnis )->SetRecalcModeNormal();
+
+ return pErgebnis;
+}
+
+
+// if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
+// else stream pointer stays unchanged
+sal_Bool ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
+{
+ sal_uInt8 nOp;
+ sal_Bool bRet = sal_True;
+
+ if( nFormulaLen == 0 )
+ bRet = false;
+ else
+ {
+ aIn.PushPosition();
+
+ aIn >> nOp;
+
+ if( nOp == 0x01 ) // Shared Formula [ 277]
+ {
+ sal_uInt16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
+ ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
+
+ bRet = sal_True;
+ }
+ else
+ bRet = false;
+
+ aIn.PopPosition();
+ }
+
+ if( bRet )
+ {
+ aIn.Ignore( nFormulaLen );
+ rpErgebnis = aPool[ aStack.Get() ];
+ }
+ else
+ rpErgebnis = NULL;
+
+ return bRet;
+}
+
+
+void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
+{
+ sal_uInt16 nInd;
+
+ switch( eErr )
+ {
+ case ConvErrNi: nInd = errUnknownToken; break;
+ case ConvErrNoMem: nInd = errCodeOverflow; break;
+ case ConvErrExternal: nInd = errNoName; break;
+ case ConvErrCount: nInd = errCodeOverflow; break;
+ default: nInd = errNoCode; // hier fiel mir nichts
+ // Besseres ein...
+ }
+
+ rCell.SetErrCode( nInd );
+}
+
+
+void ExcelToSc::SetComplCol( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsColRel() )
+ rSRD.nRelCol = MAXCOL - aEingPos.Col();
+ else
+ rSRD.nCol = MAXCOL;
+}
+
+
+void ExcelToSc::SetComplRow( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsRowRel() )
+ rSRD.nRelRow = MAXROW - aEingPos.Row();
+ else
+ rSRD.nRow = MAXROW;
+}
+
+void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn )
+{
+ // printf( "inline array;\n" );
+
+ sal_uInt8 nByte;
+ sal_uInt16 nUINT16;
+ double fDouble;
+ String aString;
+ ScMatrix* pMatrix;
+
+ aIn >> nByte >> nUINT16;
+
+ SCSIZE nC, nCols;
+ SCSIZE nR, nRows;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ nCols = nByte + 1;
+ nRows = nUINT16 + 1;
+ }
+ else
+ {
+ nCols = nByte ? nByte : 256;
+ nRows = nUINT16;
+ }
+
+ pMatrix = aPool.GetMatrix( n );
+
+ if( NULL != pMatrix )
+ {
+ pMatrix->Resize(nCols, nRows);
+ pMatrix->GetDimensions( nC, nR);
+ if( nC != nCols || nR != nRows )
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - matrix size mismatch" );
+ pMatrix = NULL;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - missing matrix" );
+ }
+
+ for( nR = 0 ; nR < nRows; nR++ )
+ {
+ for( nC = 0 ; nC < nCols; nC++ )
+ {
+ aIn >> nByte;
+ switch( nByte )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ aIn.Ignore( 8 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutEmpty( nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_DOUBLE:
+ aIn >> fDouble;
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutDouble( fDouble, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_STRING:
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ aIn >> nUINT16;
+ aString = aIn.ReadUniString( nUINT16 );
+ }
+ else
+ {
+ aIn >> nByte;
+ aString = aIn.ReadRawByteString( nByte );
+ }
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutString( aString, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_BOOL:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutBoolean( nByte != 0, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_ERROR:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutError( XclTools::GetScErrorCode( nByte ), nC, nR );
+ }
+ break;
+ }
+ }
+ }
+}
+
+void ExcelToSc::ReadExtensionNlr( XclImpStream& aIn )
+{
+ // printf( "natural lang fmla;\n" );
+
+ sal_uInt32 nFlags;
+ aIn >> nFlags;
+
+ sal_uInt32 nCount = nFlags & EXC_TOK_NLR_ADDMASK;
+ aIn.Ignore( nCount * 4 ); // Drop the cell positions
+}
+
+void ExcelToSc::ReadExtensionMemArea( XclImpStream& aIn )
+{
+ // printf( "mem area;\n" );
+
+ sal_uInt16 nCount;
+ aIn >> nCount;
+
+ aIn.Ignore( nCount * ((GetBiff() == EXC_BIFF8) ? 8 : 6) ); // drop the ranges
+}
+
+void ExcelToSc::ReadExtensions( const ExtensionTypeVec& rExtensions,
+ XclImpStream& aIn )
+{
+ unsigned int nArray = 0;
+
+ for( unsigned int i = 0 ; i < rExtensions.size() ; i++ )
+ {
+ ExtensionType eType = rExtensions[i];
+
+ switch( eType )
+ {
+ case EXTENSION_ARRAY:
+ ReadExtensionArray( nArray++, aIn );
+ break;
+
+ case EXTENSION_NLR:
+ ReadExtensionNlr( aIn );
+ break;
+
+ case EXTENSION_MEMAREA:
+ ReadExtensionMemArea( aIn );
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
new file mode 100644
index 000000000000..f989abc3c196
--- /dev/null
+++ b/sc/source/filter/excel/excform8.cxx
@@ -0,0 +1,1681 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "excform.hxx"
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+
+#include "externalrefmgr.hxx"
+
+#include <vector>
+#include <cstring>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::std::vector;
+
+namespace {
+
+/**
+ * Extract a file path from OLE link path. An OLE link path is expected to
+ * be in the following format:
+ *
+ * Excel.Sheet.8 \3 [file path]
+ */
+bool extractFilePath(const OUString& rUrl, OUString& rPath)
+{
+ const char* prefix = "Excel.Sheet.8\3";
+ size_t nPrefixLen = ::std::strlen(prefix);
+
+ sal_Int32 n = rUrl.getLength();
+ if (n <= static_cast<sal_Int32>(nPrefixLen))
+ // needs to have the specified prefix.
+ return false;
+
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rUrl.getStr();
+ for (size_t i = 0; i < static_cast<size_t>(n); ++i, ++p)
+ {
+ if (i < nPrefixLen)
+ {
+ sal_Unicode pc = static_cast<sal_Unicode>(*prefix++);
+ if (pc != *p)
+ return false;
+
+ continue;
+ }
+ aBuf.append(*p);
+ }
+
+ rPath = aBuf.makeStringAndClear();
+ return true;
+}
+
+}
+
+ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
+ mnFileId(0), mbExternal(false)
+{
+}
+
+// ============================================================================
+
+ExcelToSc8::ExcelToSc8( const XclImpRoot& rRoot ) :
+ ExcelToSc( rRoot ),
+ rLinkMan( rRoot.GetLinkManager() )
+{
+}
+
+
+ExcelToSc8::~ExcelToSc8()
+{
+}
+
+bool ExcelToSc8::GetExternalFileIdFromXti( sal_uInt16 nIxti, sal_uInt16& rFileId ) const
+{
+ const String* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
+ if (!pFileUrl || pFileUrl->Len() == 0 || !GetDocShell())
+ return false;
+
+ String aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ rFileId = pRefMgr->getExternalFileId(aFileUrl);
+
+ return true;
+}
+
+bool ExcelToSc8::Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo )
+{
+ rFirstTab = rLastTab = 0;
+ rExtInfo.mbExternal = !rLinkMan.IsSelfRef(nIxti);
+ bool bSuccess = rLinkMan.GetScTabRange(rFirstTab, rLastTab, nIxti);
+ if (!bSuccess)
+ return false;
+
+ if (!rExtInfo.mbExternal)
+ // This is internal reference. Stop here.
+ return true;
+
+ rExtInfo.maTabName = rLinkMan.GetSupbookTabName(nIxti, rFirstTab);
+ return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
+}
+
+bool ExcelToSc8::HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo)
+{
+ const String* pUrl = rLinkMan.GetSupbookUrl(nXtiIndex);
+ if (!pUrl)
+ return false;
+
+ OUString aPath;
+ if (!extractFilePath(*pUrl, aPath))
+ // file path extraction failed.
+ return false;
+
+ OUString aFileUrl = ScGlobal::GetAbsDocName(aPath, GetDocShell());
+ return rExtName.CreateOleData(GetDoc(), aFileUrl, rExtInfo.mnFileId, rExtInfo.maTabName, rExtInfo.maRange);
+}
+
+// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
+// otherwise it will seek to the first byte past additional content after <nFormulaLen>
+ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
+{
+ sal_uInt8 nOp, nLen, nByte;
+ sal_uInt16 nUINT16;
+ double fDouble;
+ String aString;
+ sal_Bool bError = false;
+ sal_Bool bArrayFormula = false;
+ TokenId nMerk0;
+ const sal_Bool bRangeName = eFT == FT_RangeName;
+ const sal_Bool bSharedFormula = eFT == FT_SharedFormula;
+ const sal_Bool bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ ExtensionTypeVec aExtensions;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ {
+ aPool.Store( CREATE_STRING( "-/-" ) );
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ return ConvOK;
+ }
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ aIn.Ignore( 4 );
+
+ bArrayFormula = sal_True;
+ break;
+ case 0x03: // Addition [312 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocAdd << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x04: // Subtraction [313 264]
+ // SECOMD-TOP minus TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocSub << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x05: // Multiplication [313 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocMul << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x06: // Division [313 264]
+ // divide TOP by SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocDiv << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x07: // Exponetiation [313 265]
+ // raise SECOND-TOP to power of TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocPow << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x08: // Concatenation [313 265]
+ // append TOP to SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocAmpersand << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x09: // Less Than [313 265]
+ // SECOND-TOP < TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLess << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ // SECOND-TOP <= TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLessEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0B: // Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreaterEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0D: // Greater Than [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreater << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0E: // Not Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocNotEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0F: // Intersection [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocIntersect << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x10: // Union [314 265]
+ // ocSep behelfsweise statt 'ocUnion'
+ aStack >> nMerk0;
+ aPool << aStack << ocSep << nMerk0;
+ // doesn't fit exactly, but is more Excel-like
+ aPool >> aStack;
+ break;
+ case 0x11: // Range [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocRange << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x12: // Unary Plus [312 264]
+ aPool << ocAdd << aStack;
+ aPool >> aStack;
+ break;
+ case 0x13: // Unary Minus [312 264]
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+ case 0x14: // Percent Sign [312 264]
+ aPool << aStack << ocPercentSign;
+ aPool >> aStack;
+ break;
+ case 0x15: // Parenthesis [326 278]
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x16: // Missing Argument [314 266]
+ aPool << ocMissing;
+ aPool >> aStack;
+ GetTracer().TraceFormulaMissingArg();
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen; // und?
+ aString = aIn.ReadUniString( nLen ); // reads Grbit even if nLen==0
+
+ aStack << aPool.Store( aString );
+ break;
+ case 0x18: // natural language formula
+ {
+ sal_uInt8 nEptg;
+ sal_uInt16 nCol, nRow;
+ aIn >> nEptg;
+ switch( nEptg )
+ { // name size ext type
+ case 0x01: // Lel 4 - err
+ aIn.Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x02: // Rw 4 - ref
+ case 0x03: // Col 4 - ref
+ case 0x06: // RwV 4 - val
+ case 0x07: // ColV 4 - val
+ aIn >> nRow >> nCol;
+
+ aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
+
+ if( nEptg == 0x02 || nEptg == 0x06 )
+ aSRD.SetRowRel( sal_True );
+ else
+ aSRD.SetColRel( sal_True );
+
+ aSRD.CalcRelFromAbs( aEingPos );
+
+ aStack << aPool.StoreNlf( aSRD );
+ break;
+ case 0x0A: // Radical 13 - ref
+ aIn >> nRow >> nCol;
+ aIn.Ignore( 9 );
+
+ aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
+
+ aSRD.SetColRel( sal_True );
+
+ aSRD.CalcRelFromAbs( aEingPos );
+
+ aStack << aPool.StoreNlf( aSRD );
+ break;
+ case 0x0B: // RadicalS 13 x ref
+ aIn.Ignore( 13 );
+ aExtensions.push_back( EXTENSION_NLR );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x0C: // RwS 4 x ref
+ case 0x0D: // ColS 4 x ref
+ case 0x0E: // RwSV 4 x val
+ case 0x0F: // ColSV 4 x val
+ aIn.Ignore( 4 );
+ aExtensions.push_back( EXTENSION_NLR );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case 0x10: // RadicalLel 4 - err
+ case 0x1D: // SxName 4 - val
+ aIn.Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ default:
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt16 nData, nFakt;
+ sal_uInt8 nOpt;
+
+ aIn >> nOpt >> nData;
+ nFakt = 2;
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ else if( nOpt & 0x10 ) // AttrSum
+ DoMulArgs( ocSum, 1 );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ aIn >> nByte;
+
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+ aPool >> aStack;
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ aIn >> nByte;
+ if( nByte == 0 )
+ aPool << ocFalse << ocOpen << ocClose;
+ else
+ aPool << ocTrue << ocOpen << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn >> nUINT16;
+ aStack << aPool.Store( ( double ) nUINT16 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn >> fDouble;
+ aStack << aPool.Store( fDouble );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn >> nByte >> nUINT16;
+ aIn.Ignore( 4 );
+ if( bAllowArrays )
+ {
+ aStack << aPool.StoreMatrix();
+ aExtensions.push_back( EXTENSION_ARRAY );
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ {
+ sal_uInt16 nXclFunc;
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ {
+ sal_uInt16 nXclFunc;
+ sal_uInt8 nParamCount;
+ aIn >> nParamCount >> nXclFunc;
+ nParamCount &= 0x7F;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ {
+ aIn >> nUINT16;
+ aIn.Ignore( 2 );
+ const XclImpName* pName = GetNameManager().GetName( nUINT16 );
+ if (pName)
+ {
+ if (pName->GetScRangeData())
+ aStack << aPool.StoreName(nUINT16, pName->IsGlobal());
+ else
+ // used-defined macro name.
+ aStack << aPool.Store(ocMacro, pName->GetXclName());
+ }
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ {
+ sal_uInt16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nCol = static_cast<SCCOL>(nCol);
+ aSRD.nRow = nRow & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( sal_True );
+ aSRD.SetRowDeleted( sal_True );
+ }
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ {
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt16 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( sal_True );
+ rSRef2.SetTabRel( sal_True );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ // no information which part is deleted, set all
+ rSRef1.SetColDeleted( sal_True );
+ rSRef1.SetRowDeleted( sal_True );
+ rSRef2.SetColDeleted( sal_True );
+ rSRef2.SetRowDeleted( sal_True );
+ }
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ aExtensions.push_back( EXTENSION_MEMAREA );
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+ break;
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ sal_uInt16 nRow, nCol;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt16 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( sal_True );
+ aCRD.Ref2.SetTabRel( sal_True );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+// aPool << ocBad;
+// aPool >> aStack;
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aString.AssignAscii( "COMM_EQU_FUNC" );
+ aIn >> nByte;
+ aString += String::CreateFromInt32( nByte );
+ aIn >> nByte;
+ aStack << aPool.Store( aString );
+ DoMulArgs( ocPush, nByte + 1 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ {
+ sal_uInt16 nXtiIndex, nNameIdx;
+ aIn >> nXtiIndex >> nNameIdx;
+ aIn.Ignore( 2 );
+
+ if( rLinkMan.IsSelfRef( nXtiIndex ) )
+ {
+ // internal defined name with explicit sheet, i.e.: =Sheet1!AnyName
+ const XclImpName* pName = GetNameManager().GetName( nNameIdx );
+ if (pName)
+ {
+ if (pName->GetScRangeData())
+ aStack << aPool.StoreName( nNameIdx, pName->IsGlobal());
+ else
+ aStack << aPool.Store(ocMacro, pName->GetXclName());
+ }
+ }
+ else if( const XclImpExtName* pExtName = rLinkMan.GetExternName( nXtiIndex, nNameIdx ) )
+ {
+ switch( pExtName->GetType() )
+ {
+ case xlExtName:
+ {
+ /* FIXME: enable this code for #i4385# once
+ * external name reference can be stored in ODF,
+ * which remains to be done for #i3740#. Until then
+ * create a #NAME? token. */
+#if 1
+ sal_uInt16 nFileId;
+ if (!GetExternalFileIdFromXti(nXtiIndex, nFileId) || !pExtName->HasFormulaTokens())
+ {
+ aStack << aPool.Store(ocNoName, pExtName->GetName());
+ break;
+ }
+
+ aStack << aPool.StoreExtName(nFileId, pExtName->GetName());
+ pExtName->CreateExtNameData(GetDoc(), nFileId);
+#else
+ aStack << aPool.Store( ocNoName, pExtName->GetName() );
+#endif
+ }
+ break;
+
+ case xlExtAddIn:
+ {
+ aStack << aPool.Store( ocExternal, pExtName->GetName() );
+ }
+ break;
+
+ case xlExtDDE:
+ {
+ String aApplic, aTopic;
+ if( rLinkMan.GetLinkData( aApplic, aTopic, nXtiIndex ) )
+ {
+ TokenId nPar1 = aPool.Store( aApplic );
+ TokenId nPar2 = aPool.Store( aTopic );
+ nMerk0 = aPool.Store( pExtName->GetName() );
+ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
+ << nMerk0 << ocClose;
+ aPool >> aStack;
+ pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
+ }
+ }
+ break;
+
+ case xlExtEuroConvert:
+ {
+ aStack << aPool.Store( ocEuroConvert, String() );
+ }
+ break;
+ case xlExtOLE:
+ {
+ ExternalTabInfo aExtInfo;
+ if (HandleOleLink(nXtiIndex, *pExtName, aExtInfo))
+ {
+ if (aExtInfo.maRange.aStart == aExtInfo.maRange.aEnd)
+ {
+ // single cell
+ aSRD.InitAddress(aExtInfo.maRange.aStart);
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
+ }
+ else
+ {
+ // range
+ aCRD.InitRange(aExtInfo.maRange);
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ }
+ else
+ aStack << aPool.Store(ocNoName, pExtName->GetName());
+ }
+ break;
+ default:
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ }
+ else
+ {
+ //aStack << ocNoName;
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ }
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ {
+ sal_uInt16 nIxti, nRw, nGrbitCol;
+ SCTAB nTabFirst, nTabLast;
+
+ aIn >> nIxti >> nRw >> nGrbitCol;
+
+ ExternalTabInfo aExtInfo;
+ if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ }
+
+ aSRD.nTab = nTabFirst;
+ aSRD.SetFlag3D( sal_True );
+ aSRD.SetTabRel( false );
+
+ ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( sal_True );
+ aSRD.SetRowDeleted( sal_True );
+ }
+
+ if (aExtInfo.mbExternal)
+ {
+ // nTabFirst and nTabLast are the indices of the refernced
+ // sheets in the SUPBOOK record, hence do not represent
+ // the actual indices of the original sheets since the
+ // SUPBOOK record only stores referenced sheets and skips
+ // the ones that are not referenced.
+
+ if (nTabLast != nTabFirst)
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = nTabLast;
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ else
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
+ }
+ else
+ {
+ if ( !ValidTab(nTabFirst))
+ aSRD.SetTabDeleted( sal_True );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = nTabLast;
+ aCRD.Ref2.SetTabDeleted( !ValidTab(nTabLast) );
+ aStack << aPool.Store( aCRD );
+ }
+ else
+ aStack << aPool.Store( aSRD );
+ }
+ }
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ {
+ sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
+ SCTAB nTabFirst, nTabLast;
+ aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
+
+ ExternalTabInfo aExtInfo;
+ if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ }
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+
+ rR1.nTab = nTabFirst;
+ rR2.nTab = nTabLast;
+ rR1.SetFlag3D( sal_True );
+ rR1.SetTabRel( false );
+ rR2.SetFlag3D( nTabFirst != nTabLast );
+ rR2.SetTabRel( false );
+
+ ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRw1, nRw2 ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ // no information which part is deleted, set all
+ rR1.SetColDeleted( sal_True );
+ rR1.SetRowDeleted( sal_True );
+ rR2.SetColDeleted( sal_True );
+ rR2.SetRowDeleted( sal_True );
+ }
+
+ if (aExtInfo.mbExternal)
+ {
+ aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
+ }
+ else
+ {
+ if ( !ValidTab(nTabFirst) )
+ rR1.SetTabDeleted( sal_True );
+ if ( !ValidTab(nTabLast) )
+ rR2.SetTabDeleted( sal_True );
+
+ aStack << aPool.Store( aCRD );
+ }
+ }
+ break;
+ default: bError = sal_True;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( aIn.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else if( bArrayFormula )
+ {
+ rpTokArray = NULL;
+ eRet = ConvOK;
+ }
+ else
+ {
+ rpTokArray = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ aIn.Seek( nEndPos );
+
+ if( eRet == ConvOK)
+ ReadExtensions( aExtensions, aIn );
+
+ return eRet;
+}
+
+
+// stream seeks to first byte after <nFormulaLen>
+ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen,
+ SCsTAB nTab, const FORMULA_TYPE eFT )
+{
+ sal_uInt8 nOp, nLen;//, nByte;
+ sal_Bool bError = false;
+ const sal_Bool bRangeName = eFT == FT_RangeName;
+ const sal_Bool bSharedFormula = eFT == FT_SharedFormula;
+ const sal_Bool bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+
+ bExternName = false;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ return ConvOK;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ aIn.Ignore( 4 );
+ break;
+ case 0x02: // Data Table [325 277]
+ aIn.Ignore( 4 );
+ break;
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen; // und?
+
+ aIn.IgnoreUniString( nLen ); // reads Grbit even if nLen==0
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt16 nData, nFakt;
+ sal_uInt8 nOpt;
+
+ aIn >> nOpt >> nData;
+ nFakt = 2;
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ aIn.Ignore( 1 );
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn.Ignore( 2 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn.Ignore( 8 );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn.Ignore( 7 );
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ aIn.Ignore( 2 );
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ aIn.Ignore( 3 );
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ aIn.Ignore( 4 );
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ {
+ sal_uInt16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nCol = static_cast<SCCOL>(nCol);
+ aSRD.nRow = nRow & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
+
+ rRangeList.Append( aSRD, nTab );
+ }
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ {
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt16 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( sal_True );
+ rSRef2.SetTabRel( sal_True );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( 6 ); // mehr steht da nicht!
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ aIn.Ignore( 2 ); // mehr steht da nicht!
+ break;
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ aIn.Ignore( 3 );
+ break;
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ aIn.Ignore( 6 );
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ sal_uInt16 nRow, nCol;
+
+ aIn >> nRow >> nCol;
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( sal_True );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
+
+ rRangeList.Append( aSRD, nTab );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ sal_uInt16 nRowFirst, nRowLast;
+ sal_uInt16 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( sal_True );
+ aCRD.Ref2.SetTabRel( sal_True );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }
+ break;
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aIn.Ignore( 2 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ aIn.Ignore( 24 );
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ {
+ sal_uInt16 nIxti, nRw, nGrbitCol;
+
+ aIn >> nIxti >> nRw >> nGrbitCol;
+
+ SCTAB nFirstScTab, nLastScTab;
+ if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
+ {
+ aSRD.nTab = nFirstScTab;
+ aSRD.SetFlag3D( sal_True );
+ aSRD.SetTabRel( false );
+
+ ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
+
+ if( nFirstScTab != nLastScTab )
+ {
+ aCRD.Ref1 = aSRD;
+ aCRD.Ref2.nCol = aSRD.nCol;
+ aCRD.Ref2.nRow = aSRD.nRow;
+ aCRD.Ref2.nTab = nLastScTab;
+ rRangeList.Append( aCRD, nTab );
+ }
+ else
+ rRangeList.Append( aSRD, nTab );
+ }
+ }
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ {
+ sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
+
+ aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
+
+ SCTAB nFirstScTab, nLastScTab;
+ if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
+ {
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+ rR1.nTab = nFirstScTab;
+ rR2.nTab = nLastScTab;
+ rR1.SetFlag3D( sal_True );
+ rR1.SetTabRel( false );
+ rR2.SetFlag3D( nFirstScTab != nLastScTab );
+ rR2.SetTabRel( false );
+
+ ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
+ ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRw1, nRw2 ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD, nTab );
+ }
+ }
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ aIn.Ignore( 6 );
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ aIn.Ignore( 10 );
+ break;
+ default:
+ bError = sal_True;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ eRet = ConvErrNi;
+ else if( aIn.GetRecPos() != nEndPos )
+ eRet = ConvErrCount;
+ else if( bExternName )
+ eRet = ConvErrExternal;
+ else
+ eRet = ConvOK;
+
+ aIn.Seek( nEndPos );
+ return eRet;
+}
+
+ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const vector<String>& rTabNames )
+{
+ if( !GetDocShell() )
+ return ConvErrNi;
+
+ String aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
+
+ sal_uInt8 nOp, nByte;
+ bool bError = false;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+
+ if (eStatus != ConvOK)
+ {
+ rStrm.Ignore(nFormulaLen);
+ return eStatus;
+ }
+
+ if (nFormulaLen == 0)
+ {
+ aPool.Store(CREATE_STRING("-/-"));
+ aPool >> aStack;
+ rpArray = aPool[aStack.Get()];
+ return ConvOK;
+ }
+
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
+ sal_uInt16 nTabCount = static_cast< sal_uInt16 >( rTabNames.size() );
+
+ sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
+
+ while( (rStrm.GetRecPos() < nEndPos) && !bError )
+ {
+ rStrm >> nOp;
+
+ // always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp )
+ {
+ case 0x1C: // Error Value
+ {
+ rStrm >> nByte;
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+ aPool >> aStack;
+ }
+ break;
+ case 0x3A:
+ {
+ // cell reference in external range name
+ sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
+ rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
+ if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
+ {
+ bError = true;
+ break;
+ }
+
+ aSRD.nTab = nExtTab1;
+ aSRD.SetFlag3D(true);
+ aSRD.SetTabRel(false);
+ ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ String aTabName = rTabNames[nExtTab1];
+
+ if (nExtTab1 == nExtTab2)
+ {
+ // single cell reference
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
+ }
+ else
+ {
+ // area reference
+ aCRD.Ref2.nTab = nExtTab2;
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
+ }
+ }
+ break;
+ case 0x3B:
+ {
+ // area reference
+ sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
+ rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
+ ScSingleRefData& rR1 = aCRD.Ref1;
+ ScSingleRefData& rR2 = aCRD.Ref2;
+
+ rR1.nTab = nExtTab1;
+ rR1.SetFlag3D(true);
+ rR1.SetTabRel(false);
+ ExcRelToScRel8(nRow1, nGrbitCol1, rR1, true);
+
+ rR2.nTab = nExtTab2;
+ rR2.SetFlag3D(true);
+ rR2.SetTabRel(false);
+ ExcRelToScRel8(nRow2, nGrbitCol2, rR2, true);
+
+ String aTabName = rTabNames[nExtTab1];
+ aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
+ }
+ break;
+ default:
+ bError = true;
+ }
+ bError |= !rStrm.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( rStrm.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else
+ {
+ rpArray = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ rStrm.Seek(nEndPos);
+ return eRet;
+}
+
+void ExcelToSc8::ExcRelToScRel8( sal_uInt16 nRow, sal_uInt16 nC, ScSingleRefData &rSRD, const sal_Bool bName )
+{
+ const sal_Bool bColRel = ( nC & 0x4000 ) != 0;
+ const sal_Bool bRowRel = ( nC & 0x8000 ) != 0;
+ const sal_uInt8 nCol = static_cast<sal_uInt8>(nC);
+
+ rSRD.SetColRel( bColRel );
+ rSRD.SetRowRel( bRowRel );
+
+ if( bName )
+ {
+ // C O L
+ if( bColRel )
+ // rel Col
+ rSRD.nRelCol = static_cast<SCsCOL>(static_cast<sal_Int8>(nC));
+ else
+ // abs Col
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+
+ // R O W
+ if( bRowRel )
+ // rel Row
+ rSRD.nRelRow = static_cast<SCsROW>(static_cast<sal_Int16>(nRow));
+ else
+ // abs Row
+ rSRD.nRow = Min( static_cast<SCROW>(nRow), MAXROW);
+
+ // T A B
+ // abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab();
+ }
+ else
+ {
+ // C O L
+ if ( bColRel )
+ {
+ rSRD.nRelCol = static_cast<SCsCOL>(nCol) - aEingPos.Col();
+ rSRD.nCol = rSRD.nRelCol;
+ }
+ else
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+
+ // R O W
+ if ( bRowRel )
+ {
+ rSRD.nRelRow = static_cast<SCsROW>(nRow) - aEingPos.Row();
+ rSRD.nRow = rSRD.nRelRow;
+ }
+ else
+ rSRD.nRow = static_cast<SCROW>(nRow);
+
+ // T A B
+ // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
+ }
+}
+
+
+// stream seeks to first byte after <nLen>
+sal_Bool ExcelToSc8::GetAbsRefs( ScRangeList& r, XclImpStream& aIn, sal_Size nLen )
+{
+ sal_uInt8 nOp;
+ sal_uInt16 nRow1, nRow2, nCol1, nCol2;
+ SCTAB nTab1, nTab2;
+ sal_uInt16 nIxti;
+
+ sal_Size nSeek;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nLen;
+
+ while( aIn.IsValid() && (aIn.GetRecPos() < nEndPos) )
+ {
+ aIn >> nOp;
+ nSeek = 0;
+
+ switch( nOp )
+ {
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ aIn >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ // Area Reference Within a Shared Formula[ 274]
+ aIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ aIn >> nIxti >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+
+ goto _3d_common;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ aIn >> nIxti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ _3d_common:
+ // skip references to deleted sheets
+ if( !rLinkMan.GetScTabRange( nTab1, nTab2, nIxti ) || !ValidTab( nTab1 ) || !ValidTab( nTab2 ) )
+ break;
+
+ goto _common;
+ _common:
+ // do not check abs/rel flags, linked controls have set them!
+// if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
+ {
+ ScRange aScRange;
+ nCol1 &= 0x3FFF;
+ nCol2 &= 0x3FFF;
+ if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
+ r.Append( aScRange );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nSeek = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nSeek = 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ nSeek = 3;
+ break;
+ case 0x01: // Array Formula [325 ]
+ case 0x02: // Data Table [325 277]
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nSeek = 4;
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nSeek = 6;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nSeek = 7;
+ break;
+ case 0x1F: // Number [315 266]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nSeek = 8;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nSeek = 10;
+ break;
+ case 0x17: // String Constant [314 266]
+ {
+ sal_uInt8 nStrLen;
+ aIn >> nStrLen;
+ aIn.IgnoreUniString( nStrLen ); // reads Grbit even if nLen==0
+ nSeek = 0;
+ }
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ sal_uInt16 nData;
+ sal_uInt8 nOpt;
+ aIn >> nOpt >> nData;
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ nSeek = nData * 2;
+ }
+ }
+ break;
+ }
+
+ aIn.Ignore( nSeek );
+ }
+ aIn.Seek( nEndPos );
+
+ return !r.empty();
+}
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
new file mode 100644
index 000000000000..a1bbe57dbc0c
--- /dev/null
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -0,0 +1,859 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "excimp8.hxx"
+
+#include <scitems.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <unotools/fltrcfg.hxx>
+
+#include <svtools/wmf.hxx>
+
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docinf.hxx>
+#include <sfx2/frame.hxx>
+
+#include <editeng/brshitem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/xflclit.hxx>
+
+#include <vcl/graph.hxx>
+#include <vcl/bmpacc.hxx>
+#include <sot/exchange.hxx>
+
+#include <svl/stritem.hxx>
+
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/math.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/charclass.hxx>
+#include <drwlayer.hxx>
+
+#include <boost/scoped_array.hpp>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "conditio.hxx"
+#include "dbcolect.hxx"
+#include "globalnames.hxx"
+#include "editutil.hxx"
+#include "markdata.hxx"
+#include "rangenam.hxx"
+#include "docoptio.hxx"
+#include "globstr.hrc"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xicontent.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+
+#include "excform.hxx"
+#include "scextopt.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "detfunc.hxx"
+#include "macromgr.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include <cppuhelper/component_context.hxx>
+#include <sfx2/app.hxx>
+#include "xltoolbar.hxx"
+
+
+using namespace com::sun::star;
+using namespace ::comphelper;
+using ::rtl::OUString;
+
+//OleNameOverrideContainer
+
+typedef ::cppu::WeakImplHelper1< container::XNameContainer > OleNameOverrideContainer_BASE;
+
+class OleNameOverrideContainer : public OleNameOverrideContainer_BASE
+{
+private:
+ typedef boost::unordered_map< rtl::OUString, uno::Reference< container::XIndexContainer >, ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > NamedIndexToOleName;
+ NamedIndexToOleName IdToOleNameHash;
+ ::osl::Mutex m_aMutex;
+public:
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { return container::XIndexContainer::static_type(0); }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return ( IdToOleNameHash.size() > 0 );
+ }
+ // XNameAcess
+ virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ return uno::makeAny( IdToOleNameHash[ aName ] );
+ }
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ uno::Sequence< ::rtl::OUString > aResult( IdToOleNameHash.size() );
+ NamedIndexToOleName::iterator it = IdToOleNameHash.begin();
+ NamedIndexToOleName::iterator it_end = IdToOleNameHash.end();
+ rtl::OUString* pName = aResult.getArray();
+ for (; it != it_end; ++it, ++pName )
+ *pName = it->first;
+ return aResult;
+ }
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return ( IdToOleNameHash.find( aName ) != IdToOleNameHash.end() );
+ }
+
+ // XElementAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return IdToOleNameHash.size();
+ }
+ // XNameContainer
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( hasByName( aName ) )
+ throw container::ElementExistException();
+ uno::Reference< container::XIndexContainer > xElement;
+ if ( ! ( aElement >>= xElement ) )
+ throw lang::IllegalArgumentException();
+ IdToOleNameHash[ aName ] = xElement;
+ }
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& aName ) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ IdToOleNameHash.erase( IdToOleNameHash.find( aName ) );
+ }
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement ) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ uno::Reference< container::XIndexContainer > xElement;
+ if ( ! ( aElement >>= xElement ) )
+ throw lang::IllegalArgumentException();
+ IdToOleNameHash[ aName ] = xElement;
+ }
+};
+
+// defined in docfunc.cxx ( really this needs a new name )
+script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule );
+
+ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) :
+ ImportExcel( rImpData, rStrm )
+{
+ // replace BIFF2-BIFF5 formula importer with BIFF8 formula importer
+ delete pFormConv;
+ pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() );
+}
+
+
+ImportExcel8::~ImportExcel8()
+{
+}
+
+
+void ImportExcel8::Calccount( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIterCount( aIn.ReaduInt16() );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Precision( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetCalcAsShown( aIn.ReaduInt16() == 0 );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Delta( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIterEps( aIn.ReadDouble() );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Iteration( void )
+{
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetIter( aIn.ReaduInt16() == 1 );
+ pD->SetDocOptions( aOpt );
+}
+
+
+void ImportExcel8::Boundsheet( void )
+{
+ sal_uInt8 nLen;
+ sal_uInt16 nGrbit;
+
+ aIn.DisableDecryption();
+ maSheetOffsets.push_back( aIn.ReaduInt32() );
+ aIn.EnableDecryption();
+ aIn >> nGrbit >> nLen;
+
+ String aName( aIn.ReadUniString( nLen ) );
+ GetTabInfo().AppendXclTabName( aName, nBdshtTab );
+
+ SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
+ if( nScTab > 0 )
+ {
+ DBG_ASSERT( !pD->HasTable( nScTab ), "ImportExcel8::Boundsheet - sheet exists already" );
+ pD->MakeTable( nScTab );
+ }
+
+ if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
+ pD->SetVisible( nScTab, false );
+
+ if( !pD->RenameTab( nScTab, aName ) )
+ {
+ pD->CreateValidTabName( aName );
+ pD->RenameTab( nScTab, aName );
+ }
+
+ nBdshtTab++;
+}
+
+
+void ImportExcel8::Scenman( void )
+{
+ sal_uInt16 nLastDispl;
+
+ aIn.Ignore( 4 );
+ aIn >> nLastDispl;
+
+ aScenList.nLastScenario = nLastDispl;
+}
+
+
+void ImportExcel8::Scenario( void )
+{
+ aScenList.aEntries.push_back( new ExcScenario( aIn, *pExcRoot ) );
+}
+
+
+void ImportExcel8::Labelsst( void )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXF;
+ sal_uInt32 nSst;
+
+ aIn >> aXclPos >> nXF >> nSst;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ if( ScBaseCell* pCell = GetSst().CreateCell( nSst, nXF ) )
+ GetDoc().PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pCell );
+ }
+}
+
+
+void ImportExcel8::SheetProtection( void )
+{
+ GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
+}
+
+void ImportExcel8::ReadBasic( void )
+{
+ SfxObjectShell* pShell = GetDocShell();
+ SotStorageRef xRootStrg = GetRootStorage();
+ SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get();
+ if( pShell && xRootStrg.Is() ) try
+ {
+ bool bLoadCode = pFilterOpt->IsLoadExcelBasicCode();
+ bool bLoadExecutable = pFilterOpt->IsLoadExcelBasicExecutable();
+ bool bLoadStrg = pFilterOpt->IsLoadExcelBasicStorage();
+ // #FIXME need to get rid of this, we can also do this from within oox
+ // via the "ooo.vba.VBAGlobals" service
+ if( bLoadCode || bLoadStrg )
+ {
+ bool bAsComment = !bLoadExecutable;
+
+ if ( !bAsComment )
+ {
+ // see if we have the XCB stream
+ SvStorageStreamRef xXCB = xRootStrg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "XCB" ) ), STREAM_STD_READ | STREAM_NOCREATE );
+ if ( xXCB.Is()|| SVSTREAM_OK == xXCB->GetError() )
+ {
+ CTBWrapper wrapper;
+ if ( wrapper.Read( xXCB ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ wrapper.Print( stderr );
+#endif
+ wrapper.ImportCustomToolBar( *pShell );
+ }
+ }
+ }
+ }
+ try
+ {
+ uno::Reference< lang::XComponent > xComponent( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::NamedValue > aArgSeq( 1 );
+
+ // collect names of embedded form controls, as specified in the VBA project
+ aArgSeq[ 0 ].Name = CREATE_OUSTRING( "OleNameOverrideInfo" );
+ uno::Reference< container::XNameContainer > xOleNameOverrideSink( new OleNameOverrideContainer );
+ aArgSeq[ 0 ].Value <<= xOleNameOverrideSink;
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ // framework calls filter objects with factory as first argument
+ aArgs[ 0 ] <<= getProcessServiceFactory();
+ aArgs[ 1 ] <<= aArgSeq;
+
+ uno::Reference< document::XImporter > xImporter( ScfApiHelper::CreateInstanceWithArgs( CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelVbaProjectFilter" ), aArgs ), uno::UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComponent );
+
+ MediaDescriptor aMediaDesc;
+ SfxMedium& rMedium = GetMedium();
+ SfxItemSet* pItemSet = rMedium.GetItemSet();
+ if( pItemSet )
+ {
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
+ aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem->GetValue() );
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_PASSWORD ) ) )
+ aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pItem->GetValue() );
+ }
+ aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream();
+ aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler();
+
+ // call the filter
+ uno::Reference< document::XFilter > xFilter( xImporter, uno::UNO_QUERY_THROW );
+ xFilter->filter( aMediaDesc.getAsConstPropertyValueList() );
+ GetObjectManager().SetOleNameOverrideInfo( xOleNameOverrideSink );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+
+void ImportExcel8::EndSheet( void )
+{
+ ImportExcel::EndSheet();
+ GetCondFormatManager().Apply();
+ GetValidationManager().Apply();
+}
+
+
+void ImportExcel8::PostDocLoad( void )
+{
+ // reading basic has been delayed until sheet objects (codenames etc.) are read
+ if( HasBasic() )
+ ReadBasic();
+ // #i11776# filtered ranges before outlines and hidden rows
+ if( pExcRoot->pAutoFilterBuffer )
+ pExcRoot->pAutoFilterBuffer->Apply();
+
+ GetWebQueryBuffer().Apply(); //! test if extant
+ GetSheetProtectBuffer().Apply();
+ GetDocProtectBuffer().Apply();
+
+ ImportExcel::PostDocLoad();
+
+ // Scenarien bemachen! ACHTUNG: Hier wird Tabellen-Anzahl im Dokument erhoeht!!
+ if( !pD->IsClipboard() && aScenList.aEntries.size() )
+ {
+ pD->UpdateChartListenerCollection(); // references in charts must be updated
+
+ aScenList.Apply( GetRoot() );
+ }
+
+ // read doc info (no docshell while pasting from clipboard)
+ LoadDocumentProperties();
+
+ // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available
+ // when formula cells are calculated, for the GETPIVOTDATA function.
+}
+
+void ImportExcel8::LoadDocumentProperties()
+{
+ // no docshell while pasting from clipboard
+ if( SfxObjectShell* pShell = GetDocShell() )
+ {
+ // BIFF5+ without storage is possible
+ SotStorageRef xRootStrg = GetRootStorage();
+ if( xRootStrg.Is() ) try
+ {
+ uno::Reference< document::XDocumentPropertiesSupplier > xDPS( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XDocumentProperties > xDocProps( xDPS->getDocumentProperties(), uno::UNO_SET_THROW );
+ sfx2::LoadOlePropertySet( xDocProps, xRootStrg );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+//___________________________________________________________________
+// autofilter
+
+void ImportExcel8::FilterMode( void )
+{
+ // The FilterMode record exists: if either the AutoFilter
+ // record exists or an Advanced Filter is saved and stored
+ // in the sheet. Thus if the FilterMode records only exists
+ // then the latter is true..
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ pData->SetAutoOrAdvanced();
+}
+
+void ImportExcel8::AutoFilterInfo( void )
+{
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ {
+ pData->SetAdvancedRange( NULL );
+ pData->Activate();
+ }
+}
+
+void ImportExcel8::AutoFilter( void )
+{
+ if( !pExcRoot->pAutoFilterBuffer ) return;
+
+ XclImpAutoFilterData* pData = pExcRoot->pAutoFilterBuffer->GetByTab( GetCurrScTab() );
+ if( pData )
+ pData->ReadAutoFilter( aIn );
+}
+
+
+
+XclImpAutoFilterData::XclImpAutoFilterData( RootData* pRoot, const ScRange& rRange ) :
+ ExcRoot( pRoot ),
+ pCurrDBData(NULL),
+ nFirstEmpty( 0 ),
+ bActive( false ),
+ bHasConflict( false ),
+ bCriteria( false ),
+ bAutoOrAdvanced(false)
+{
+ aParam.nCol1 = rRange.aStart.Col();
+ aParam.nRow1 = rRange.aStart.Row();
+ aParam.nTab = rRange.aStart.Tab();
+ aParam.nCol2 = rRange.aEnd.Col();
+ aParam.nRow2 = rRange.aEnd.Row();
+
+ aParam.bInplace = sal_True;
+
+}
+
+void XclImpAutoFilterData::CreateFromDouble( String& rStr, double fVal )
+{
+ rStr += String( ::rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), sal_True));
+}
+
+void XclImpAutoFilterData::SetCellAttribs()
+{
+ ScDocument& rDoc = pExcRoot->pIR->GetDoc();
+ for ( SCCOL nCol = StartCol(); nCol <= EndCol(); nCol++ )
+ {
+ sal_Int16 nFlag = ((ScMergeFlagAttr*) rDoc.GetAttr( nCol, StartRow(), Tab(), ATTR_MERGE_FLAG ))->GetValue();
+ rDoc.ApplyAttr( nCol, StartRow(), Tab(), ScMergeFlagAttr( nFlag | SC_MF_AUTO) );
+ }
+}
+
+void XclImpAutoFilterData::InsertQueryParam()
+{
+ if( pCurrDBData && !bHasConflict )
+ {
+ ScRange aAdvRange;
+ sal_Bool bHasAdv = pCurrDBData->GetAdvancedQuerySource( aAdvRange );
+ if( bHasAdv )
+ pExcRoot->pIR->GetDoc().CreateQueryParam( aAdvRange.aStart.Col(),
+ aAdvRange.aStart.Row(), aAdvRange.aEnd.Col(), aAdvRange.aEnd.Row(),
+ aAdvRange.aStart.Tab(), aParam );
+
+ pCurrDBData->SetQueryParam( aParam );
+ if( bHasAdv )
+ pCurrDBData->SetAdvancedQuerySource( &aAdvRange );
+ else
+ {
+ pCurrDBData->SetAutoFilter( sal_True );
+ SetCellAttribs();
+ }
+ }
+}
+
+static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
+{
+ if( ( rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL ) || rEntry.pStr == NULL )
+ return;
+ else
+ {
+ xub_StrLen nLen = rEntry.pStr->Len();
+ sal_Unicode nStart = rEntry.pStr->GetChar( 0 );
+ sal_Unicode nEnd = rEntry.pStr->GetChar( nLen-1 );
+ if( nLen >2 && nStart == '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( nLen-1, 1 );
+ rEntry.pStr->Erase( 0, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_CONTAINS : SC_DOES_NOT_CONTAIN;
+ }
+ else if( nLen > 1 && nStart == '*' && nEnd != '*' )
+ {
+ rEntry.pStr->Erase( 0, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_ENDS_WITH : SC_DOES_NOT_END_WITH;
+ }
+ else if( nLen > 1 && nStart != '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( nLen-1, 1 );
+ rEntry.eOp = ( rEntry.eOp == SC_EQUAL ) ? SC_BEGINS_WITH : SC_DOES_NOT_BEGIN_WITH;
+ }
+ else if( nLen == 2 && nStart == '*' && nEnd == '*' )
+ {
+ rEntry.pStr->Erase( 0, 1 );
+ }
+ }
+}
+
+void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
+{
+ sal_uInt16 nCol, nFlags;
+ rStrm >> nCol >> nFlags;
+
+ ScQueryConnect eConn = ::get_flagvalue( nFlags, EXC_AFFLAG_ANDORMASK, SC_OR, SC_AND );
+ sal_Bool bTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10 );
+ sal_Bool bTopOfTop10 = ::get_flag( nFlags, EXC_AFFLAG_TOP10TOP );
+ sal_Bool bPercent = ::get_flag( nFlags, EXC_AFFLAG_TOP10PERC );
+ sal_uInt16 nCntOfTop10 = nFlags >> 7;
+ SCSIZE nCount = aParam.GetEntryCount();
+
+ if( bTop10 )
+ {
+ if( nFirstEmpty < nCount )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ aEntry.bDoQuery = sal_True;
+ aEntry.bQueryByString = sal_True;
+ aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
+ aEntry.eOp = bTopOfTop10 ?
+ (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
+ aEntry.eConnect = SC_AND;
+ aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nCntOfTop10 ) );
+
+ rStrm.Ignore( 20 );
+ nFirstEmpty++;
+ }
+ }
+ else
+ {
+ sal_uInt8 nE, nType, nOper, nBoolErr, nVal;
+ sal_Int32 nRK;
+ double fVal;
+ sal_Bool bIgnore;
+
+ sal_uInt8 nStrLen[ 2 ] = { 0, 0 };
+ ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
+
+ for( nE = 0; nE < 2; nE++ )
+ {
+ if( nFirstEmpty < nCount )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ pQueryEntries[ nE ] = &aEntry;
+ bIgnore = false;
+
+ rStrm >> nType >> nOper;
+ switch( nOper )
+ {
+ case EXC_AFOPER_LESS:
+ aEntry.eOp = SC_LESS;
+ break;
+ case EXC_AFOPER_EQUAL:
+ aEntry.eOp = SC_EQUAL;
+ break;
+ case EXC_AFOPER_LESSEQUAL:
+ aEntry.eOp = SC_LESS_EQUAL;
+ break;
+ case EXC_AFOPER_GREATER:
+ aEntry.eOp = SC_GREATER;
+ break;
+ case EXC_AFOPER_NOTEQUAL:
+ aEntry.eOp = SC_NOT_EQUAL;
+ break;
+ case EXC_AFOPER_GREATEREQUAL:
+ aEntry.eOp = SC_GREATER_EQUAL;
+ break;
+ default:
+ aEntry.eOp = SC_EQUAL;
+ }
+
+ switch( nType )
+ {
+ case EXC_AFTYPE_RK:
+ rStrm >> nRK;
+ rStrm.Ignore( 4 );
+ CreateFromDouble( *aEntry.pStr, XclTools::GetDoubleFromRK( nRK ) );
+ break;
+ case EXC_AFTYPE_DOUBLE:
+ rStrm >> fVal;
+ CreateFromDouble( *aEntry.pStr, fVal );
+ break;
+ case EXC_AFTYPE_STRING:
+ rStrm.Ignore( 4 );
+ rStrm >> nStrLen[ nE ];
+ rStrm.Ignore( 3 );
+ aEntry.pStr->Erase();
+ break;
+ case EXC_AFTYPE_BOOLERR:
+ rStrm >> nBoolErr >> nVal;
+ rStrm.Ignore( 6 );
+ aEntry.pStr->Assign( String::CreateFromInt32( (sal_Int32) nVal ) );
+ bIgnore = (sal_Bool) nBoolErr;
+ break;
+ case EXC_AFTYPE_EMPTY:
+ aEntry.bQueryByString = false;
+ aEntry.nVal = SC_EMPTYFIELDS;
+ aEntry.eOp = SC_EQUAL;
+ break;
+ case EXC_AFTYPE_NOTEMPTY:
+ aEntry.bQueryByString = false;
+ aEntry.nVal = SC_NONEMPTYFIELDS;
+ aEntry.eOp = SC_EQUAL;
+ break;
+ default:
+ rStrm.Ignore( 8 );
+ bIgnore = sal_True;
+ }
+
+ /* #i39464# conflict, if two conditions of one column are 'OR'ed,
+ and they follow conditions of other columns.
+ Example: Let A1 be a condition of column A, and B1 and B2
+ conditions of column B, connected with OR. Excel performs
+ 'A1 AND (B1 OR B2)' in this case, but Calc would do
+ '(A1 AND B1) OR B2' instead. */
+ if( (nFirstEmpty > 1) && nE && (eConn == SC_OR) && !bIgnore )
+ bHasConflict = sal_True;
+ if( !bHasConflict && !bIgnore )
+ {
+ aEntry.bDoQuery = sal_True;
+ aEntry.bQueryByString = sal_True;
+ aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
+ aEntry.eConnect = nE ? eConn : SC_AND;
+ nFirstEmpty++;
+ }
+ }
+ else
+ rStrm.Ignore( 10 );
+ }
+
+ for( nE = 0; nE < 2; nE++ )
+ if( nStrLen[ nE ] && pQueryEntries[ nE ] )
+ {
+ pQueryEntries[ nE ]->pStr->Assign ( rStrm.ReadUniString( nStrLen[ nE ] ) );
+ ExcelQueryToOooQuery( *pQueryEntries[ nE ] );
+ }
+
+ }
+}
+
+void XclImpAutoFilterData::SetAdvancedRange( const ScRange* pRange )
+{
+ if (pRange)
+ {
+ aCriteriaRange = *pRange;
+ bCriteria = sal_True;
+ }
+ else
+ bCriteria = false;
+}
+
+void XclImpAutoFilterData::SetExtractPos( const ScAddress& rAddr )
+{
+ aParam.nDestCol = rAddr.Col();
+ aParam.nDestRow = rAddr.Row();
+ aParam.nDestTab = rAddr.Tab();
+ aParam.bInplace = false;
+ aParam.bDestPers = sal_True;
+}
+
+void XclImpAutoFilterData::Apply()
+{
+ CreateScDBData();
+
+ if( bActive )
+ {
+ InsertQueryParam();
+
+ // #i38093# rows hidden by filter need extra flag, but CR_FILTERED is not set here yet
+// SCROW nRow1 = StartRow();
+// SCROW nRow2 = EndRow();
+// size_t nRows = nRow2 - nRow1 + 1;
+// boost::scoped_array<sal_uInt8> pFlags( new sal_uInt8[nRows]);
+// pExcRoot->pDoc->GetRowFlagsArray( Tab()).FillDataArray( nRow1, nRow2,
+// pFlags.get());
+// for (size_t j=0; j<nRows; ++j)
+// {
+// if ((pFlags[j] & CR_HIDDEN) && !(pFlags[j] & CR_FILTERED))
+// pExcRoot->pDoc->SetRowFlags( nRow1 + j, Tab(),
+// pFlags[j] | CR_FILTERED );
+// }
+ }
+}
+
+void XclImpAutoFilterData::CreateScDBData()
+{
+
+ // Create the ScDBData() object if the AutoFilter is activated
+ // or if we need to create the Advanced Filter.
+ if( bActive || bCriteria)
+ {
+ ScDocument* pDoc = pExcRoot->pIR->GetDocPtr();
+ String aNewName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
+ pCurrDBData = new ScDBData(aNewName , Tab(),
+ StartCol(),StartRow(), EndCol(),EndRow() );
+ if(bCriteria)
+ {
+ EnableRemoveFilter();
+
+ pCurrDBData->SetQueryParam( aParam );
+ pCurrDBData->SetAdvancedQuerySource(&aCriteriaRange);
+ }
+ else
+ pCurrDBData->SetAdvancedQuerySource(NULL);
+ pDoc->SetAnonymousDBData(Tab(), pCurrDBData);
+ }
+
+}
+
+void XclImpAutoFilterData::EnableRemoveFilter()
+{
+ // only if this is a saved Advanced filter
+ if( !bActive && bAutoOrAdvanced )
+ {
+ ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+ aEntry.bDoQuery = sal_True;
+ ++nFirstEmpty;
+ }
+
+ // TBD: force the automatic activation of the
+ // "Remove Filter" by setting a virtual mouse click
+ // inside the advanced range
+}
+
+XclImpAutoFilterBuffer::XclImpAutoFilterBuffer()
+{
+}
+
+XclImpAutoFilterBuffer::~XclImpAutoFilterBuffer()
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ delete pData;
+}
+
+void XclImpAutoFilterBuffer::Insert( RootData* pRoot, const ScRange& rRange)
+{
+ if( !GetByTab( rRange.aStart.Tab() ) )
+ Append( new XclImpAutoFilterData( pRoot, rRange) );
+}
+
+void XclImpAutoFilterBuffer::AddAdvancedRange( const ScRange& rRange )
+{
+ XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
+ if( pData )
+ pData->SetAdvancedRange( &rRange );
+}
+
+void XclImpAutoFilterBuffer::AddExtractPos( const ScRange& rRange )
+{
+ XclImpAutoFilterData* pData = GetByTab( rRange.aStart.Tab() );
+ if( pData )
+ pData->SetExtractPos( rRange.aStart );
+}
+
+void XclImpAutoFilterBuffer::Apply()
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ pData->Apply();
+}
+
+XclImpAutoFilterData* XclImpAutoFilterBuffer::GetByTab( SCTAB nTab )
+{
+ for( XclImpAutoFilterData* pData = _First(); pData; pData = _Next() )
+ if( pData->Tab() == nTab )
+ return pData;
+ return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
new file mode 100644
index 000000000000..d3671b4d1cbe
--- /dev/null
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -0,0 +1,1060 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "excrecds.hxx"
+
+#include <map>
+#include <filter/msfilter/countryid.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/objsh.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+
+#include <editeng/flditem.hxx>
+#include <editeng/flstitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svtools/ctrltool.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+
+#include <string.h>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "progress.hxx"
+#include "dociter.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "editutil.hxx"
+#include "formula/errorcodes.hxx"
+
+#include "excdoc.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xecontent.hxx"
+
+#include "xcl97rec.hxx"
+
+using namespace ::oox;
+
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OString;
+
+//--------------------------------------------------------- class ExcDummy_00 -
+const sal_uInt8 ExcDummy_00::pMyData[] = {
+ 0x5c, 0x00, 0x20, 0x00, 0x04, 'C', 'a', 'l', 'c', // WRITEACCESS
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData );
+
+//-------------------------------------------------------- class ExcDummy_04x -
+const sal_uInt8 ExcDummy_040::pMyData[] = {
+ 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, // BACKUP
+ 0x8d, 0x00, 0x02, 0x00, 0x00, 0x00, // HIDEOBJ
+};
+const sal_Size ExcDummy_040::nMyLen = sizeof( ExcDummy_040::pMyData );
+
+const sal_uInt8 ExcDummy_041::pMyData[] = {
+ 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, // PRECISION
+ 0xda, 0x00, 0x02, 0x00, 0x00, 0x00 // BOOKBOOL
+};
+const sal_Size ExcDummy_041::nMyLen = sizeof( ExcDummy_041::pMyData );
+
+//-------------------------------------------------------- class ExcDummy_02a -
+const sal_uInt8 ExcDummy_02a::pMyData[] = {
+ 0x0d, 0x00, 0x02, 0x00, 0x01, 0x00, // CALCMODE
+ 0x0c, 0x00, 0x02, 0x00, 0x64, 0x00, // CALCCOUNT
+ 0x0f, 0x00, 0x02, 0x00, 0x01, 0x00, // REFMODE
+ 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, // ITERATION
+ 0x10, 0x00, 0x08, 0x00, 0xfc, 0xa9, 0xf1, 0xd2, 0x4d, // DELTA
+ 0x62, 0x50, 0x3f,
+ 0x5f, 0x00, 0x02, 0x00, 0x01, 0x00 // SAVERECALC
+};
+const sal_Size ExcDummy_02a::nMyLen = sizeof( ExcDummy_02a::pMyData );
+
+//----------------------------------------------------------- class ExcRecord -
+
+void ExcRecord::Save( XclExpStream& rStrm )
+{
+ SetRecHeader( GetNum(), GetLen() );
+ XclExpRecord::Save( rStrm );
+}
+
+void ExcRecord::SaveCont( XclExpStream& /*rStrm*/ )
+{
+}
+
+void ExcRecord::WriteBody( XclExpStream& rStrm )
+{
+ SaveCont( rStrm );
+}
+
+void ExcRecord::SaveXml( XclExpXmlStream& /*rStrm*/ )
+{
+}
+
+
+//--------------------------------------------------------- class ExcEmptyRec -
+
+void ExcEmptyRec::Save( XclExpStream& /*rStrm*/ )
+{
+}
+
+
+sal_uInt16 ExcEmptyRec::GetNum() const
+{
+ return 0;
+}
+
+
+sal_Size ExcEmptyRec::GetLen() const
+{
+ return 0;
+}
+
+
+
+//------------------------------------------------------- class ExcRecordList -
+
+ExcRecordList::~ExcRecordList()
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ delete pRec;
+}
+
+
+void ExcRecordList::Save( XclExpStream& rStrm )
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ pRec->Save( rStrm );
+}
+
+
+
+//--------------------------------------------------------- class ExcDummyRec -
+
+void ExcDummyRec::Save( XclExpStream& rStrm )
+{
+ rStrm.Write( GetData(), GetLen() ); // raw write mode
+}
+
+
+sal_uInt16 ExcDummyRec::GetNum( void ) const
+{
+ return 0x0000;
+}
+
+
+
+//------------------------------------------------------- class ExcBoolRecord -
+
+void ExcBoolRecord::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16)(bVal ? 0x0001 : 0x0000);
+}
+
+
+sal_Size ExcBoolRecord::GetLen( void ) const
+{
+ return 2;
+}
+
+
+
+
+//--------------------------------------------------------- class ExcBof_Base -
+
+ExcBof_Base::ExcBof_Base() :
+ nRupBuild( 0x096C ), // copied from Excel
+ nRupYear( 0x07C9 ) // copied from Excel
+{
+}
+
+
+
+//-------------------------------------------------------------- class ExcBof -
+
+ExcBof::ExcBof( void )
+{
+ nDocType = 0x0010;
+ nVers = 0x0500;
+}
+
+
+void ExcBof::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nVers << nDocType << nRupBuild << nRupYear;
+}
+
+
+sal_uInt16 ExcBof::GetNum( void ) const
+{
+ return 0x0809;
+}
+
+
+sal_Size ExcBof::GetLen( void ) const
+{
+ return 8;
+}
+
+
+
+//------------------------------------------------------------- class ExcBofW -
+
+ExcBofW::ExcBofW( void )
+{
+ nDocType = 0x0005;
+ nVers = 0x0500;
+}
+
+
+void ExcBofW::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nVers << nDocType << nRupBuild << nRupYear;
+}
+
+
+
+sal_uInt16 ExcBofW::GetNum( void ) const
+{
+ return 0x0809;
+}
+
+
+
+sal_Size ExcBofW::GetLen( void ) const
+{
+ return 8;
+}
+
+
+
+//-------------------------------------------------------------- class ExcEof -
+
+sal_uInt16 ExcEof::GetNum( void ) const
+{
+ return 0x000A;
+}
+
+
+sal_Size ExcEof::GetLen( void ) const
+{
+ return 0;
+}
+
+
+
+//--------------------------------------------------------- class ExcDummy_00 -
+
+sal_Size ExcDummy_00::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy_00::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+//-------------------------------------------------------- class ExcDummy_04x -
+
+sal_Size ExcDummy_040::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy_040::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+
+sal_Size ExcDummy_041::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy_041::GetData( void ) const
+{
+ return pMyData;
+}
+
+
+
+//------------------------------------------------------------- class Exc1904 -
+
+Exc1904::Exc1904( ScDocument& rDoc )
+{
+ Date* pDate = rDoc.GetFormatTable()->GetNullDate();
+ bVal = pDate ? (*pDate == Date( 1, 1, 1904 )) : false;
+ bDateCompatibility = pDate ? !( *pDate == Date( 30, 12, 1899 )) : false;
+}
+
+
+sal_uInt16 Exc1904::GetNum( void ) const
+{
+ return 0x0022;
+}
+
+
+void Exc1904::SaveXml( XclExpXmlStream& rStrm )
+{
+ bool bISOIEC = ( rStrm.getVersion() == oox::core::ISOIEC_29500_2008 );
+
+ if( bISOIEC )
+ {
+ rStrm.WriteAttributes(
+ XML_dateCompatibility, XclXmlUtils::ToPsz( bDateCompatibility ),
+ FSEND );
+ }
+
+ if( !bISOIEC || bDateCompatibility )
+ {
+ rStrm.WriteAttributes(
+ XML_date1904, XclXmlUtils::ToPsz( bVal ),
+ FSEND );
+ }
+}
+
+
+
+//------------------------------------------------------ class ExcBundlesheet -
+
+ExcBundlesheetBase::ExcBundlesheetBase( RootData& rRootData, SCTAB nTabNum ) :
+ nStrPos( STREAM_SEEK_TO_END ),
+ nOwnPos( STREAM_SEEK_TO_END ),
+ nGrbit( rRootData.pER->GetTabInfo().IsVisibleTab( nTabNum ) ? 0x0000 : 0x0001 ),
+ nTab( nTabNum )
+{
+}
+
+
+ExcBundlesheetBase::ExcBundlesheetBase() :
+ nStrPos( STREAM_SEEK_TO_END ),
+ nOwnPos( STREAM_SEEK_TO_END ),
+ nGrbit( 0x0000 ),
+ nTab( SCTAB_GLOBAL )
+{
+}
+
+
+void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
+{
+ rStrm.SetSvStreamPos( nOwnPos );
+ rStrm.DisableEncryption();
+ rStrm << static_cast<sal_uInt32>(nStrPos);
+ rStrm.EnableEncryption();
+}
+
+
+sal_uInt16 ExcBundlesheetBase::GetNum( void ) const
+{
+ return 0x0085;
+}
+
+
+
+
+ExcBundlesheet::ExcBundlesheet( RootData& rRootData, SCTAB _nTab ) :
+ ExcBundlesheetBase( rRootData, _nTab )
+{
+ String sTabName = rRootData.pER->GetTabInfo().GetScTabName( _nTab );
+ DBG_ASSERT( sTabName.Len() < 256, "ExcBundlesheet::ExcBundlesheet - table name too long" );
+ aName = ByteString( sTabName, rRootData.pER->GetTextEncoding() );
+}
+
+
+void ExcBundlesheet::SaveCont( XclExpStream& rStrm )
+{
+ nOwnPos = rStrm.GetSvStreamPos();
+ rStrm << (sal_uInt32) 0x00000000 // dummy (stream position of the sheet)
+ << nGrbit;
+ rStrm.WriteByteString( aName ); // 8 bit length, max 255 chars
+}
+
+
+sal_Size ExcBundlesheet::GetLen() const
+{
+ return 7 + Min( aName.Len(), (xub_StrLen) 255 );
+}
+
+
+//--------------------------------------------------------- class ExcDummy_02 -
+
+sal_Size ExcDummy_02a::GetLen( void ) const
+{
+ return nMyLen;
+}
+
+const sal_uInt8* ExcDummy_02a::GetData( void ) const
+{
+ return pMyData;
+}
+//--------------------------------------------------------- class ExcDummy_02 -
+
+XclExpCountry::XclExpCountry( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_COUNTRY, 4 )
+{
+ /* #i31530# set document country as UI country too -
+ needed for correct behaviour of number formats. */
+ mnUICountry = mnDocCountry = static_cast< sal_uInt16 >(
+ ::msfilter::ConvertLanguageToCountry( rRoot.GetDocLanguage() ) );
+}
+
+void XclExpCountry::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnUICountry << mnDocCountry;
+}
+
+// XclExpWsbool ===============================================================
+
+XclExpWsbool::XclExpWsbool( bool bFitToPages, SCTAB nScTab, XclExpFilterManager* pManager )
+ : XclExpUInt16Record( EXC_ID_WSBOOL, EXC_WSBOOL_DEFAULTFLAGS )
+ , mnScTab( nScTab )
+ , mpManager( pManager )
+{
+ if( bFitToPages )
+ SetValue( GetValue() | EXC_WSBOOL_FITTOPAGE );
+}
+
+void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetPr,
+ // OOXTODO: XML_syncHorizontal,
+ // OOXTODO: XML_syncVertical,
+ // OOXTODO: XML_syncRef,
+ // OOXTODO: XML_transitionEvaluation,
+ // OOXTODO: XML_transitionEntry,
+ // OOXTODO: XML_published,
+ // OOXTODO: XML_codeName,
+ XML_filterMode, mpManager ? XclXmlUtils::ToPsz( mpManager->HasFilterMode( mnScTab ) ) : NULL,
+ // OOXTODO: XML_enableFormatConditionsCalculation,
+ FSEND );
+ // OOXTODO: elements XML_tabColor, XML_outlinePr
+ rWorksheet->singleElement( XML_pageSetUpPr,
+ // OOXTODO: XML_autoPageBreaks,
+ XML_fitToPage, XclXmlUtils::ToPsz( GetValue() & EXC_WSBOOL_FITTOPAGE ),
+ FSEND );
+ rWorksheet->endElement( XML_sheetPr );
+}
+
+
+// XclExpWindowProtection ===============================================================
+
+XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
+ XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
+{
+}
+
+void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_lockWindows, XclXmlUtils::ToPsz( GetBool() ),
+ FSEND );
+}
+
+// XclExpDocProtection ===============================================================
+
+XclExpProtection::XclExpProtection(bool bValue) :
+ XclExpBoolRecord(EXC_ID_PROTECT, bValue)
+{
+}
+
+// ============================================================================
+
+XclExpPassHash::XclExpPassHash(const Sequence<sal_Int8>& aHash) :
+ XclExpRecord(EXC_ID_PASSWORD, 2),
+ mnHash(0x0000)
+{
+ if (aHash.getLength() >= 2)
+ {
+ mnHash = ((aHash[0] << 8) & 0xFFFF);
+ mnHash |= (aHash[1] & 0xFF);
+ }
+}
+
+XclExpPassHash::~XclExpPassHash()
+{
+}
+
+void XclExpPassHash::WriteBody(XclExpStream& rStrm)
+{
+ rStrm << mnHash;
+}
+
+// ============================================================================
+
+XclExpFiltermode::XclExpFiltermode() :
+ XclExpEmptyRecord( EXC_ID_FILTERMODE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpAutofilterinfo::XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol ) :
+ XclExpUInt16Record( EXC_ID_AUTOFILTERINFO, static_cast< sal_uInt16 >( nScCol ) ),
+ maStartPos( rStartPos )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ExcFilterCondition::ExcFilterCondition() :
+ nType( EXC_AFTYPE_NOTUSED ),
+ nOper( EXC_AFOPER_EQUAL ),
+ fVal( 0.0 ),
+ pText( NULL )
+{
+}
+
+ExcFilterCondition::~ExcFilterCondition()
+{
+ if( pText )
+ delete pText;
+}
+
+sal_Size ExcFilterCondition::GetTextBytes() const
+{
+ return pText ? (1 + pText->GetBufferSize()) : 0;
+}
+
+void ExcFilterCondition::SetCondition( sal_uInt8 nTp, sal_uInt8 nOp, double fV, String* pT )
+{
+ nType = nTp;
+ nOper = nOp;
+ fVal = fV;
+
+ delete pText;
+ pText = pT ? new XclExpString( *pT, EXC_STR_8BITLENGTH ) : NULL;
+}
+
+void ExcFilterCondition::Save( XclExpStream& rStrm )
+{
+ rStrm << nType << nOper;
+ switch( nType )
+ {
+ case EXC_AFTYPE_DOUBLE:
+ rStrm << fVal;
+ break;
+ case EXC_AFTYPE_STRING:
+ DBG_ASSERT( pText, "ExcFilterCondition::Save() -- pText is NULL!" );
+ rStrm << (sal_uInt32)0 << (sal_uInt8) pText->Len() << (sal_uInt16)0 << (sal_uInt8)0;
+ break;
+ case EXC_AFTYPE_BOOLERR:
+ rStrm << (sal_uInt8)0 << (sal_uInt8)((fVal != 0) ? 1 : 0) << (sal_uInt32)0 << (sal_uInt16)0;
+ break;
+ default:
+ rStrm << (sal_uInt32)0 << (sal_uInt32)0;
+ }
+}
+
+static const char* lcl_GetOperator( sal_uInt8 nOper )
+{
+ switch( nOper )
+ {
+ case EXC_AFOPER_EQUAL: return "equal";
+ case EXC_AFOPER_GREATER: return "greaterThan";
+ case EXC_AFOPER_GREATEREQUAL: return "greaterThanOrEqual";
+ case EXC_AFOPER_LESS: return "lessThan";
+ case EXC_AFOPER_LESSEQUAL: return "lessThanOrEqual";
+ case EXC_AFOPER_NOTEQUAL: return "notEqual";
+ case EXC_AFOPER_NONE:
+ default: return "**none**";
+ }
+}
+
+static OString lcl_GetValue( sal_uInt8 nType, double fVal, XclExpString* pStr )
+{
+ switch( nType )
+ {
+ case EXC_AFTYPE_STRING: return XclXmlUtils::ToOString( *pStr );
+ case EXC_AFTYPE_DOUBLE: return OString::valueOf( fVal );
+ case EXC_AFTYPE_BOOLERR: return OString::valueOf( (sal_Int32) ( fVal != 0 ? 1 : 0 ) );
+ default: return OString();
+ }
+}
+
+void ExcFilterCondition::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( IsEmpty() )
+ return;
+
+ rStrm.GetCurrentStream()->singleElement( XML_customFilter,
+ XML_operator, lcl_GetOperator( nOper ),
+ XML_val, lcl_GetValue( nType, fVal, pText ).getStr(),
+ FSEND );
+}
+
+void ExcFilterCondition::SaveText( XclExpStream& rStrm )
+{
+ if( nType == EXC_AFTYPE_STRING )
+ {
+ DBG_ASSERT( pText, "ExcFilterCondition::SaveText() -- pText is NULL!" );
+ pText->WriteFlagField( rStrm );
+ pText->WriteBuffer( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
+ XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
+ XclExpRoot( rRoot ),
+ nCol( nC ),
+ nFlags( 0 )
+{
+}
+
+sal_Bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp,
+ double fVal, String* pText, sal_Bool bSimple )
+{
+ if( !aCond[ 1 ].IsEmpty() )
+ return false;
+
+ sal_uInt16 nInd = aCond[ 0 ].IsEmpty() ? 0 : 1;
+
+ if( nInd == 1 )
+ nFlags |= (eConn == SC_OR) ? EXC_AFFLAG_OR : EXC_AFFLAG_AND;
+ if( bSimple )
+ nFlags |= (nInd == 0) ? EXC_AFFLAG_SIMPLE1 : EXC_AFFLAG_SIMPLE2;
+
+ aCond[ nInd ].SetCondition( nType, nOp, fVal, pText );
+
+ AddRecSize( aCond[ nInd ].GetTextBytes() );
+
+ return sal_True;
+}
+
+sal_Bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
+{
+ sal_Bool bConflict = false;
+ String sText;
+
+ if( rEntry.pStr )
+ {
+ sText.Assign( *rEntry.pStr );
+ switch( rEntry.eOp )
+ {
+ case SC_CONTAINS:
+ case SC_DOES_NOT_CONTAIN:
+ {
+ sText.InsertAscii( "*" , 0 );
+ sText.AppendAscii( "*" );
+ }
+ break;
+ case SC_BEGINS_WITH:
+ case SC_DOES_NOT_BEGIN_WITH:
+ sText.AppendAscii( "*" );
+ break;
+ case SC_ENDS_WITH:
+ case SC_DOES_NOT_END_WITH:
+ sText.InsertAscii( "*" , 0 );
+ break;
+ default:
+ {
+ //nothing
+ }
+ }
+ }
+
+ sal_Bool bLen = sText.Len() > 0;
+
+ // empty/nonempty fields
+ if( !bLen && (rEntry.nVal == SC_EMPTYFIELDS) )
+ bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, NULL, sal_True );
+ else if( !bLen && (rEntry.nVal == SC_NONEMPTYFIELDS) )
+ bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, NULL, sal_True );
+ // other conditions
+ else
+ {
+ double fVal = 0.0;
+ sal_uInt32 nIndex = 0;
+ sal_Bool bIsNum = bLen ? GetFormatter().IsNumberFormat( sText, nIndex, fVal ) : sal_True;
+ String* pText = bIsNum ? NULL : &sText;
+
+ // top10 flags
+ sal_uInt16 nNewFlags = 0x0000;
+ switch( rEntry.eOp )
+ {
+ case SC_TOPVAL:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP);
+ break;
+ case SC_BOTVAL:
+ nNewFlags = EXC_AFFLAG_TOP10;
+ break;
+ case SC_TOPPERC:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP | EXC_AFFLAG_TOP10PERC);
+ break;
+ case SC_BOTPERC:
+ nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10PERC);
+ break;
+ default:;
+ }
+ sal_Bool bNewTop10 = ::get_flag( nNewFlags, EXC_AFFLAG_TOP10 );
+
+ bConflict = HasTop10() && bNewTop10;
+ if( !bConflict )
+ {
+ if( bNewTop10 )
+ {
+ if( fVal < 0 ) fVal = 0;
+ if( fVal >= 501 ) fVal = 500;
+ nFlags |= (nNewFlags | (sal_uInt16)(fVal) << 7);
+ }
+ // normal condition
+ else
+ {
+ sal_uInt8 nType = bIsNum ? EXC_AFTYPE_DOUBLE : EXC_AFTYPE_STRING;
+ sal_uInt8 nOper = EXC_AFOPER_NONE;
+
+ switch( rEntry.eOp )
+ {
+ case SC_EQUAL: nOper = EXC_AFOPER_EQUAL; break;
+ case SC_LESS: nOper = EXC_AFOPER_LESS; break;
+ case SC_GREATER: nOper = EXC_AFOPER_GREATER; break;
+ case SC_LESS_EQUAL: nOper = EXC_AFOPER_LESSEQUAL; break;
+ case SC_GREATER_EQUAL: nOper = EXC_AFOPER_GREATEREQUAL; break;
+ case SC_NOT_EQUAL: nOper = EXC_AFOPER_NOTEQUAL; break;
+ case SC_CONTAINS:
+ case SC_BEGINS_WITH:
+ case SC_ENDS_WITH:
+ nOper = EXC_AFOPER_EQUAL; break;
+ case SC_DOES_NOT_CONTAIN:
+ case SC_DOES_NOT_BEGIN_WITH:
+ case SC_DOES_NOT_END_WITH:
+ nOper = EXC_AFOPER_NOTEQUAL; break;
+ default:;
+ }
+ bConflict = !AddCondition( rEntry.eConnect, nType, nOper, fVal, pText );
+ }
+ }
+ }
+ return bConflict;
+}
+
+void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << nCol << nFlags;
+ aCond[ 0 ].Save( rStrm );
+ aCond[ 1 ].Save( rStrm );
+ aCond[ 0 ].SaveText( rStrm );
+ aCond[ 1 ].SaveText( rStrm );
+}
+
+void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !HasCondition() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+
+ rWorksheet->startElement( XML_filterColumn,
+ XML_colId, OString::valueOf( (sal_Int32) nCol ).getStr(),
+ // OOXTODO: XML_hiddenButton, AutoFilter12 fHideArrow?
+ // OOXTODO: XML_showButton,
+ FSEND );
+
+ if( HasTop10() )
+ {
+ rWorksheet->singleElement( XML_top10,
+ XML_top, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
+ XML_percent, XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
+ XML_val, OString::valueOf( (sal_Int32) (nFlags >> 7 ) ).getStr(),
+ // OOXTODO: XML_filterVal,
+ FSEND );
+ }
+
+ rWorksheet->startElement( XML_customFilters,
+ XML_and, XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
+ FSEND );
+ aCond[ 0 ].SaveXml( rStrm );
+ aCond[ 1 ].SaveXml( rStrm );
+ rWorksheet->endElement( XML_customFilters );
+ // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
+ // XML_extLst, XML_filters, XML_iconFilter, XML_top10
+ rWorksheet->endElement( XML_filterColumn );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRoot( rRoot ),
+ pFilterMode( NULL ),
+ pFilterInfo( NULL )
+ , mbAutoFilter (false)
+{
+ XclExpNameManager& rNameMgr = GetNameManager();
+
+ sal_Bool bFound = false;
+ sal_Bool bAdvanced = false;
+ ScDBData* pData = rRoot.GetDoc().GetAnonymousDBData(nTab);
+ ScRange aAdvRange;
+ if (pData)
+ {
+ bAdvanced = pData->GetAdvancedQuerySource( aAdvRange );
+ bFound = (pData->HasQueryParam() || pData->HasAutoFilter() || bAdvanced);
+ }
+ if( bFound )
+ {
+ ScQueryParam aParam;
+ pData->GetQueryParam( aParam );
+
+ ScRange aRange( aParam.nCol1, aParam.nRow1, aParam.nTab,
+ aParam.nCol2, aParam.nRow2, aParam.nTab );
+ SCCOL nColCnt = aParam.nCol2 - aParam.nCol1 + 1;
+
+ maRef = aRange;
+
+ // #i2394# built-in defined names must be sorted by containing sheet name
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_FILTERDATABASE, aRange );
+
+ // advanced filter
+ if( bAdvanced )
+ {
+ // filter criteria, excel allows only same table
+ if( aAdvRange.aStart.Tab() == nTab )
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_CRITERIA, aAdvRange );
+
+ // filter destination range, excel allows only same table
+ if( !aParam.bInplace )
+ {
+ ScRange aDestRange( aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
+ aDestRange.aEnd.IncCol( nColCnt - 1 );
+ if( aDestRange.aStart.Tab() == nTab )
+ rNameMgr.InsertBuiltInName( EXC_BUILTIN_EXTRACT, aDestRange );
+ }
+
+ pFilterMode = new XclExpFiltermode;
+ }
+ // AutoFilter
+ else
+ {
+ sal_Bool bConflict = false;
+ sal_Bool bContLoop = sal_True;
+ sal_Bool bHasOr = false;
+ SCCOLROW nFirstField = aParam.GetEntry( 0 ).nField;
+
+ // create AUTOFILTER records for filtered columns
+ for( SCSIZE nEntry = 0; !bConflict && bContLoop && (nEntry < aParam.GetEntryCount()); nEntry++ )
+ {
+ const ScQueryEntry& rEntry = aParam.GetEntry( nEntry );
+
+ bContLoop = rEntry.bDoQuery;
+ if( bContLoop )
+ {
+ XclExpAutofilter* pFilter = GetByCol( static_cast<SCCOL>(rEntry.nField) - aRange.aStart.Col() );
+
+ if( nEntry > 0 )
+ bHasOr |= (rEntry.eConnect == SC_OR);
+
+ bConflict = (nEntry > 1) && bHasOr;
+ if( !bConflict )
+ bConflict = (nEntry == 1) && (rEntry.eConnect == SC_OR) &&
+ (nFirstField != rEntry.nField);
+ if( !bConflict )
+ bConflict = pFilter->AddEntry( rEntry );
+ }
+ }
+
+ // additional tests for conflicts
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); !bConflict && (nPos < nSize); ++nPos )
+ {
+ XclExpAutofilterRef xFilter = maFilterList.GetRecord( nPos );
+ bConflict = xFilter->HasCondition() && xFilter->HasTop10();
+ }
+
+ if( bConflict )
+ maFilterList.RemoveAllRecords();
+
+ if( !maFilterList.IsEmpty() )
+ pFilterMode = new XclExpFiltermode;
+ pFilterInfo = new XclExpAutofilterinfo( aRange.aStart, nColCnt );
+
+ if (maFilterList.IsEmpty () && !bConflict)
+ mbAutoFilter = true;
+ }
+ }
+}
+
+ExcAutoFilterRecs::~ExcAutoFilterRecs()
+{
+ delete pFilterMode;
+ delete pFilterInfo;
+}
+
+XclExpAutofilter* ExcAutoFilterRecs::GetByCol( SCCOL nCol )
+{
+ XclExpAutofilterRef xFilter;
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
+ {
+ xFilter = maFilterList.GetRecord( nPos );
+ if( xFilter->GetCol() == static_cast<sal_uInt16>(nCol) )
+ return xFilter.get();
+ }
+ xFilter.reset( new XclExpAutofilter( GetRoot(), static_cast<sal_uInt16>(nCol) ) );
+ maFilterList.AppendRecord( xFilter );
+ return xFilter.get();
+}
+
+sal_Bool ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
+{
+ for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
+ if( maFilterList.GetRecord( nPos )->GetCol() == static_cast<sal_uInt16>(nCol) )
+ return sal_True;
+ return false;
+}
+
+void ExcAutoFilterRecs::AddObjRecs()
+{
+ if( pFilterInfo )
+ {
+ ScAddress aAddr( pFilterInfo->GetStartPos() );
+ for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ )
+ {
+ XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) );
+ GetObjectManager().AddObj( pObjRec );
+ aAddr.IncCol( 1 );
+ }
+ }
+}
+
+void ExcAutoFilterRecs::Save( XclExpStream& rStrm )
+{
+ if( pFilterMode )
+ pFilterMode->Save( rStrm );
+ if( pFilterInfo )
+ pFilterInfo->Save( rStrm );
+ maFilterList.Save( rStrm );
+}
+
+void ExcAutoFilterRecs::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maFilterList.IsEmpty() && !mbAutoFilter )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_autoFilter,
+ XML_ref, XclXmlUtils::ToOString( maRef ).getStr(),
+ FSEND );
+ // OOXTODO: XML_extLst, XML_sortState
+ if( !maFilterList.IsEmpty() )
+ maFilterList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_autoFilter );
+}
+
+bool ExcAutoFilterRecs::HasFilterMode() const
+{
+ return pFilterMode != NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpFilterManager::XclExpFilterManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpFilterManager::InitTabFilter( SCTAB nScTab )
+{
+ maFilterMap[ nScTab ].reset( new ExcAutoFilterRecs( GetRoot(), nScTab ) );
+}
+
+XclExpRecordRef XclExpFilterManager::CreateRecord( SCTAB nScTab )
+{
+ XclExpTabFilterRef xRec;
+ XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
+ if( aIt != maFilterMap.end() )
+ {
+ xRec = aIt->second;
+ xRec->AddObjRecs();
+ }
+ return xRec;
+}
+
+bool XclExpFilterManager::HasFilterMode( SCTAB nScTab )
+{
+ XclExpTabFilterRef xRec;
+ XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
+ if( aIt != maFilterMap.end() )
+ {
+ return aIt->second->HasFilterMode();
+ }
+ return false;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx
new file mode 100644
index 000000000000..4cfedccea8f5
--- /dev/null
+++ b/sc/source/filter/excel/exctools.cxx
@@ -0,0 +1,296 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+
+#include "document.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "scextopt.hxx"
+#include "progress.hxx"
+#include "rangenam.hxx"
+#include "editutil.hxx"
+
+#include "excrecds.hxx"
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+#include "otlnbuff.hxx"
+#include "xcl97rec.hxx"
+#include "formel.hxx"
+#include "xilink.hxx"
+#include "xecontent.hxx"
+
+#include <vector>
+
+RootData::RootData( void )
+{
+ eDateiTyp = BiffX;
+ pExtSheetBuff = NULL;
+ pShrfmlaBuff = NULL;
+ pExtNameBuff = NULL;
+ pFmlaConverter = NULL;
+
+ pAutoFilterBuffer = NULL;
+ pPrintRanges = new _ScRangeListTabs;
+ pPrintTitles = new _ScRangeListTabs;
+
+ pTabId = NULL;
+ pUserBViewList = NULL;
+
+ pIR = NULL;
+ pER = NULL;
+}
+
+RootData::~RootData()
+{
+ delete pExtSheetBuff;
+ delete pShrfmlaBuff;
+ delete pExtNameBuff;
+ delete pAutoFilterBuffer;
+ delete pPrintRanges;
+ delete pPrintTitles;
+}
+
+
+XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize ) :
+ maLevels(0, nNewSize, 0),
+ mpOutlineArray(NULL),
+ mnEndPos(nNewSize),
+ mnMaxLevel(0),
+ mbButtonAfter(true)
+{
+}
+
+XclImpOutlineBuffer::~XclImpOutlineBuffer()
+{
+}
+
+void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed )
+{
+ maLevels.insert_back(nIndex, nIndex+1, nVal);
+ if (nVal > mnMaxLevel)
+ mnMaxLevel = nVal;
+ if (bCollapsed)
+ maCollapsedPosSet.insert(nIndex);
+}
+
+void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
+{
+ mpOutlineArray = pOArray;
+}
+
+void XclImpOutlineBuffer::MakeScOutline()
+{
+ if (!mpOutlineArray)
+ return;
+
+ ::std::vector<SCSIZE> aOutlineStack;
+ aOutlineStack.reserve(mnMaxLevel);
+ OutlineLevels::const_iterator itr = maLevels.begin(), itrEnd = maLevels.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ SCSIZE nPos = itr->first;
+ if (nPos >= mnEndPos)
+ {
+ // Don't go beyond the max allowed position.
+ DBG_ASSERT(aOutlineStack.empty(), "XclImpOutlineBuffer::MakeScOutline: outline stack not empty but expected to be.");
+ break;
+ }
+ sal_uInt8 nLevel = itr->second;
+ sal_uInt8 nCurLevel = static_cast<sal_uInt8>(aOutlineStack.size());
+ if (nLevel > nCurLevel)
+ {
+ for (sal_uInt8 i = 0; i < nLevel - nCurLevel; ++i)
+ aOutlineStack.push_back(nPos);
+ }
+ else
+ {
+ DBG_ASSERT(nLevel < nCurLevel, "XclImpOutlineBuffer::MakeScOutline: unexpected level!");
+ for (sal_uInt8 i = 0; i < nCurLevel - nLevel; ++i)
+ {
+ if (aOutlineStack.empty())
+ {
+ // Something is wrong.
+ return;
+ }
+ SCSIZE nFirstPos = aOutlineStack.back();
+ aOutlineStack.pop_back();
+ bool bCollapsed = false;
+ if (mbButtonAfter)
+ bCollapsed = maCollapsedPosSet.count(nPos) > 0;
+ else if (nFirstPos > 0)
+ bCollapsed = maCollapsedPosSet.count(nFirstPos-1) > 0;
+
+ sal_Bool bDummy;
+ mpOutlineArray->Insert(nFirstPos, nPos-1, bDummy, bCollapsed);
+ }
+ }
+ }
+}
+
+void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed )
+{
+ if (nF > nL)
+ // invalid range
+ return;
+
+ maLevels.insert_back(nF, nL+1, nVal);
+
+ if (bCollapsed)
+ maCollapsedPosSet.insert(nF);
+}
+
+void XclImpOutlineBuffer::SetButtonMode( bool bRightOrUnder )
+{
+ mbButtonAfter = bRightOrUnder;
+}
+
+ExcScenarioCell::ExcScenarioCell( const sal_uInt16 nC, const sal_uInt16 nR )
+ : nCol( nC ), nRow( nR )
+{
+}
+
+ExcScenario::ExcScenario( XclImpStream& rIn, const RootData& rR )
+ : nTab( rR.pIR->GetCurrScTab() )
+{
+ sal_uInt16 nCref;
+ sal_uInt8 nName, nComment;
+
+ rIn >> nCref;
+ rIn >> nProtected;
+ rIn.Ignore( 1 ); // Hide
+ rIn >> nName >> nComment;
+ rIn.Ignore( 1 ); // statt nUser!
+
+ if( nName )
+ pName = new String( rIn.ReadUniString( nName ) );
+ else
+ {
+ pName = new String( RTL_CONSTASCII_USTRINGPARAM( "Scenery" ) );
+ rIn.Ignore( 1 );
+ }
+
+ pUserName = new String( rIn.ReadUniString() );
+
+ if( nComment )
+ pComment = new String( rIn.ReadUniString() );
+ else
+ pComment = new String;
+
+ sal_uInt16 n = nCref;
+ sal_uInt16 nC, nR;
+ while( n )
+ {
+ rIn >> nR >> nC;
+
+ aEntries.push_back(new ExcScenarioCell( nC, nR ));
+
+ n--;
+ }
+
+ n = nCref;
+
+ boost::ptr_vector<ExcScenarioCell>::iterator iter;
+ for (iter = aEntries.begin(); iter != aEntries.end(); ++iter)
+ iter->SetValue(rIn.ReadUniString());
+}
+
+ExcScenario::~ExcScenario()
+{
+ if( pName )
+ delete pName;
+ if( pComment )
+ delete pComment;
+ if( pUserName )
+ delete pUserName;
+}
+
+void ExcScenario::Apply( const XclImpRoot& rRoot, const sal_Bool bLast )
+{
+ ScDocument& r = rRoot.GetDoc();
+ String aSzenName( *pName );
+ sal_uInt16 nNewTab = nTab + 1;
+
+ if( !r.InsertTab( nNewTab, aSzenName ) )
+ return;
+
+ r.SetScenario( nNewTab, true );
+ // do not show scenario frames
+ r.SetScenarioData( nNewTab, *pComment, COL_LIGHTGRAY, /*SC_SCENARIO_SHOWFRAME|*/SC_SCENARIO_COPYALL|(nProtected ? SC_SCENARIO_PROTECT : 0) );
+
+ boost::ptr_vector<ExcScenarioCell>::const_iterator iter;
+ for (iter = aEntries.begin(); iter != aEntries.end(); ++iter)
+ {
+ sal_uInt16 nCol = iter->nCol;
+ sal_uInt16 nRow = iter->nRow;
+ String aVal = iter->GetValue();
+
+ r.ApplyFlagsTab( nCol, nRow, nCol, nRow, nNewTab, SC_MF_SCENARIO );
+
+ r.SetString( nCol, nRow, nNewTab, aVal );
+ }
+
+ if( bLast )
+ r.SetActiveScenario( nNewTab, sal_True );
+
+ // modify what the Active tab is set to if the new
+ // scenario tab occurs before the active tab.
+ ScExtDocSettings& rDocSett = rRoot.GetExtDocOptions().GetDocSettings();
+ if( (static_cast< SCCOL >( nTab ) < rDocSett.mnDisplTab) && (rDocSett.mnDisplTab < MAXTAB) )
+ ++rDocSett.mnDisplTab;
+ rRoot.GetTabInfo().InsertScTab( nNewTab );
+}
+
+void ExcScenarioList::Apply( const XclImpRoot& rRoot )
+{
+ sal_uInt16 n = static_cast<sal_uInt16>(aEntries.size());
+
+ boost::ptr_vector<ExcScenario>::reverse_iterator iter;
+ for (iter = aEntries.rbegin(); iter != aEntries.rend(); ++iter)
+ {
+ n--;
+ iter->Apply(rRoot, n == nLastScenario);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx
new file mode 100644
index 000000000000..f52c0d7feec2
--- /dev/null
+++ b/sc/source/filter/excel/expop2.cxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <unotools/fltrcfg.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/docinf.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+
+#include "scerrors.hxx"
+#include "scextopt.hxx"
+
+#include "root.hxx"
+#include "excdoc.hxx"
+#include "exp_op.hxx"
+
+#include "xcl97esc.hxx"
+
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "filtopt.hxx"
+#include "xltools.hxx"
+#include "xelink.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+
+ExportBiff5::ExportBiff5( XclExpRootData& rExpData, SvStream& rStrm ):
+ ExportTyp( rStrm, &rExpData.mrDoc, rExpData.meTextEnc ),
+ XclExpRoot( rExpData )
+{
+ // nur Teil der Root-Daten gebraucht
+ pExcRoot = &GetOldRoot();
+ pExcRoot->pER = this; // ExcRoot -> XclExpRoot
+ pExcRoot->eDateiTyp = Biff5;
+ pExcDoc = new ExcDocument( *this );
+}
+
+
+ExportBiff5::~ExportBiff5()
+{
+ delete pExcDoc;
+}
+
+
+FltError ExportBiff5::Write()
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+ DBG_ASSERT( pDocShell, "ExportBiff5::Write - no document shell" );
+
+ SotStorageRef xRootStrg = GetRootStorage();
+ DBG_ASSERT( xRootStrg.Is(), "ExportBiff5::Write - no root storage" );
+
+ bool bWriteBasicCode = false;
+ bool bWriteBasicStrg = false;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
+ {
+ bWriteBasicCode = pFilterOpt->IsLoadExcelBasicCode();
+ bWriteBasicStrg = pFilterOpt->IsLoadExcelBasicStorage();
+ }
+ }
+
+ if( pDocShell && xRootStrg.Is() && bWriteBasicStrg )
+ {
+ SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
+ sal_uLong nErr = aBasicImport.SaveOrDelMSVBAStorage( sal_True, EXC_STORAGE_VBA_PROJECT );
+ if( nErr != ERRCODE_NONE )
+ pDocShell->SetError( nErr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ pExcDoc->ReadDoc(); // ScDoc -> ExcDoc
+ pExcDoc->Write( aOut ); // wechstreamen
+
+ if( pDocShell && xRootStrg.Is() )
+ {
+ // #i88642# update doc info (revision etc)
+ pDocShell->UpdateDocInfoForSave();
+
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ if ( SvtFilterOptions::Get()->IsEnableCalcPreview() )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ pDocShell->GetPreviewMetaFile (false);
+ uno::Sequence<sal_uInt8> metaFile(
+ sfx2::convertMetaFile(pMetaFile.get()));
+ sfx2::SaveOlePropertySet(xDocProps, xRootStrg, &metaFile);
+ }
+ else
+ sfx2::SaveOlePropertySet(xDocProps, xRootStrg );
+ }
+
+ //! TODO: separate warnings for columns and sheets
+ const XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsColTruncated() || rAddrConv.IsRowTruncated() || rAddrConv.IsTabTruncated() )
+ return SCWARN_EXPORT_MAXROW;
+
+ return eERR_OK;
+}
+
+
+
+ExportBiff8::ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm ) :
+ ExportBiff5( rExpData, rStrm )
+{
+ pExcRoot->eDateiTyp = Biff8;
+}
+
+
+ExportBiff8::~ExportBiff8()
+{
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/fontbuff.cxx b/sc/source/filter/excel/fontbuff.cxx
new file mode 100644
index 000000000000..26db50f0166f
--- /dev/null
+++ b/sc/source/filter/excel/fontbuff.cxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "lotfntbf.hxx"
+
+#include "scitems.hxx"
+#include <editeng/cntritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/printer.hxx>
+
+#include "attrib.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "ftools.hxx"
+
+const sal_uInt16 LotusFontBuffer::nSize = 8;
+
+void LotusFontBuffer::Fill( const sal_uInt8 nIndex, SfxItemSet& rItemSet )
+{
+ sal_uInt8 nIntIndex = nIndex & 0x07;
+
+ ENTRY* pAkt = pData + nIntIndex;
+
+ if( pAkt->pFont )
+ rItemSet.Put( *pAkt->pFont );
+
+ if( pAkt->pHeight )
+ rItemSet.Put( *pAkt->pHeight );
+
+ if( pAkt->pColor )
+ rItemSet.Put( *pAkt->pColor );
+
+ if( nIndex & 0x08 )
+ {
+ SvxWeightItem aWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT );
+ rItemSet.Put( aWeightItem );
+ }
+
+ if( nIndex & 0x10 )
+ {
+ SvxPostureItem aAttr( ITALIC_NORMAL, ATTR_FONT_POSTURE );
+ rItemSet.Put( aAttr );
+ }
+
+ FontUnderline eUnderline;
+ switch( nIndex & 0x60 ) // Bit 5+6
+ {
+ case 0x60:
+ case 0x20: eUnderline = UNDERLINE_SINGLE; break;
+ case 0x40: eUnderline = UNDERLINE_DOUBLE; break;
+ default: eUnderline = UNDERLINE_NONE;
+ }
+ if( eUnderline != UNDERLINE_NONE )
+ {
+ SvxUnderlineItem aUndItem( eUnderline, ATTR_FONT_UNDERLINE );
+ rItemSet.Put( aUndItem );
+ }
+}
+
+
+void LotusFontBuffer::SetName( const sal_uInt16 nIndex, const String& rName )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetName(): Array zu klein!" );
+ if( nIndex < nSize )
+ {
+ register ENTRY* pEntry = pData + nIndex;
+ pEntry->TmpName( rName );
+
+ if( pEntry->nType >= 0 )
+ MakeFont( pEntry );
+ }
+}
+
+
+void LotusFontBuffer::SetHeight( const sal_uInt16 nIndex, const sal_uInt16 nHeight )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetHeight(): Array zu klein!" );
+ if( nIndex < nSize )
+ pData[ nIndex ].Height( *( new SvxFontHeightItem( ( sal_uLong ) nHeight * 20, 100, ATTR_FONT_HEIGHT ) ) );
+}
+
+
+void LotusFontBuffer::SetType( const sal_uInt16 nIndex, const sal_uInt16 nType )
+{
+ DBG_ASSERT( nIndex < nSize, "*LotusFontBuffer::SetType(): Array zu klein!" );
+ if( nIndex < nSize )
+ {
+ register ENTRY* pEntry = pData + nIndex;
+ pEntry->Type( nType );
+
+ if( pEntry->pTmpName )
+ MakeFont( pEntry );
+ }
+}
+
+
+void LotusFontBuffer::MakeFont( ENTRY* pEntry )
+{
+ FontFamily eFamily = FAMILY_DONTKNOW;
+ FontPitch ePitch = PITCH_DONTKNOW;
+ CharSet eCharSet = RTL_TEXTENCODING_DONTKNOW;
+
+ switch( pEntry->nType )
+ {
+ case 0x00: // Helvetica
+ eFamily = FAMILY_SWISS;
+ ePitch = PITCH_VARIABLE;
+ break;
+ case 0x01: // Times Roman
+ eFamily = FAMILY_ROMAN;
+ ePitch = PITCH_VARIABLE;
+ break;
+ case 0x02: // Courier
+ ePitch = PITCH_FIXED;
+ break;
+ case 0x03: // Symbol
+ eCharSet = RTL_TEXTENCODING_SYMBOL;
+ break;
+ }
+
+ pEntry->pFont = new SvxFontItem( eFamily, *pEntry->pTmpName, EMPTY_STRING, ePitch, eCharSet, ATTR_FONT );
+
+ delete pEntry->pTmpName;
+ pEntry->pTmpName = NULL;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/frmbase.cxx b/sc/source/filter/excel/frmbase.cxx
new file mode 100644
index 000000000000..81706ce5cb7d
--- /dev/null
+++ b/sc/source/filter/excel/frmbase.cxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "formel.hxx"
+
+_ScRangeListTabs::_ScRangeListTabs()
+{
+}
+
+_ScRangeListTabs::~_ScRangeListTabs()
+{
+}
+
+
+void _ScRangeListTabs::Append( ScSingleRefData a, SCTAB nTab, const bool b )
+{
+ if( b )
+ {
+ if( a.nTab > MAXTAB )
+ a.nTab = MAXTAB;
+
+ if( a.nCol > MAXCOL )
+ a.nCol = MAXCOL;
+
+ if( a.nRow > MAXROW )
+ a.nRow = MAXROW;
+ }
+ else
+ {
+ DBG_ASSERT( ValidTab(a.nTab), "-_ScRangeListTabs::Append(): Luegen haben kurze Abstuerze!" );
+ }
+
+ if( nTab == SCTAB_MAX)
+ return;
+ if( nTab < 0)
+ nTab = a.nTab;
+
+ if (nTab < 0 || MAXTAB < nTab)
+ return;
+
+ TabRangeType::iterator itr = maTabRanges.find(nTab);
+ if (itr == maTabRanges.end())
+ {
+ // No entry for this table yet. Insert a new one.
+ std::pair<TabRangeType::iterator, bool> r =
+ maTabRanges.insert(nTab, new RangeListType);
+
+ if (!r.second)
+ // Insertion failed.
+ return;
+
+ itr = r.first;
+ }
+ itr->second->push_back(ScRange(a.nCol,a.nRow,a.nTab));
+}
+
+void _ScRangeListTabs::Append( ScComplexRefData a, SCTAB nTab, bool b )
+{
+ if( b )
+ {
+ // ignore 3D ranges
+ if( a.Ref1.nTab != a.Ref2.nTab )
+ return;
+
+ SCsTAB& rTab = a.Ref1.nTab;
+ if( rTab > MAXTAB )
+ rTab = MAXTAB;
+ else if( rTab < 0 )
+ rTab = 0;
+
+ SCsCOL& rCol1 = a.Ref1.nCol;
+ if( rCol1 > MAXCOL )
+ rCol1 = MAXCOL;
+ else if( rCol1 < 0 )
+ rCol1 = 0;
+
+ SCsROW& rRow1 = a.Ref1.nRow;
+ if( rRow1 > MAXROW )
+ rRow1 = MAXROW;
+ else if( rRow1 < 0 )
+ rRow1 = 0;
+
+ SCsCOL& rCol2 = a.Ref2.nCol;
+ if( rCol2 > MAXCOL )
+ rCol2 = MAXCOL;
+ else if( rCol2 < 0 )
+ rCol2 = 0;
+
+ SCsROW& rRow2 = a.Ref2.nRow;
+ if( rRow2 > MAXROW )
+ rRow2 = MAXROW;
+ else if( rRow2 < 0 )
+ rRow2 = 0;
+ }
+ else
+ {
+ DBG_ASSERT( ValidTab(a.Ref1.nTab),
+ "-_ScRangeListTabs::Append(): Luegen haben kurze Abstuerze!" );
+ DBG_ASSERT( a.Ref1.nTab == a.Ref2.nTab,
+ "+_ScRangeListTabs::Append(): 3D-Ranges werden in SC nicht unterstuetzt!" );
+ }
+
+ if( nTab == SCTAB_MAX)
+ return;
+
+ if( nTab < -1)
+ nTab = a.Ref1.nTab;
+
+ if (nTab < 0 || MAXTAB < nTab)
+ return;
+
+ TabRangeType::iterator itr = maTabRanges.find(nTab);
+ if (itr == maTabRanges.end())
+ {
+ // No entry for this table yet. Insert a new one.
+ std::pair<TabRangeType::iterator, bool> r =
+ maTabRanges.insert(nTab, new RangeListType);
+
+ if (!r.second)
+ // Insertion failed.
+ return;
+
+ itr = r.first;
+ }
+ itr->second->push_back(
+ ScRange(a.Ref1.nCol,a.Ref1.nRow,a.Ref1.nTab,
+ a.Ref2.nCol,a.Ref2.nRow,a.Ref2.nTab));
+}
+
+const ScRange* _ScRangeListTabs::First( SCTAB n )
+{
+ DBG_ASSERT( ValidTab(n), "-_ScRangeListTabs::First(): Und tschuessssssss!" );
+
+ TabRangeType::iterator itr = maTabRanges.find(n);
+ if (itr == maTabRanges.end())
+ // No range list exists for this table.
+ return NULL;
+
+ const RangeListType& rList = *itr->second;
+ maItrCur = rList.begin();
+ maItrCurEnd = rList.end();
+ return rList.empty() ? NULL : &(*maItrCur);
+}
+
+const ScRange* _ScRangeListTabs::Next ()
+{
+ ++maItrCur;
+ if (maItrCur == maItrCurEnd)
+ return NULL;
+
+ return &(*maItrCur);
+}
+
+ConverterBase::ConverterBase( sal_uInt16 nNewBuffer ) :
+ aEingPos( 0, 0, 0 ),
+ eStatus( ConvOK ),
+ nBufferSize( nNewBuffer )
+{
+ DBG_ASSERT( nNewBuffer > 0, "ConverterBase::ConverterBase - nNewBuffer == 0!" );
+ pBuffer = new sal_Char[ nNewBuffer ];
+}
+
+ConverterBase::~ConverterBase()
+{
+ delete[] pBuffer;
+}
+
+void ConverterBase::Reset()
+{
+ eStatus = ConvOK;
+ aPool.Reset();
+ aStack.Reset();
+}
+
+
+
+
+ExcelConverterBase::ExcelConverterBase( sal_uInt16 nNewBuffer ) :
+ ConverterBase( nNewBuffer )
+{
+}
+
+ExcelConverterBase::~ExcelConverterBase()
+{
+}
+
+void ExcelConverterBase::Reset( const ScAddress& rEingPos )
+{
+ ConverterBase::Reset();
+ aEingPos = rEingPos;
+}
+
+void ExcelConverterBase::Reset()
+{
+ ConverterBase::Reset();
+ aEingPos.Set( 0, 0, 0 );
+}
+
+
+
+
+LotusConverterBase::LotusConverterBase( SvStream &rStr, sal_uInt16 nNewBuffer ) :
+ ConverterBase( nNewBuffer ),
+ aIn( rStr ),
+ nBytesLeft( 0 )
+{
+}
+
+LotusConverterBase::~LotusConverterBase()
+{
+}
+
+void LotusConverterBase::Reset( const ScAddress& rEingPos )
+{
+ ConverterBase::Reset();
+ nBytesLeft = 0;
+ aEingPos = rEingPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
new file mode 100644
index 000000000000..9ad703da3b0e
--- /dev/null
+++ b/sc/source/filter/excel/impop.cxx
@@ -0,0 +1,1336 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "imp_op.hxx"
+
+#include <filter/msfilter/countryid.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/colritem.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/zforlist.hxx>
+
+#include <sfx2/objsh.hxx>
+#include "tools/urlobj.hxx"
+#include "docuno.hxx"
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "compiler.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "markdata.hxx"
+#include "olinetab.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "compiler.hxx"
+#include "viewopti.hxx"
+#include "docoptio.hxx"
+#include "scextopt.hxx"
+#include "editutil.hxx"
+#include "filtopt.hxx"
+#include "scerrors.hxx"
+#include "unonames.hxx"
+#include "paramisc.hxx"
+#include "postit.hxx"
+
+#include "fapihelper.hxx"
+#include "xltools.hxx"
+#include "xltable.hxx"
+#include "xlview.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+#include "xicontent.hxx"
+
+#include "excimp8.hxx"
+#include "excform.hxx"
+
+#if defined( WNT )
+#include <math.h>
+#else
+#include <stdlib.h>
+#endif
+
+using namespace ::com::sun::star;
+
+
+const double ImportExcel::fExcToTwips =
+ ( double ) TWIPS_PER_CHAR / 256.0;
+
+
+ImportTyp::ImportTyp( ScDocument* pDoc, CharSet eQ )
+{
+ eQuellChar = eQ;
+ pD = pDoc;
+}
+
+
+ImportTyp::~ImportTyp()
+{
+}
+
+
+FltError ImportTyp::Read()
+{
+ return eERR_INTERN;
+}
+
+
+ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
+ ImportTyp( &rImpData.mrDoc, rImpData.meTextEnc ),
+ XclImpRoot( rImpData ),
+ maStrm( rStrm, GetRoot() ),
+ aIn( maStrm ),
+ maScOleSize( ScAddress::INITIALIZE_INVALID )
+{
+ mnLastRefIdx = 0;
+ nBdshtTab = 0;
+ nIxfeIndex = 0; // zur Sicherheit auf 0
+
+ // Root-Daten fuellen - nach new's ohne Root als Parameter
+ pExcRoot = &GetOldRoot();
+ pExcRoot->pIR = this; // ExcRoot -> XclImpRoot
+ pExcRoot->eDateiTyp = BiffX;
+ pExcRoot->pExtSheetBuff = new ExtSheetBuffer( pExcRoot ); //&aExtSheetBuff;
+ pExcRoot->pShrfmlaBuff = new ShrfmlaBuffer( pExcRoot ); //&aShrfrmlaBuff;
+ pExcRoot->pExtNameBuff = new ExtNameBuff ( *this );
+
+ pExtNameBuff = new NameBuffer( pExcRoot ); //prevent empty rootdata
+ pExtNameBuff->SetBase( 1 );
+
+ pOutlineListBuffer = new XclImpOutlineListBuffer( );
+
+ // ab Biff8
+ pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc( GetRoot() );
+
+ bTabTruncated = false;
+
+ // Excel-Dokument per Default auf 31.12.1899, entspricht Excel-Einstellungen mit 1.1.1900
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetDate( 30, 12, 1899 );
+ pD->SetDocOptions( aOpt );
+ pD->GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
+
+ ScDocOptions aDocOpt( pD->GetDocOptions() );
+ aDocOpt.SetIgnoreCase( sal_True ); // always in Excel
+ aDocOpt.SetFormulaRegexEnabled( false ); // regular expressions? what's that?
+ aDocOpt.SetLookUpColRowNames( false ); // default: no natural language refs
+ pD->SetDocOptions( aDocOpt );
+}
+
+
+ImportExcel::~ImportExcel( void )
+{
+ GetDoc().SetSrcCharSet( GetTextEncoding() );
+
+ delete pExtNameBuff;
+
+ delete pOutlineListBuffer;
+
+ delete pFormConv;
+}
+
+
+void ImportExcel::ReadFileSharing()
+{
+ sal_uInt16 nRecommendReadOnly, nPasswordHash;
+ maStrm >> nRecommendReadOnly >> nPasswordHash;
+
+ if( (nRecommendReadOnly != 0) || (nPasswordHash != 0) )
+ {
+ if( SfxItemSet* pItemSet = GetMedium().GetItemSet() )
+ pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+
+ if( SfxObjectShell* pShell = GetDocShell() )
+ {
+ if( nRecommendReadOnly != 0 )
+ pShell->SetLoadReadonly( sal_True );
+ if( nPasswordHash != 0 )
+ pShell->SetModifyPasswordHash( nPasswordHash );
+ }
+ }
+}
+
+sal_uInt16 ImportExcel::ReadXFIndex( bool bBiff2 )
+{
+ sal_uInt16 nXFIdx = 0;
+ if( bBiff2 )
+ {
+ sal_uInt8 nXFIdx2;
+ maStrm >> nXFIdx2;
+ maStrm.Ignore( 2 );
+ nXFIdx = nXFIdx2 & 0x3F;
+ if( nXFIdx == 63 )
+ nXFIdx = nIxfeIndex;
+ }
+ else
+ aIn >> nXFIdx;
+ return nXFIdx;
+}
+
+void ImportExcel::ReadDimensions()
+{
+ XclRange aXclUsedArea( ScAddress::UNINITIALIZED );
+ if( (maStrm.GetRecId() == EXC_ID2_DIMENSIONS) || (GetBiff() <= EXC_BIFF5) )
+ {
+ maStrm >> aXclUsedArea;
+ if( (aXclUsedArea.GetColCount() > 1) && (aXclUsedArea.GetRowCount() > 1) )
+ {
+ // Excel stores first unused row/column index
+ --aXclUsedArea.maLast.mnCol;
+ --aXclUsedArea.maLast.mnRow;
+ // create the Calc range
+ SCTAB nScTab = GetCurrScTab();
+ ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
+ GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
+ // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
+ }
+ }
+ else
+ {
+ sal_uInt32 nXclRow1, nXclRow2;
+ maStrm >> nXclRow1 >> nXclRow2 >> aXclUsedArea.maFirst.mnCol >> aXclUsedArea.maLast.mnCol;
+ if( (nXclRow1 < nXclRow2) && (aXclUsedArea.GetColCount() > 1) &&
+ (nXclRow1 <= static_cast< sal_uInt32 >( GetScMaxPos().Row() )) )
+ {
+ // Excel stores first unused row/column index
+ --nXclRow2;
+ --aXclUsedArea.maLast.mnCol;
+ // convert row indexes to 16-bit values
+ aXclUsedArea.maFirst.mnRow = static_cast< sal_uInt16 >( nXclRow1 );
+ aXclUsedArea.maLast.mnRow = limit_cast< sal_uInt16 >( nXclRow2, aXclUsedArea.maFirst.mnRow, SAL_MAX_UINT16 );
+ // create the Calc range
+ SCTAB nScTab = GetCurrScTab();
+ ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
+ GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
+ // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
+ }
+ }
+}
+
+void ImportExcel::ReadBlank()
+{
+ XclAddress aXclPos;
+ aIn >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BLANK );
+
+ GetXFRangeBuffer().SetBlankXF( aScPos, nXFIdx );
+ }
+}
+
+void ImportExcel::ReadInteger()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( true );
+ sal_uInt16 nValue;
+ maStrm >> nValue;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( nValue ) );
+ }
+}
+
+void ImportExcel::ReadNumber()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_NUMBER );
+ double fValue;
+ maStrm >> fValue;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( fValue ) );
+ }
+}
+
+void ImportExcel::ReadLabel()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ /* 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 */
+ bool bBiff2 = maStrm.GetRecId() == EXC_ID2_LABEL;
+ sal_uInt16 nXFIdx = ReadXFIndex( bBiff2 );
+ XclStrFlags nFlags = (bBiff2 && (GetBiff() <= EXC_BIFF5)) ? EXC_STR_8BITLENGTH : EXC_STR_DEFAULT;
+ XclImpString aString;
+
+ // #i63105# use text encoding from FONT record
+ rtl_TextEncoding eOldTextEnc = GetTextEncoding();
+ if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
+ SetTextEncoding( pFont->GetFontEncoding() );
+ aString.Read( maStrm, nFlags );
+ SetTextEncoding( eOldTextEnc );
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( GetRoot(), aString, nXFIdx ) )
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+void ImportExcel::ReadBoolErr()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BOOLERR );
+ sal_uInt8 nValue, nType;
+ maStrm >> nValue >> nType;
+
+ if( nType == EXC_BOOLERR_BOOL )
+ GetXFRangeBuffer().SetBoolXF( aScPos, nXFIdx );
+ else
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+
+ double fValue;
+ const ScTokenArray* pScTokArr = ErrorToFormula( nType, nValue, fValue );
+ ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pScTokArr );
+ pCell->SetHybridDouble( fValue );
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+void ImportExcel::ReadRk()
+{
+ XclAddress aXclPos;
+ maStrm >> aXclPos;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ sal_uInt16 nXFIdx = ReadXFIndex( false );
+ sal_Int32 nRk;
+ maStrm >> nRk;
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ GetDoc().PutCell( aScPos, new ScValueCell( XclTools::GetDoubleFromRK( nRk ) ) );
+ }
+}
+
+
+void ImportExcel::Window1()
+{
+ GetDocViewSettings().ReadWindow1( maStrm );
+}
+
+
+
+
+void ImportExcel::Row25( void )
+{
+ sal_uInt16 nRow, nRowHeight;
+
+ aIn >> nRow;
+ aIn.Ignore( 4 ); // Mic und Mac ueberspringen
+
+ if( ValidRow( nRow ) )
+ {
+ aIn >> nRowHeight; // direkt in Twips angegeben
+ aIn.Ignore( 2 );
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// -------------------- BIFF2
+ pColRowBuff->SetHeight( nRow, nRowHeight );
+ }
+ else
+ {// -------------------- BIFF5
+ sal_uInt16 nGrbit;
+
+ aIn.Ignore( 2 ); // reserved
+ aIn >> nGrbit;
+
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+ pRowOutlineBuff->SetLevel( nRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+ pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
+ }
+ }
+}
+
+
+void ImportExcel::Bof2( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff2C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff2M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff2;
+}
+
+
+void ImportExcel::Eof( void )
+{
+ // POST: darf nur nach einer GUELTIGEN Tabelle gerufen werden!
+ EndSheet();
+ IncCurrScTab();
+}
+
+
+void ImportExcel::SheetPassword( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
+}
+
+
+void ImportExcel::Externsheet( void )
+{
+ String aUrl, aTabName;
+ bool bSameWorkBook;
+ String aEncodedUrl( aIn.ReadByteString( false ) );
+ XclImpUrlHelper::DecodeUrl( aUrl, aTabName, bSameWorkBook, *pExcRoot->pIR, aEncodedUrl );
+ mnLastRefIdx = pExcRoot->pExtSheetBuff->Add( aUrl, aTabName, bSameWorkBook );
+}
+
+
+void ImportExcel:: WinProtection( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
+}
+
+
+void ImportExcel::Columndefault( void )
+{// Default Cell Attributes
+ sal_uInt16 nColMic, nColMac;
+ sal_uInt8 nOpt0;
+
+ aIn >> nColMic >> nColMac;
+
+ DBG_ASSERT( aIn.GetRecLeft() == (sal_Size)(nColMac - nColMic) * 3 + 2,
+ "ImportExcel::Columndefault - wrong record size" );
+
+ nColMac--;
+
+ if( nColMac > MAXCOL )
+ nColMac = static_cast<sal_uInt16>(MAXCOL);
+
+ for( sal_uInt16 nCol = nColMic ; nCol <= nColMac ; nCol++ )
+ {
+ aIn >> nOpt0;
+ aIn.Ignore( 2 ); // nur 0. Attribut-Byte benutzt
+
+ if( nOpt0 & 0x80 ) // Col hidden?
+ pColRowBuff->HideCol( nCol );
+ }
+}
+
+
+void ImportExcel::Array25( void )
+{
+ sal_uInt16 nFirstRow, nLastRow, nFormLen;
+ sal_uInt8 nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// BIFF2
+ aIn.Ignore( 1 );
+ nFormLen = aIn.ReaduInt8();
+ }
+ else
+ {// BIFF5
+ aIn.Ignore( 6 );
+ aIn >> nFormLen;
+ }
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
+ pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ DBG_ASSERT( pErgebnis, "*ImportExcel::Array25(): ScTokenArray ist NULL!" );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( GetCurrScTab() );
+ pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
+ pErgebnis );
+ }
+}
+
+
+void ImportExcel::Rec1904( void )
+{
+ sal_uInt16 n1904;
+
+ aIn >> n1904;
+
+ if( n1904 )
+ {// 1904 date system
+ ScDocOptions aOpt = pD->GetDocOptions();
+ aOpt.SetDate( 1, 1, 1904 );
+ pD->SetDocOptions( aOpt );
+ pD->GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
+ }
+}
+
+
+void ImportExcel::Externname25( void )
+{
+ sal_uInt32 nRes;
+ sal_uInt16 nOpt;
+
+ aIn >> nOpt >> nRes;
+
+ String aName( aIn.ReadByteString( false ) );
+
+ if( ( nOpt & 0x0001 ) || ( ( nOpt & 0xFFFE ) == 0x0000 ) )
+ {// external name
+ ScfTools::ConvertToScDefinedName( aName );
+ pExcRoot->pExtNameBuff->AddName( aName, mnLastRefIdx );
+ }
+ else if( nOpt & 0x0010 )
+ {// ole link
+ pExcRoot->pExtNameBuff->AddOLE( aName, mnLastRefIdx, nRes ); // nRes is storage ID
+ }
+ else
+ {// dde link
+ pExcRoot->pExtNameBuff->AddDDE( aName, mnLastRefIdx );
+ }
+}
+
+
+void ImportExcel::Colwidth( void )
+{// Column Width
+ sal_uInt8 nColFirst, nColLast;
+ sal_uInt16 nColWidth;
+
+ aIn >> nColFirst >> nColLast >> nColWidth;
+
+//! TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
+// if( nColLast > MAXCOL )
+// nColLast = static_cast<sal_uInt16>(MAXCOL);
+
+ sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
+ pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
+}
+
+
+void ImportExcel::Defrowheight2( void )
+{
+ sal_uInt16 nDefHeight;
+ maStrm >> nDefHeight;
+ nDefHeight &= 0x7FFF;
+ pColRowBuff->SetDefHeight( nDefHeight, EXC_DEFROW_UNSYNCED );
+}
+
+
+void ImportExcel::SheetProtect( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
+}
+
+void ImportExcel::DocProtect( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
+}
+
+void ImportExcel::DocPasssword( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
+}
+
+void ImportExcel::Codepage( void )
+{
+ SetCodePage( maStrm.ReaduInt16() );
+}
+
+
+void ImportExcel::Ixfe( void )
+{
+ aIn >> nIxfeIndex;
+}
+
+
+void ImportExcel::DefColWidth( void )
+{
+ // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
+ double fDefWidth = 256.0 * maStrm.ReaduInt16();
+
+ // #i3006# additional space for default width - Excel adds space depending on font size
+ long nFontHt = GetFontBuffer().GetAppFontData().mnHeight;
+ fDefWidth += XclTools::GetXclDefColWidthCorrection( nFontHt );
+
+ sal_uInt16 nScWidth = XclTools::GetScColumnWidth( limit_cast< sal_uInt16 >( fDefWidth ), GetCharWidth() );
+ pColRowBuff->SetDefWidth( nScWidth );
+}
+
+
+void ImportExcel::Builtinfmtcnt( void )
+{
+}
+
+
+void ImportExcel::Colinfo( void )
+{// Column Formatting Information
+ sal_uInt16 nColFirst, nColLast, nColWidth, nXF;
+ sal_uInt16 nOpt;
+
+ aIn >> nColFirst >> nColLast >> nColWidth >> nXF >> nOpt;
+
+ if( nColFirst > MAXCOL )
+ return;
+
+ if( nColLast > MAXCOL )
+ nColLast = static_cast<sal_uInt16>(MAXCOL);
+
+ bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
+ bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
+ pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed );
+
+ if( bHidden )
+ pColRowBuff->HideColRange( nColFirst, nColLast );
+
+ sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
+ pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
+ pColRowBuff->SetDefaultXF( nColFirst, nColLast, nXF );
+}
+
+
+void ImportExcel::Wsbool( void )
+{
+ sal_uInt16 nFlags;
+ aIn >> nFlags;
+
+ pRowOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_ROWBELOW ) );
+ pColOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_COLBELOW ) );
+
+ GetPageSettings().SetFitToPages( ::get_flag( nFlags, EXC_WSBOOL_FITTOPAGE ) );
+}
+
+
+void ImportExcel::Boundsheet( void )
+{
+ sal_uInt16 nGrbit = 0;
+
+ if( GetBiff() == EXC_BIFF5 )
+ {
+ aIn.DisableDecryption();
+ maSheetOffsets.push_back( aIn.ReaduInt32() );
+ aIn.EnableDecryption();
+ aIn >> nGrbit;
+ }
+
+ String aName( aIn.ReadByteString( false ) );
+
+ SCTAB nScTab = static_cast< SCTAB >( nBdshtTab );
+ if( nScTab > 0 )
+ {
+ DBG_ASSERT( !pD->HasTable( nScTab ), "ImportExcel::Boundsheet - sheet exists already" );
+ pD->MakeTable( nScTab );
+ }
+
+ if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
+ pD->SetVisible( nScTab, false );
+
+ if( !pD->RenameTab( nScTab, aName ) )
+ {
+ pD->CreateValidTabName( aName );
+ pD->RenameTab( nScTab, aName );
+ }
+
+ nBdshtTab++;
+}
+
+
+void ImportExcel::Country( void )
+{
+ sal_uInt16 nUICountry, nDocCountry;
+ maStrm >> nUICountry >> nDocCountry;
+
+ // Store system language in XclRoot
+ LanguageType eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nDocCountry ) );
+ if( eLanguage != LANGUAGE_DONTKNOW )
+ SetDocLanguage( eLanguage );
+
+ // Set Excel UI language in add-in name translator
+ eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nUICountry ) );
+ if( eLanguage != LANGUAGE_DONTKNOW )
+ SetUILanguage( eLanguage );
+}
+
+
+void ImportExcel::ReadUsesElfs()
+{
+ if( maStrm.ReaduInt16() != 0 )
+ {
+ ScDocOptions aDocOpt = GetDoc().GetDocOptions();
+ aDocOpt.SetLookUpColRowNames( sal_True );
+ GetDoc().SetDocOptions( aDocOpt );
+ }
+}
+
+
+void ImportExcel::Hideobj( void )
+{
+ sal_uInt16 nHide;
+ ScVObjMode eOle, eChart, eDraw;
+
+ aIn >> nHide;
+
+ ScViewOptions aOpts( pD->GetViewOptions() );
+
+ switch( nHide )
+ {
+ case 1: // Placeholders
+ eOle = VOBJ_MODE_SHOW; // in Excel 97 werden nur Charts als Platzhalter angezeigt
+ eChart = VOBJ_MODE_SHOW; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
+ eDraw = VOBJ_MODE_SHOW;
+ break;
+ case 2: // Hide all
+ eOle = VOBJ_MODE_HIDE;
+ eChart = VOBJ_MODE_HIDE;
+ eDraw = VOBJ_MODE_HIDE;
+ break;
+ default: // Show all
+ eOle = VOBJ_MODE_SHOW;
+ eChart = VOBJ_MODE_SHOW;
+ eDraw = VOBJ_MODE_SHOW;
+ break;
+ }
+
+ aOpts.SetObjMode( VOBJ_TYPE_OLE, eOle );
+ aOpts.SetObjMode( VOBJ_TYPE_CHART, eChart );
+ aOpts.SetObjMode( VOBJ_TYPE_DRAW, eDraw );
+
+ pD->SetViewOptions( aOpts );
+}
+
+
+void ImportExcel::Bundleheader( void )
+{
+}
+
+
+void ImportExcel::Standardwidth( void )
+{
+ sal_uInt16 nScWidth = XclTools::GetScColumnWidth( maStrm.ReaduInt16(), GetCharWidth() );
+ pColRowBuff->SetDefWidth( nScWidth, sal_True );
+}
+
+
+void ImportExcel::Shrfmla( void )
+{
+ sal_uInt16 nFirstRow, nLastRow, nLenExpr;
+ sal_uInt8 nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+ aIn.Ignore( 2 );
+ aIn >> nLenExpr;
+
+ // jetzt steht Lesemarke an der Formel
+
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset();
+ pFormConv->Convert( pErgebnis, maStrm, nLenExpr, true, FT_SharedFormula );
+
+
+ DBG_ASSERT( pErgebnis, "+ImportExcel::Shrfmla(): ScTokenArray ist NULL!" );
+
+ pExcRoot->pShrfmlaBuff->Store( ScRange( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab(),
+ static_cast<SCCOL>(nLastCol), static_cast<SCROW>(nLastRow),
+ GetCurrScTab()), *pErgebnis );
+}
+
+
+void ImportExcel::Mulrk( void )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXF;
+ sal_Int32 nRkNum;
+
+ aIn >> aXclPos;
+
+ for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
+ {
+ aIn >> nXF >> nRkNum;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
+ {
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ GetDoc().PutCell( aScPos, new ScValueCell( XclTools::GetDoubleFromRK( nRkNum ) ) );
+ }
+ }
+}
+
+
+void ImportExcel::Mulblank( void )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXF;
+
+ aIn >> aXclPos;
+
+ for( XclAddress aCurrXclPos( aXclPos ); (aXclPos.mnCol <= aCurrXclPos.mnCol) && (aIn.GetRecLeft() > 2); ++aCurrXclPos.mnCol )
+ {
+ aIn >> nXF;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
+ GetXFRangeBuffer().SetBlankXF( aScPos, nXF );
+ }
+}
+
+
+void ImportExcel::Rstring( void )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nXFIdx;
+ aIn >> aXclPos >> nXFIdx;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
+ {
+ // unformatted Unicode string with separate formatting information
+ XclImpString aString;
+
+ // #i63105# use text encoding from FONT record
+ rtl_TextEncoding eOldTextEnc = GetTextEncoding();
+ if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
+ SetTextEncoding( pFont->GetFontEncoding() );
+ aString.Read( maStrm );
+ SetTextEncoding( eOldTextEnc );
+
+ // character formatting runs
+ if( !aString.IsRich() )
+ aString.ReadFormats( maStrm );
+
+ GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
+ if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( *this, aString, nXFIdx ) )
+ GetDoc().PutCell( aScPos, pCell );
+ }
+}
+
+
+void ImportExcel::Cellmerging()
+{
+ XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ SCTAB nScTab = GetCurrScTab();
+
+ sal_uInt16 nCount;
+ maStrm >> nCount;
+ for( sal_uInt16 nIdx = 0; (nIdx < nCount) && (maStrm.GetRecLeft() >= 8); ++nIdx )
+ {
+ XclRange aXclRange;
+ maStrm >> aXclRange; // 16-bit rows and columns
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( rAddrConv.ConvertRange( aScRange, aXclRange, nScTab, nScTab, true ) )
+ GetXFRangeBuffer().SetMerge( aScRange.aStart.Col(), aScRange.aStart.Row(), aScRange.aEnd.Col(), aScRange.aEnd.Row() );
+ }
+}
+
+
+void ImportExcel::Olesize( void )
+{
+ XclRange aXclOleSize( ScAddress::UNINITIALIZED );
+ maStrm.Ignore( 2 );
+ aXclOleSize.Read( maStrm, false );
+
+ SCTAB nScTab = GetCurrScTab();
+ GetAddressConverter().ConvertRange( maScOleSize, aXclOleSize, nScTab, nScTab, false );
+}
+
+
+void ImportExcel::Row34( void )
+{
+ sal_uInt16 nRow, nRowHeight, nGrbit, nXF;
+
+ aIn >> nRow;
+ aIn.Ignore( 4 ); // Mic und Mac ueberspringen
+
+ SCROW nScRow = static_cast< SCROW >( nRow );
+
+ if( ValidRow( nScRow ) )
+ {
+ aIn >> nRowHeight; // direkt in Twips angegeben
+ aIn.Ignore( 4 );
+
+ aIn >> nGrbit >> nXF;
+
+ sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+ pRowOutlineBuff->SetLevel( nScRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+ pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
+
+ if( nGrbit & EXC_ROW_USEDEFXF )
+ GetXFRangeBuffer().SetRowDefXF( nScRow, nXF & EXC_ROW_XFMASK );
+ }
+}
+
+
+void ImportExcel::Bof3( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ DBG_ASSERT( nSubType != 0x0100, "*ImportExcel::Bof3(): Biff3 als Workbook?!" );
+ if( nSubType == 0x0100 ) // Book
+ pExcRoot->eDateiTyp = Biff3W;
+ else if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff3C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff3M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff3;
+}
+
+
+void ImportExcel::Array34( void )
+{
+ sal_uInt16 nFirstRow, nLastRow, nFormLen;
+ sal_uInt8 nFirstCol, nLastCol;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol;
+ aIn.Ignore( (GetBiff() >= EXC_BIFF5) ? 6 : 2 );
+ aIn >> nFormLen;
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis;
+
+ pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
+ pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ DBG_ASSERT( pErgebnis, "+ImportExcel::Array34(): ScTokenArray ist NULL!" );
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( GetCurrScTab() );
+ pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
+ pErgebnis);
+ }
+}
+
+
+void ImportExcel::Externname34( void )
+{
+}
+
+
+void ImportExcel::Defrowheight345( void )
+{
+ sal_uInt16 nFlags, nDefHeight;
+ maStrm >> nFlags >> nDefHeight;
+ pColRowBuff->SetDefHeight( nDefHeight, nFlags );
+}
+
+
+void ImportExcel::TableOp( void )
+{
+ sal_uInt16 nFirstRow, nLastRow;
+ sal_uInt8 nFirstCol, nLastCol;
+ sal_uInt16 nGrbit;
+ sal_uInt16 nInpRow, nInpCol, nInpRow2, nInpCol2;
+
+ aIn >> nFirstRow >> nLastRow >> nFirstCol >> nLastCol >> nGrbit
+ >> nInpRow >> nInpCol >> nInpRow2 >> nInpCol2;
+
+ if( ValidColRow( nLastCol, nLastRow ) )
+ {
+ if( nFirstCol && nFirstRow )
+ {
+ ScTabOpParam aTabOpParam;
+ aTabOpParam.nMode = (nGrbit & EXC_TABLEOP_BOTH) ? 2 : ((nGrbit & EXC_TABLEOP_ROW) ? 1 : 0 );
+ sal_uInt16 nCol = nFirstCol - 1;
+ sal_uInt16 nRow = nFirstRow - 1;
+ SCTAB nTab = GetCurrScTab();
+ switch( aTabOpParam.nMode )
+ {
+ case 0: // COL
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol),
+ static_cast<SCROW>(nFirstRow - 1), nTab, false,
+ false, false );
+ aTabOpParam.aRefFormulaEnd.Set(
+ static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nFirstRow - 1), nTab, false,
+ false, false );
+ aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, false, false,
+ false );
+ nRow++;
+ break;
+ case 1: // ROW
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nFirstRow), nTab, false, false,
+ false );
+ aTabOpParam.aRefFormulaEnd.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nLastRow), nTab, false, false,
+ false );
+ aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, false, false,
+ false );
+ nCol++;
+ break;
+ case 2: // TWO-INPUT
+ aTabOpParam.aRefFormulaCell.Set(
+ static_cast<SCCOL>(nFirstCol - 1),
+ static_cast<SCROW>(nFirstRow - 1), nTab, false,
+ false, false );
+ aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
+ static_cast<SCROW>(nInpRow), nTab, false, false,
+ false );
+ aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol2),
+ static_cast<SCROW>(nInpRow2), nTab, false, false,
+ false );
+ break;
+ }
+
+ ScMarkData aMarkData;
+ aMarkData.SelectOneTable( nTab );
+ pD->InsertTableOp( aTabOpParam, static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), static_cast<SCCOL>(nLastCol),
+ static_cast<SCROW>(nLastRow), aMarkData );
+ }
+ }
+ else
+ {
+ bTabTruncated = sal_True;
+ GetTracer().TraceInvalidRow(GetCurrScTab(), nLastRow, MAXROW);
+ }
+}
+
+
+void ImportExcel::Bof4( void )
+{
+ sal_uInt16 nSubType;
+ maStrm.DisableDecryption();
+ maStrm.Ignore( 2 );
+ maStrm >> nSubType;
+
+ if( nSubType == 0x0100 ) // Book
+ pExcRoot->eDateiTyp = Biff4W;
+ else if( nSubType == 0x0020 ) // Chart
+ pExcRoot->eDateiTyp = Biff4C;
+ else if( nSubType == 0x0040 ) // Macro
+ pExcRoot->eDateiTyp = Biff4M;
+ else // #i51490# Excel interprets invalid indexes as worksheet
+ pExcRoot->eDateiTyp = Biff4;
+}
+
+
+void ImportExcel::Bof5( void )
+{
+ //POST: eDateiTyp = Typ der zu lesenden Datei
+ sal_uInt16 nSubType, nVers;
+ BiffTyp eDatei;
+
+ maStrm.DisableDecryption();
+ maStrm >> nVers >> nSubType;
+
+ switch( nSubType )
+ {
+ case 0x0005: eDatei = Biff5W; break; // workbook globals
+ case 0x0006: eDatei = Biff5V; break; // VB module
+ case 0x0010: eDatei = Biff5; break; // worksheet
+ case 0x0020: eDatei = Biff5C; break; // chart
+ case 0x0040: eDatei = Biff5M4; break; // macro sheet
+ default:
+ pExcRoot->eDateiTyp = BiffX;
+ return;
+ }
+
+ if( nVers == 0x0600 && (GetBiff() == EXC_BIFF8) )
+ eDatei = ( BiffTyp ) ( eDatei - Biff5 + Biff8 );
+
+ pExcRoot->eDateiTyp = eDatei;
+}
+
+void ImportExcel::EndSheet( void )
+{
+ pExcRoot->pExtSheetBuff->Reset();
+
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ pExcRoot->pExtNameBuff->Reset();
+ mnLastRefIdx = 0;
+ }
+
+ FinalizeTable();
+}
+
+
+void ImportExcel::NeueTabelle( void )
+{
+ SCTAB nTab = GetCurrScTab();
+ if( nTab > 0 && !pD->HasTable( nTab ) )
+ pD->MakeTable( nTab );
+
+ if (nTab == 0 && GetBiff() == EXC_BIFF2)
+ {
+ // For Excel 2.1 Worksheet file, we need to set the file name as the
+ // sheet name.
+ INetURLObject aURL(GetDocUrl());
+ pD->RenameTab(0, aURL.getBase(), false);
+ }
+
+ pExcRoot->pShrfmlaBuff->Clear();
+
+ InitializeTable( nTab );
+
+ XclImpOutlineDataBuffer* pNewItem = new XclImpOutlineDataBuffer( GetRoot(), nTab );
+ pOutlineListBuffer->push_back( pNewItem );
+ pExcRoot->pColRowBuff = pColRowBuff = pNewItem->GetColRowBuff();
+ pColOutlineBuff = pNewItem->GetColOutline();
+ pRowOutlineBuff = pNewItem->GetRowOutline();
+}
+
+
+const ScTokenArray* ImportExcel::ErrorToFormula( sal_uInt8 bErrOrVal, sal_uInt8 nError, double& rVal )
+{
+ return pFormConv->GetBoolErr( XclTools::ErrorToEnum( rVal, bErrOrVal, nError ) );
+}
+
+
+void ImportExcel::AdjustRowHeight()
+{
+ /* Speed up chart import: import all sheets without charts, then
+ update row heights (here), last load all charts -> do not any longer
+ update inside of ScDocShell::ConvertFrom() (causes update of existing
+ charts during each and every change of row height). */
+ if( ScModelObj* pDocObj = GetDocModelObj() )
+ pDocObj->UpdateAllRowHeights();
+}
+
+
+void ImportExcel::PostDocLoad( void )
+{
+ /* Set automatic page numbering in Default page style (default is "page number = 1").
+ Otherwise hidden tables (i.e. for scenarios) which have Default page style will
+ break automatic page numbering. */
+ if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PAGE ) )
+ pStyleSheet->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 0 ) );
+
+ // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
+ for (XclImpOutlineListBuffer::iterator itBuffer = pOutlineListBuffer->begin(); itBuffer != pOutlineListBuffer->end(); ++itBuffer)
+ itBuffer->Convert();
+
+ // document view settings (before visible OLE area)
+ GetDocViewSettings().Finalize();
+
+ // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
+ GetObjectManager().ConvertObjects();
+
+ // visible area (used if this document is an embedded OLE object)
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ // visible area if embedded
+ const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings();
+ SCTAB nDisplScTab = rDocSett.mnDisplTab;
+
+ /* #i44077# If a new OLE object is inserted from file, there is no
+ OLESIZE record in the Excel file. Calculate used area from file
+ contents (used cells and drawing objects). */
+ if( !maScOleSize.IsValid() )
+ {
+ // used area of displayed sheet (cell contents)
+ if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) )
+ maScOleSize = pTabSett->maUsedArea;
+ // add all valid drawing objects
+ ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab );
+ if( aScObjArea.IsValid() )
+ maScOleSize.ExtendTo( aScObjArea );
+ }
+
+ // valid size found - set it at the document
+ if( maScOleSize.IsValid() )
+ {
+ pDocShell->SetVisArea( GetDoc().GetMMRect(
+ maScOleSize.aStart.Col(), maScOleSize.aStart.Row(),
+ maScOleSize.aEnd.Col(), maScOleSize.aEnd.Row(), nDisplScTab ) );
+ GetDoc().SetVisibleTab( nDisplScTab );
+ }
+ }
+
+ // open forms in alive mode (has no effect, if no controls in document)
+ if( ScModelObj* pDocObj = GetDocModelObj() )
+ pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), uno::Any( false ) );
+
+ // enables extended options to be set to the view after import
+ GetExtDocOptions().SetChanged( true );
+
+ // root data owns the extended document options -> create a new object
+ GetDoc().SetExtDocOptions( new ScExtDocOptions( GetExtDocOptions() ) );
+
+ const SCTAB nLast = pD->GetTableCount();
+ const ScRange* p;
+
+ if( pExcRoot->pPrintRanges->HasRanges() )
+ {
+ for( SCTAB n = 0 ; n < nLast ; n++ )
+ {
+ p = pExcRoot->pPrintRanges->First(n);
+ if( p )
+ {
+ pD->ClearPrintRanges( n );
+ while( p )
+ {
+ pD->AddPrintRange( n, *p );
+ p = pExcRoot->pPrintRanges->Next();
+ }
+ }
+ else
+ {
+ // #i4063# no print ranges -> print entire sheet
+ pD->SetPrintEntireSheet( n );
+ }
+ }
+ GetTracer().TracePrintRange();
+ }
+
+ if( pExcRoot->pPrintTitles->HasRanges() )
+ {
+ for( SCTAB n = 0 ; n < nLast ; n++ )
+ {
+ p = pExcRoot->pPrintTitles->First(n);
+ if( p )
+ {
+ sal_Bool bRowVirgin = sal_True;
+ sal_Bool bColVirgin = sal_True;
+
+ while( p )
+ {
+ if( p->aStart.Col() == 0 && p->aEnd.Col() == MAXCOL && bRowVirgin )
+ {
+ pD->SetRepeatRowRange( n, p );
+ bRowVirgin = false;
+ }
+
+ if( p->aStart.Row() == 0 && p->aEnd.Row() == MAXROW && bColVirgin )
+ {
+ pD->SetRepeatColRange( n, p );
+ bColVirgin = false;
+ }
+
+ p = pExcRoot->pPrintTitles->Next();
+ }
+ }
+ }
+ }
+}
+
+XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab ) :
+ XclImpRoot( rRoot ),
+ mxColOutlineBuff( new XclImpOutlineBuffer( MAXCOLCOUNT ) ),
+ mxRowOutlineBuff( new XclImpOutlineBuffer( MAXROWCOUNT ) ),
+ mxColRowBuff( new XclImpColRowSettings( rRoot ) ),
+ mnScTab( nScTab )
+{
+}
+
+XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
+{
+}
+
+void XclImpOutlineDataBuffer::Convert()
+{
+ mxColOutlineBuff->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab, sal_True )->GetColArray() );
+ mxColOutlineBuff->MakeScOutline();
+
+ mxRowOutlineBuff->SetOutlineArray( GetDoc().GetOutlineTable( mnScTab, sal_True )->GetRowArray() );
+ mxRowOutlineBuff->MakeScOutline();
+
+ mxColRowBuff->ConvertHiddenFlags( mnScTab );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
new file mode 100644
index 000000000000..fe388a218e95
--- /dev/null
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "namebuff.hxx"
+
+#include <tools/urlobj.hxx>
+#include <string.h>
+
+#include "rangenam.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "scextopt.hxx"
+
+#include "root.hxx"
+#include "tokstack.hxx"
+#include "xltools.hxx"
+#include "xiroot.hxx"
+
+
+sal_uInt32 StringHashEntry::MakeHashCode( const String& r )
+{
+ register sal_uInt32 n = 0;
+ const sal_Unicode* pAkt = r.GetBuffer();
+ register sal_Unicode cAkt = *pAkt;
+
+ while( cAkt )
+ {
+ n *= 70;
+ n += ( sal_uInt32 ) cAkt;
+ pAkt++;
+ cAkt = *pAkt;
+ }
+
+ return n;
+}
+
+
+
+
+NameBuffer::~NameBuffer()
+{
+ register StringHashEntry* pDel = ( StringHashEntry* ) List::First();
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( StringHashEntry* ) List::Next();
+ }
+}
+
+
+//void NameBuffer::operator <<( const SpString &rNewString )
+void NameBuffer::operator <<( const String &rNewString )
+{
+ DBG_ASSERT( Count() + nBase < 0xFFFF,
+ "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
+
+ List::Insert( new StringHashEntry( rNewString ), LIST_APPEND );
+}
+
+
+#ifdef DBG_UTIL
+sal_uInt16 nShrCnt;
+#endif
+
+
+size_t ShrfmlaBuffer::ScAddressHashFunc::operator() (const ScAddress &addr) const
+{
+ // Use something simple, it is just a hash.
+ return static_cast< sal_uInt16 >( addr.Row() ) | (static_cast< sal_uInt8 >( addr.Col() ) << 16);
+}
+
+const size_t nBase = 16384; // Range~ und Shared~ Dingens mit jeweils der Haelfte Ids
+ShrfmlaBuffer::ShrfmlaBuffer( RootData* pRD ) :
+ ExcRoot( pRD ),
+ mnCurrIdx (nBase)
+{
+#ifdef DBG_UTIL
+ nShrCnt = 0;
+#endif
+}
+
+ShrfmlaBuffer::~ShrfmlaBuffer()
+{
+}
+
+void ShrfmlaBuffer::Clear()
+{
+ index_hash.clear();
+ // do not clear index_list, index calculation depends on complete list size...
+ // do not change mnCurrIdx
+}
+
+void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
+{
+ String aName( CreateName( rRange.aStart ) );
+
+ DBG_ASSERT( mnCurrIdx <= 0xFFFF, "*ShrfmlaBuffer::Store(): Gleich wird mir schlecht...!" );
+
+ ScRangeData* pData = new ScRangeData( pExcRoot->pIR->GetDocPtr(), aName, rToken, rRange.aStart, RT_SHARED );
+ const ScAddress& rMaxPos = pExcRoot->pIR->GetMaxPos();
+ pData->SetMaxCol(rMaxPos.Col());
+ pData->SetMaxRow(rMaxPos.Row());
+ pData->SetIndex( static_cast< sal_uInt16 >( mnCurrIdx ) );
+ pExcRoot->pIR->GetNamedRanges().insert( pData );
+ index_hash[rRange.aStart] = static_cast< sal_uInt16 >( mnCurrIdx );
+ index_list.push_front (rRange);
+ ++mnCurrIdx;
+}
+
+
+sal_uInt16 ShrfmlaBuffer::Find( const ScAddress & aAddr ) const
+{
+ ShrfmlaHash::const_iterator hash = index_hash.find (aAddr);
+ if (hash != index_hash.end())
+ return hash->second;
+
+ // It was not hashed on the top left corner ? do a brute force search
+ unsigned int ind = nBase;
+ for (ShrfmlaList::const_iterator ptr = index_list.end(); ptr != index_list.begin() ; ind++)
+ if ((--ptr)->In (aAddr))
+ return static_cast< sal_uInt16 >( ind );
+ return static_cast< sal_uInt16 >( mnCurrIdx );
+}
+
+
+#define SHRFMLA_BASENAME "SHARED_FORMULA_"
+
+String ShrfmlaBuffer::CreateName( const ScRange& r )
+{
+ String aName( RTL_CONSTASCII_USTRINGPARAM( SHRFMLA_BASENAME ) );
+ aName += String::CreateFromInt32( r.aStart.Col() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aStart.Row() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aEnd.Col() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aEnd.Row() );
+ aName.Append( '_' );
+ aName += String::CreateFromInt32( r.aStart.Tab() );
+
+ return aName;
+}
+
+
+ExtSheetBuffer::~ExtSheetBuffer()
+{
+ Cont *pAkt = ( Cont * ) List::First();
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( Cont * ) List::Next();
+ }
+}
+
+
+sal_Int16 ExtSheetBuffer::Add( const String& rFPAN, const String& rTN, const sal_Bool bSWB )
+{
+ List::Insert( new Cont( rFPAN, rTN, bSWB ), LIST_APPEND );
+ // return 1-based index of EXTERNSHEET
+ return static_cast< sal_Int16 >( List::Count() );
+}
+
+
+sal_Bool ExtSheetBuffer::GetScTabIndex( sal_uInt16 nExcIndex, sal_uInt16& rScIndex )
+{
+ DBG_ASSERT( nExcIndex,
+ "*ExtSheetBuffer::GetScTabIndex(): Sheet-Index == 0!" );
+
+ nExcIndex--;
+ Cont* pCur = ( Cont * ) List::GetObject( nExcIndex );
+ sal_uInt16& rTabNum = pCur->nTabNum;
+
+ if( pCur )
+ {
+ if( rTabNum < 0xFFFD )
+ {
+ rScIndex = rTabNum;
+ return sal_True;
+ }
+
+ if( rTabNum == 0xFFFF )
+ {// neue Tabelle erzeugen
+ SCTAB nNewTabNum;
+ if( pCur->bSWB )
+ {// Tabelle ist im selben Workbook!
+ if( pExcRoot->pIR->GetDoc().GetTable( pCur->aTab, nNewTabNum ) )
+ {
+ rScIndex = rTabNum = static_cast<sal_uInt16>(nNewTabNum);
+ return sal_True;
+ }
+ else
+ rTabNum = 0xFFFD;
+ }
+ else if( pExcRoot->pIR->GetDocShell() )
+ {// Tabelle ist 'echt' extern
+ if( pExcRoot->pIR->GetExtDocOptions().GetDocSettings().mnLinkCnt == 0 )
+ {
+ String aURL( ScGlobal::GetAbsDocName( pCur->aFile,
+ pExcRoot->pIR->GetDocShell() ) );
+ String aTabName( ScGlobal::GetDocTabName( aURL, pCur->aTab ) );
+ if( pExcRoot->pIR->GetDoc().LinkExternalTab( nNewTabNum, aTabName, aURL, pCur->aTab ) )
+ {
+ rScIndex = rTabNum = static_cast<sal_uInt16>(nNewTabNum);
+ return sal_True;
+ }
+ else
+ rTabNum = 0xFFFE; // Tabelle einmal nicht angelegt -> wird
+ // wohl auch nicht mehr gehen...
+ }
+ else
+ rTabNum = 0xFFFE;
+
+ }
+ }
+ }
+
+ return false;
+}
+
+
+sal_Bool ExtSheetBuffer::IsLink( const sal_uInt16 nExcIndex ) const
+{
+ DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::IsLink(): Index muss >0 sein!" );
+ Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
+
+ if( pRet )
+ return pRet->bLink;
+ else
+ return false;
+}
+
+
+sal_Bool ExtSheetBuffer::GetLink( const sal_uInt16 nExcIndex, String& rAppl, String& rDoc ) const
+{
+ DBG_ASSERT( nExcIndex > 0, "*ExtSheetBuffer::GetLink(): Index muss >0 sein!" );
+ Cont* pRet = ( Cont * ) List::GetObject( nExcIndex - 1 );
+
+ if( pRet )
+ {
+ rAppl = pRet->aFile;
+ rDoc = pRet->aTab;
+ return sal_True;
+ }
+ else
+ return false;
+}
+
+
+void ExtSheetBuffer::Reset( void )
+{
+ Cont *pAkt = ( Cont * ) List::First();
+ while( pAkt )
+ {
+ delete pAkt;
+ pAkt = ( Cont * ) List::Next();
+ }
+
+ List::Clear();
+}
+
+
+
+
+sal_Bool ExtName::IsDDE( void ) const
+{
+ return ( nFlags & 0x0001 ) != 0;
+}
+
+
+sal_Bool ExtName::IsOLE( void ) const
+{
+ return ( nFlags & 0x0002 ) != 0;
+}
+
+
+ExtNameBuff::ExtNameBuff( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+
+void ExtNameBuff::AddDDE( const String& rName, sal_Int16 nRefIdx )
+{
+ ExtName aNew( rName, 0x0001 );
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+void ExtNameBuff::AddOLE( const String& rName, sal_Int16 nRefIdx, sal_uInt32 nStorageId )
+{
+ ExtName aNew( rName, 0x0002 );
+ aNew.nStorageId = nStorageId;
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+void ExtNameBuff::AddName( const String& rName, sal_Int16 nRefIdx )
+{
+ ExtName aNew( GetScAddInName( rName ), 0x0004 );
+ maExtNames[ nRefIdx ].push_back( aNew );
+}
+
+
+const ExtName* ExtNameBuff::GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const
+{
+ DBG_ASSERT( nNameIdx > 0, "ExtNameBuff::GetNameByIndex() - invalid name index" );
+ ExtNameMap::const_iterator aIt = maExtNames.find( nRefIdx );
+ return ((aIt != maExtNames.end()) && (0 < nNameIdx) && (nNameIdx <= aIt->second.size())) ? &aIt->second[ nNameIdx - 1 ] : 0;
+}
+
+
+void ExtNameBuff::Reset( void )
+{
+ maExtNames.clear();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/ooxml-export-TODO.txt b/sc/source/filter/excel/ooxml-export-TODO.txt
new file mode 100644
index 000000000000..5b04efb97007
--- /dev/null
+++ b/sc/source/filter/excel/ooxml-export-TODO.txt
@@ -0,0 +1,148 @@
+TODO/Unimplemented Calc OOXML Export Features:
+=============================================
+
+Partially implemented features are not mentioned here; grep for OOXTODO within
+sc/source/filter/*.
+
+In updated OfficeFileFormatsProtocols.zip [MS-XLS].pdf,
+Section §2.3.1 (p.154) provides the record name :: record number mapping, and
+Section §2.3.2 (p.165) provides the record number :: record name mapping.
+
+Elements:
+ - Workbook (§3.2):
+ - customWorkbookViews (§3.2.3)
+ - ext (§3.2.7)
+ - externalReference (§3.2.8)
+ - externalReferences (§3.2.9)
+ - extLst (§3.2.10)
+ - fileRecoveryPr (§3.2.11) [ CRASHRECERR? 865h ]
+ - fileSharing (§3.2.12) [ FILESHARING 5Bh ]
+ - functionGroup (§3.2.14) [ FNGRP12 898h; FNGROUPNAME 9Ah ]
+ - functionGroups (§3.2.15) [ FNGROUPCOUNT: 9Ch ]
+ - oleSize (§3.2.16) [ OLESIZE DEh ]
+ - smartTagPr (§3.2.21) [ BOOKEXT 863h ]
+ - smartTagType (§3.2.22) [ unknown record ]
+ - smartTagTypes (§3.2.23) [ unknown record ]
+ - webPublishing (§3.2.24) [ WOPT 80Bh ]
+ - webPublishObject (§3.2.25) [ WEBPUB 801h ]
+ - webPublishObjects (§3.2.26) [ unsupported ]
+ - Worksheets (§3.3.1):
+ - autoFilter (§3.3.1.1) [ AutoFilter 9Eh ]
+ - cellSmartTag (§3.3.1.4) [ FEAT 868h ]
+ - cellSmartTagPr (§3.3.1.5) [ FEAT? 868h ]
+ - cellSmartTags (§3.3.1.6) [ FEAT 868h ]
+ - cellWatch (§3.3.1.7) [ CELLWATCH 86Ch ]
+ - cellWatches (§3.3.1.8) [ CELLWATCH 86Ch ]
+ - cfRule (§3.3.1.9) [ CF 1B1h ]
+ - cfvo (§3.3.1.10) [ CF12 87Ah ]
+ - chartsheet (§3.3.1.11) [ CHARTFRTINFO 850h, FRTWRAPPER 851h...]
+ - color (§3.3.1.14) [ DXF 88Dh xfpropBorder?
+ XFEXT 87Dh xclrType? ]
+ - colorScale (§3.3.1.15) [ DXF 88Dh? ]
+ - control (§3.3.1.18) [ ??? ]
+ - controls (§3.3.1.19) [ ??? ]
+ - customPr (§3.3.1.20) [ ??? ]
+ - customProperties (§3.3.1.21) [ ??? ]
+ - customSheetView (§3.3.1.22) [ ???; for charts; see chartsheet? ]
+ - customSheetView (§3.3.1.23) [ ??? ]
+ - customSheetViews (§3.3.1.24) [ ???; for charts; see chartsheet? ]
+ - customSheetViews (§3.3.1.25) [ ??? ]
+ - dataBar (§3.3.1.26) [ CF12 87Ah ct=Databar ]
+ - dataConsolidate (§3.3.1.27) [ DCON 50h ]
+ - dataRef (§3.3.1.28) [ DCONBIN 1B5h ]
+ - dataRefs (§3.3.1.29) [ ??? ]
+ - dialogsheet (§3.3.1.32) [ ??? ]
+ - drawing (§3.3.1.34) [ ??? ]
+ - evenFooter (§3.3.1.35) [ HeaderFooter 89Ch ]
+ - evenHeader (§3.3.1.36) [ HeaderFooter 89Ch ]
+ - firstFooter (§3.3.1.38) [ HeaderFooter 89Ch ]
+ - firstHeader (§3.3.1.39) [ HeaderFooter 89Ch ]
+ - formula (§3.3.1.40) [ CF 1B1h ]
+ - iconSet (§3.3.1.46) [ CF12 87Ah ct=CFMultistate ]
+ - ignoredError (§3.3.1.47) [ Feat/FeatForumulaErr2/FFErrorCheck 868h ]
+ - ignoredErrors (§3.3.1.48) [ Feat 868h ]
+ - legacyDrawing (§3.3.1.51) [ MsoDrawing ECh ]
+ - legacyDrawingHF (§3.3.1.52) [ ??? ]
+ - oleObject (§3.3.1.57) [ ??? ]
+ - oleObjects (§3.3.1.58) [ ??? ]
+ - outlinePr (§3.3.1.59) [ ??? ]
+ - pageSetup (§3.3.1.62) [ ???; for charts; see chartsheet? ]
+ - picture (§3.3.1.65) [ BkHim E9h; see XclExpBitmap ]
+ - pivotArea (§3.3.1.66) [ ??? ]
+ - pivotSelection (§3.3.1.67) [ ??? ]
+ - protectedRange (§3.3.1.69) [ ??? ]
+ - protectedRanges (§3.3.1.70) [ ??? ]
+ - sheetCalcPr (§3.3.1.76) [ REFRESHALL?? ]
+ - sheetFormatPr (§3.3.1.78) [ lots of records? ]
+ @defaultColWidth: DefColWidth
+ @defaultRowHeight: DEFROWHEIGHT
+ @baseColWidth: ColInfo/coldx?
+ @customHeight: ColInfo/fUserSet?
+ @zeroHeight: ColInfo/fHidden?
+ @thickTop: ?
+ @thickBottom: ?
+ @outlineLevelRow: ?
+ @outlineLevelCol: ColInfo/iOutLevel?
+ - sheetPr (§3.3.1.80) [ ??? ; for charts ]
+ - sheetView (§3.3.1.84) [ ??? ; for charts ]
+ - sheetViews (§3.3.1.86) [ ??? ; for charts ]
+ - smartTags (§3.3.1.87) [ FEAT 868h; isf=ISFFACTOID ]
+ - sortCondition (§3.3.1.88) [ SortData 895h? ]
+ - sortState (§3.3.1.89) [ Sort 90h ]
+ - tabColor (§3.3.1.90) [ SheetExt 862h ]
+ - tablePart (§3.3.1.91) [ ??? ]
+ - tableParts (§3.3.1.92) [ ??? ]
+ - webPublishItem (§3.3.1.94) [ WebPub 801h ]
+ - webPublishItems (§3.3.1.95)
+ - AutoFilter Settings (§3.3.2):
+ - colorFilter (§3.3.2.1) [ AutoFilter12 87Eh,
+ DXFN12NoCB struct ]
+ - dateGroupItem (§3.3.2.4) [ AutoFilter12 87Eh,
+ AF12DateInfo struct ]
+ - dynamicFilter (§3.3.2.5) [ AutoFilter12 87Eh, cft field ]
+ - filter (§3.3.2.6) [ AutoFilter12 87Eh, rgCriteria? ]
+ - filters (§3.3.2.9) [ AutoFilter12 87Eh, rgCriteria? ]
+ - iconFilter (§3.3.2.9) [ AutoFilter12 87Eh,
+ AF12CellIcon struct ]
+ - Shared String Table (§3.4):
+ - phoneticPr (§3.4.3)
+ - rPh (§3.4.6)
+ - Tables (§3.5.1):
+ - calculatedColumnFormula (§3.5.1.1)
+ [ ??? ]
+ - table (§3.5.1.2) [ ??? ]
+ - tableColumn (§3.5.1.3) [ ??? ]
+ - tableColumns (§3.5.1.4) [ ??? ]
+ - tableStyleInfo (§3.5.1.5) [ ??? ]
+ - totalRowFormula (§3.5.1.6) [ ??? ]
+ - xmlColumnPr (§3.5.1.7) [ ??? ]
+ - Single Cell Tables (§3.5.2):
+ - singleXmlCell (§3.5.2.1) [ ??? ]
+ - singleXmlCells (§3.5.2.2) [ ??? ]
+ - xmlCellPr (§3.5.2.3) [ ??? ]
+ - xmlPr (§3.5.2.4) [ ??? ]
+ - Calculation Chain (§3.6):
+ - c (§3.6.1) [ ??? ]
+ - calcChain (§3.6.2) [ ??? ]
+ - Comments (§3.7):
+ - Note: Excel *requires* that there be a drawing object associated
+ with the comment before it will show it. If you _just_ generate the
+ <comments/> XML part and create a <Relationship/> for it, Excell
+ will NOT display the comment.
+ - As drawing is not currently implemented, comments support is
+ incomplete.
+ - TODO: text formatting. Currently we only write unformatted text
+ into comments?.xml, as I'm not sure how formatted text is handled.
+ - Styles (§3.8):
+ - dxf (§3.8.14): [ DXF 88Dh; unsupported ]
+ - dxfs (§3.8.15): [ DXF 88Dh ]
+ - gradientFill (§3.8.23): [ ??? ]
+ - horizontal (§3.8.24): [ DXF 88Dh fNewBorder, xfprops ]
+ - mruColors (§3.8.28): [ ??? ]
+ - scheme (§3.8.36): [ ??? ]
+ - stop (§3.8.38): [ ??? ]
+ - tableStyle (§3.8.40): [ TableStyle 88Fh; unsupported ]
+ - tableStyleElement (§3.8.41): [ TableStyleElement 890h; unsupported ]
+ - tableStyles (§3.8.42): [ TableStyles 88Eh; unsupported ]
+ - vertical (§3.8.44): [ DXF 88Dh fNewBorder, xfprops ]
+
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
new file mode 100644
index 000000000000..96e68a9df01f
--- /dev/null
+++ b/sc/source/filter/excel/read.cxx
@@ -0,0 +1,1307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "document.hxx"
+#include "scerrors.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xltable.hxx"
+#include "xihelper.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+#include "xicontent.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+#include "XclImpChangeTrack.hxx"
+
+#include "root.hxx"
+#include "imp_op.hxx"
+#include "excimp8.hxx"
+
+FltError ImportExcel::Read( void )
+{
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+ XclImpPalette& rPal = GetPalette();
+ XclImpFontBuffer& rFontBfr = GetFontBuffer();
+ XclImpNumFmtBuffer& rNumFmtBfr = GetNumFmtBuffer();
+ XclImpXFBuffer& rXFBfr = GetXFBuffer();
+ XclImpNameManager& rNameMgr = GetNameManager();
+ XclImpObjectManager& rObjMgr = GetObjectManager();
+ (void)rObjMgr;
+ // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
+
+ enum Zustand {
+ Z_BiffNull, // Nicht in gueltigem Biff-Format
+ Z_Biff2, // Biff2: nur eine Tabelle
+
+ Z_Biff3, // Biff3: nur eine Tabelle
+
+ Z_Biff4, // Biff4: nur eine Tabelle
+ Z_Biff4W, // Biff4 Workbook: Globals
+ Z_Biff4T, // Biff4 Workbook: eine Tabelle selbst
+ Z_Biff4E, // Biff4 Workbook: zwischen den Tabellen
+
+ Z_Biff5WPre,// Biff5: Prefetch Workbook
+ Z_Biff5W, // Biff5: Globals
+ Z_Biff5TPre,// Biff5: Prefetch fuer Shrfmla/Array Formula
+ Z_Biff5T, // Biff5: eine Tabelle selbst
+ Z_Biff5E, // Biff5: zwischen den Tabellen
+ Z_Biffn0, // Alle Biffs: Tabelle bis naechstesss EOF ueberlesen
+ Z_Ende };
+
+ Zustand eAkt = Z_BiffNull, ePrev = Z_BiffNull;
+
+ FltError eLastErr = eERR_OK;
+ sal_uInt16 nOpcode;
+ sal_uInt16 nBofLevel = 0;
+
+ DBG_ASSERT( &aIn != NULL, "-ImportExcel::Read(): Kein Stream - wie dass?!" );
+
+ ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
+ aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
+
+ /* #i104057# Need to track a base position for progress bar calculation,
+ because sheet substreams may not be in order of sheets. */
+ sal_Size nProgressBasePos = 0;
+ sal_Size nProgressBaseSize = 0;
+
+ while( eAkt != Z_Ende )
+ {
+ if( eAkt == Z_Biff5E )
+ {
+ sal_uInt16 nScTab = GetCurrScTab();
+ if( nScTab < maSheetOffsets.size() )
+ {
+ nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
+ nProgressBasePos = maSheetOffsets[ nScTab ];
+ aIn.StartNextRecord( nProgressBasePos );
+ }
+ else
+ eAkt = Z_Ende;
+ }
+ else
+ aIn.StartNextRecord();
+
+ nOpcode = aIn.GetRecId();
+
+ if( !aIn.IsValid() )
+ {
+ // finalize table if EOF is missing
+ switch( eAkt )
+ {
+ case Z_Biff2:
+ case Z_Biff3:
+ case Z_Biff4:
+ case Z_Biff4T:
+ case Z_Biff5TPre:
+ case Z_Biff5T:
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ break;
+ default:;
+ };
+ eAkt = Z_Ende;
+ break;
+ }
+
+ if( eAkt == Z_Ende )
+ break;
+
+ if( eAkt != Z_Biff5TPre && eAkt != Z_Biff5WPre )
+ pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
+
+ switch( eAkt )
+ {
+ // ----------------------------------------------------------------
+ case Z_BiffNull: // ------------------------------- Z_BiffNull -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF:
+ {
+ // #i23425# don't rely on the record ID, but on the detected BIFF version
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ Bof2();
+ if( pExcRoot->eDateiTyp == Biff2 )
+ {
+ eAkt = Z_Biff2;
+ NeueTabelle();
+ }
+ break;
+ case EXC_BIFF3:
+ Bof3();
+ if( pExcRoot->eDateiTyp == Biff3 )
+ {
+ eAkt = Z_Biff3;
+ NeueTabelle();
+ }
+ break;
+ case EXC_BIFF4:
+ Bof4();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4;
+ NeueTabelle();
+ }
+ else if( pExcRoot->eDateiTyp == Biff4W )
+ eAkt = Z_Biff4W;
+ break;
+ case EXC_BIFF5:
+ Bof5();
+ if( pExcRoot->eDateiTyp == Biff5W )
+ {
+ eAkt = Z_Biff5WPre;
+
+ nBdshtTab = 0;
+
+ aIn.StoreGlobalPosition(); // und Position merken
+ }
+ else if( pExcRoot->eDateiTyp == Biff5 )
+ {
+ // #i62752# possible to have BIFF5 sheet without globals
+ NeueTabelle();
+ eAkt = Z_Biff5TPre; // Shrfmla Prefetch, Row-Prefetch
+ nBofLevel = 0;
+ aIn.StoreGlobalPosition(); // und Position merken
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+ break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff2: // ---------------------------------- Z_Biff2 -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x06: Formula25(); break; // FORMULA [ 2 5]
+ case 0x08: Row25(); break; // ROW [ 2 5]
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x18: rNameMgr.ReadName( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x20: Columndefault(); break; // COLUMNDEFAULT[ 2 ]
+ case 0x21: Array25(); break; // ARRAY [ 2 5]
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x24: Colwidth(); break; // COLWIDTH [ 2 ]
+ case 0x25: Defrowheight2(); break; // DEFAULTROWHEI[ 2 ]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break;
+ case EXC_ID_EFONT: rFontBfr.ReadEfont( maStrm ); break;
+ case 0x3E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x43: rXFBfr.ReadXF( maStrm ); break;
+ case 0x44: Ixfe(); break; // IXFE [ 2 ]
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff3: // ---------------------------------- Z_Biff3 -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x0206: Formula3(); break; // FORMULA [ 3 ]
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0243: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4: // ---------------------------------- Z_Biff4 -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ Eof();
+ eAkt = Z_Ende;
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0406: Formula4(); break; // FORMULA [ 4 ]
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4W: // --------------------------------- Z_Biff4W -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Ende;
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5]
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x0409: // BOF [ 4 ]
+ Bof4();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4T;
+ NeueTabelle();
+ }
+ else
+ eAkt = Z_Ende;
+ break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4T: // --------------------------------- Z_Biff4T -
+ {
+ switch( nOpcode )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0A: // EOF [ 2345]
+ Eof();
+ eAkt = Z_Biff4E;
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ]
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0218: rNameMgr.ReadName( maStrm ); break;
+ case 0x0221: Array34(); break;
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x0231: rFontBfr.ReadFont( maStrm ); break;
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x0406: Formula4(); break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x0443: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff4E: // --------------------------------- Z_Biff4E -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Ende;
+ break;
+ case 0x8F: break; // BUNDLEHEADER [ 4 ]
+ case 0x0409: // BOF [ 4 ]
+ Bof4();
+ NeueTabelle();
+ if( pExcRoot->eDateiTyp == Biff4 )
+ {
+ eAkt = Z_Biff4T;
+ }
+ else
+ {
+ ePrev = eAkt;
+ eAkt = Z_Biffn0;
+ }
+ break;
+ }
+
+ }
+ break;
+ case Z_Biff5WPre: // ------------------------------ Z_Biff5WPre -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Biff5W;
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5]
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x3D: Window1(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x85: Boundsheet(); break; // BOUNDSHEET [ 5]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ // PALETTE follows XFs, but already needed while reading the XFs
+ case 0x92: rPal.ReadPalette( maStrm ); break;
+ }
+ }
+ break;
+ case Z_Biff5W: // --------------------------------- Z_Biff5W -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ rNumFmtBfr.CreateScFormats();
+ rXFBfr.CreateUserStyles();
+ eAkt = Z_Biff5E;
+ break;
+ case 0x18: rNameMgr.ReadName( maStrm ); break;
+ case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case 0x22: Rec1904(); break; // 1904 [ 2345]
+ case 0x31: rFontBfr.ReadFont( maStrm ); break;
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8D: Hideobj(); break; // HIDEOBJ [ 345]
+ case 0xDE: Olesize(); break;
+ case 0xE0: rXFBfr.ReadXF( maStrm ); break;
+ case 0x0293: rXFBfr.ReadStyle( maStrm ); break;
+ case 0x041E: rNumFmtBfr.ReadFormat( maStrm ); break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5TPre: // ------------------------------- Z_Biff5Pre -
+ {
+ if( nOpcode == 0x0809 )
+ nBofLevel++;
+ else if( (nOpcode == 0x000A) && nBofLevel )
+ nBofLevel--;
+ else if( !nBofLevel ) // don't read chart records
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+ case 0x08: Row25(); break; // ROW [ 2 5]
+ case 0x0A: // EOF [ 2345]
+ eAkt = Z_Biff5T;
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
+ case 0x1A:
+ case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x21: Array25(); break; // ARRAY [ 2 5]
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x41: rTabViewSett.ReadPane( maStrm ); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345]
+ case 0x55: DefColWidth(); break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345]
+ case 0x81: Wsbool(); break; // WSBOOL [ 2345]
+ case 0x8C: Country(); break; // COUNTRY [ 345]
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45]
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0223: Externname34(); break; // EXTERNNAME [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345]
+ case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5]
+ }
+ }
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5T: // --------------------------------- Z_Biff5T -
+ {
+ switch( nOpcode )
+ {
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0006:
+ case 0x0206:
+ case 0x0406: Formula25(); break;
+ case 0x0A: Eof(); eAkt = Z_Biff5E; break;
+ case 0x14:
+ case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
+ case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break;
+ case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
+ case 0x23: Externname25(); break; // EXTERNNAME [ 2 5]
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29: rPageSett.ReadMargin( maStrm ); break;
+ case 0x2A: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case 0x2B: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case 0x2F: // FILEPASS [ 2345]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = Z_Ende;
+ break;
+ case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break;
+ case 0x83:
+ case 0x84: rPageSett.ReadCenter( maStrm ); break;
+ case 0xA0: rTabViewSett.ReadScl( maStrm ); break;
+ case 0xA1: rPageSett.ReadSetup( maStrm ); break;
+ case 0xBD: Mulrk(); break; // MULRK [ 5]
+ case 0xBE: Mulblank(); break; // MULBLANK [ 5]
+ case 0xD6: Rstring(); break; // RSTRING [ 5]
+ case 0x00E5: Cellmerging(); break; // #i62300#
+ case 0x0236: TableOp(); break; // TABLE [ 5]
+ case 0x0809: // BOF [ 5]
+ XclTools::SkipSubStream( maStrm );
+ break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Biff5E: // --------------------------------- Z_Biff5E -
+ {
+ switch( nOpcode )
+ {
+ case 0x0809: // BOF [ 5]
+ Bof5();
+ NeueTabelle();
+ switch( pExcRoot->eDateiTyp )
+ {
+ case Biff5:
+ case Biff5M4:
+ eAkt = Z_Biff5TPre; // Shrfmla Prefetch, Row-Prefetch
+ nBofLevel = 0;
+ aIn.StoreGlobalPosition(); // und Position merken
+ break;
+ case Biff5C: // chart sheet
+ GetCurrSheetDrawing().ReadTabChart( maStrm );
+ Eof();
+ GetTracer().TraceChartOnlySheet();
+ break;
+ case Biff5V:
+ default:
+ pD->SetVisible( GetCurrScTab(), false );
+ ePrev = eAkt;
+ eAkt = Z_Biffn0;
+ }
+ DBG_ASSERT( pExcRoot->eDateiTyp != Biff5W,
+ "+ImportExcel::Read(): Doppel-Whopper-Workbook!" );
+
+ break;
+ }
+
+ }
+ break;
+ case Z_Biffn0: // --------------------------------- Z_Biffn0 -
+ {
+ switch( nOpcode )
+ {
+ case 0x0A: // EOF [ 2345]
+ eAkt = ePrev;
+ IncCurrScTab();
+ break;
+ }
+
+ }
+ break;
+ // ----------------------------------------------------------------
+ case Z_Ende: // ----------------------------------- Z_Ende -
+ OSL_FAIL( "*ImportExcel::Read(): Not possible state!" );
+ break;
+ default: OSL_FAIL( "-ImportExcel::Read(): Zustand vergessen!" );
+ }
+ }
+
+ if( eLastErr == eERR_OK )
+ {
+ pProgress.reset();
+
+ AdjustRowHeight();
+ PostDocLoad();
+
+ pD->CalcAfterLoad();
+
+ const XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsTabTruncated() )
+ eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
+ else if( bTabTruncated || rAddrConv.IsRowTruncated() )
+ eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
+ else if( rAddrConv.IsColTruncated() )
+ eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+ }
+
+ return eLastErr;
+}
+
+
+//___________________________________________________________________
+
+FltError ImportExcel8::Read( void )
+{
+#if EXC_INCL_DUMPER
+ {
+ Biff8RecDumper aDumper( GetRoot(), sal_True );
+ if( aDumper.Dump( aIn ) )
+ return ERRCODE_ABORT;
+ }
+#endif
+ // read the entire BIFF8 stream
+ // don't look too close - this stuff seriously needs to be reworked
+
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+ XclImpPalette& rPal = GetPalette();
+ XclImpFontBuffer& rFontBfr = GetFontBuffer();
+ XclImpNumFmtBuffer& rNumFmtBfr = GetNumFmtBuffer();
+ XclImpXFBuffer& rXFBfr = GetXFBuffer();
+ XclImpSst& rSst = GetSst();
+ XclImpTabInfo& rTabInfo = GetTabInfo();
+ XclImpNameManager& rNameMgr = GetNameManager();
+ XclImpLinkManager& rLinkMgr = GetLinkManager();
+ XclImpObjectManager& rObjMgr = GetObjectManager();
+ // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
+ XclImpCondFormatManager& rCondFmtMgr = GetCondFormatManager();
+ XclImpValidationManager& rValidMgr = GetValidationManager();
+ XclImpPivotTableManager& rPTableMgr = GetPivotTableManager();
+ XclImpWebQueryBuffer& rWQBfr = GetWebQueryBuffer();
+
+ bool bInUserView = false; // true = In USERSVIEW(BEGIN|END) record block.
+
+ enum XclImpReadState
+ {
+ EXC_STATE_BEFORE_GLOBALS, /// Before workbook globals (wait for initial BOF).
+ EXC_STATE_GLOBALS_PRE, /// Prefetch for workbook globals.
+ EXC_STATE_GLOBALS, /// Workbook globals.
+ EXC_STATE_BEFORE_SHEET, /// Before worksheet (wait for new worksheet BOF).
+ EXC_STATE_SHEET_PRE, /// Prefetch for worksheet.
+ EXC_STATE_SHEET, /// Worksheet.
+ EXC_STATE_END /// Stop reading.
+ };
+
+ XclImpReadState eAkt = EXC_STATE_BEFORE_GLOBALS;
+
+ FltError eLastErr = eERR_OK;
+
+ ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
+ aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
+
+ /* #i104057# Need to track a base position for progress bar calculation,
+ because sheet substreams may not be in order of sheets. */
+ sal_Size nProgressBasePos = 0;
+ sal_Size nProgressBaseSize = 0;
+
+ bool bSheetHasCodeName = false;
+
+ std::vector< String > CodeNames;
+
+ std::vector < SCTAB > nTabsWithNoCodeName;
+
+ while( eAkt != EXC_STATE_END )
+ {
+ if( eAkt == EXC_STATE_BEFORE_SHEET )
+ {
+ sal_uInt16 nScTab = GetCurrScTab();
+ if( nScTab < maSheetOffsets.size() )
+ {
+ nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
+ nProgressBasePos = maSheetOffsets[ nScTab ];
+ aIn.StartNextRecord( nProgressBasePos );
+ }
+ else
+ eAkt = EXC_STATE_END;
+ }
+ else
+ aIn.StartNextRecord();
+
+ if( !aIn.IsValid() )
+ {
+ // #i63591# finalize table if EOF is missing
+ switch( eAkt )
+ {
+ case EXC_STATE_SHEET_PRE:
+ eAkt = EXC_STATE_SHEET;
+ aIn.SeekGlobalPosition();
+ continue; // next iteration in while loop
+ case EXC_STATE_SHEET:
+ Eof();
+ eAkt = EXC_STATE_END;
+ break;
+ default:
+ eAkt = EXC_STATE_END;
+ }
+ }
+
+ if( eAkt == EXC_STATE_END )
+ break;
+
+ if( eAkt != EXC_STATE_SHEET_PRE && eAkt != EXC_STATE_GLOBALS_PRE )
+ pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
+
+ sal_uInt16 nRecId = aIn.GetRecId();
+
+ /* #i39464# Ignore records between USERSVIEWBEGIN and USERSVIEWEND
+ completely (user specific view settings). Otherwise view settings
+ and filters are loaded multiple times, which at least causes
+ problems in auto-filters. */
+ switch( nRecId )
+ {
+ case EXC_ID_USERSVIEWBEGIN:
+ DBG_ASSERT( !bInUserView, "ImportExcel8::Read - nested user view settings" );
+ bInUserView = true;
+ break;
+ case EXC_ID_USERSVIEWEND:
+ DBG_ASSERT( bInUserView, "ImportExcel8::Read - not in user view settings" );
+ bInUserView = false;
+ break;
+ }
+
+ if( !bInUserView ) switch( eAkt )
+ {
+ // ----------------------------------------------------------------
+ // before workbook globals: wait for initial workbook globals BOF
+ case EXC_STATE_BEFORE_GLOBALS:
+ {
+ if( nRecId == EXC_ID5_BOF )
+ {
+ DBG_ASSERT( GetBiff() == EXC_BIFF8, "ImportExcel8::Read - wrong BIFF version" );
+ Bof5();
+ if( pExcRoot->eDateiTyp == Biff8W )
+ {
+ eAkt = EXC_STATE_GLOBALS_PRE;
+ maStrm.StoreGlobalPosition();
+ nBdshtTab = 0;
+ }
+ else if( pExcRoot->eDateiTyp == Biff8 )
+ {
+ // #i62752# possible to have BIFF8 sheet without globals
+ NeueTabelle();
+ eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
+ bSheetHasCodeName = false; // reset
+ aIn.StoreGlobalPosition();
+ }
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // prefetch for workbook globals
+ case EXC_STATE_GLOBALS_PRE:
+ {
+ switch( nRecId )
+ {
+ case EXC_ID_EOF:
+ case EXC_ID_EXTSST:
+ /* #i56376# evil hack: if EOF for globals is missing,
+ simulate it. This hack works only for the bugdoc
+ given in the issue, where the sheet substreams
+ start directly after the EXTSST record. A future
+ implementation should be more robust against
+ missing EOFs. */
+ if( (nRecId == EXC_ID_EOF) ||
+ ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
+ {
+ eAkt = EXC_STATE_GLOBALS;
+ aIn.SeekGlobalPosition();
+ }
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5678]
+ case 0x13: DocPasssword(); break;
+ case 0x19: WinProtection(); break;
+ case 0x2F: // FILEPASS [ 2345 ]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+ if( eLastErr != ERRCODE_NONE )
+ eAkt = EXC_STATE_END;
+ break;
+ case EXC_ID_FILESHARING: ReadFileSharing(); break;
+ case 0x3D: Window1(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
+ case 0x85: Boundsheet(); break; // BOUNDSHEET [ 5 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345 ]
+
+ // PALETTE follows XFs, but already needed while reading the XFs
+ case EXC_ID_PALETTE: rPal.ReadPalette( maStrm ); break;
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // workbook globals
+ case EXC_STATE_GLOBALS:
+ {
+ switch( nRecId )
+ {
+ case EXC_ID_EOF:
+ case EXC_ID_EXTSST:
+ /* #i56376# evil hack: if EOF for globals is missing,
+ simulate it. This hack works only for the bugdoc
+ given in the issue, where the sheet substreams
+ start directly after the EXTSST record. A future
+ implementation should be more robust against
+ missing EOFs. */
+ if( (nRecId == EXC_ID_EOF) ||
+ ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
+ {
+ rNumFmtBfr.CreateScFormats();
+ rXFBfr.CreateUserStyles();
+ rPTableMgr.ReadPivotCaches( maStrm );
+ eAkt = EXC_STATE_BEFORE_SHEET;
+ }
+ break;
+ case 0x0E: Precision(); break; // PRECISION
+ case 0x22: Rec1904(); break; // 1904 [ 2345 ]
+ case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ]
+ case 0x8D: Hideobj(); break; // HIDEOBJ [ 345 ]
+ case 0xD3: SetHasBasic(); break;
+ case 0xDE: Olesize(); break;
+
+ case EXC_ID_CODENAME: ReadCodeName( aIn, true ); break;
+ case EXC_ID_USESELFS: ReadUsesElfs(); break;
+
+ case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break;
+ case EXC_ID4_FORMAT: rNumFmtBfr.ReadFormat( maStrm ); break;
+ case EXC_ID5_XF: rXFBfr.ReadXF( maStrm ); break;
+ case EXC_ID_STYLE: rXFBfr.ReadStyle( maStrm ); break;
+
+ case EXC_ID_SST: rSst.ReadSst( maStrm ); break;
+ case EXC_ID_TABID: rTabInfo.ReadTabid( maStrm ); break;
+ case EXC_ID_NAME: rNameMgr.ReadName( maStrm ); break;
+
+ case EXC_ID_EXTERNSHEET: rLinkMgr.ReadExternsheet( maStrm ); break;
+ case EXC_ID_SUPBOOK: rLinkMgr.ReadSupbook( maStrm ); break;
+ case EXC_ID_XCT: rLinkMgr.ReadXct( maStrm ); break;
+ case EXC_ID_CRN: rLinkMgr.ReadCrn( maStrm ); break;
+ case EXC_ID_EXTERNNAME: rLinkMgr.ReadExternname( maStrm, pFormConv ); break;
+
+ case EXC_ID_MSODRAWINGGROUP:rObjMgr.ReadMsoDrawingGroup( maStrm ); break;
+
+ case EXC_ID_SXIDSTM: rPTableMgr.ReadSxidstm( maStrm ); break;
+ case EXC_ID_SXVS: rPTableMgr.ReadSxvs( maStrm ); break;
+ case EXC_ID_DCONREF: rPTableMgr.ReadDconref( maStrm ); break;
+ case EXC_ID_DCONNAME: rPTableMgr.ReadDConName( maStrm ); break;
+ }
+
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // before worksheet: wait for new worksheet BOF
+ case EXC_STATE_BEFORE_SHEET:
+ {
+ if( nRecId == EXC_ID5_BOF )
+ {
+ // import only 256 sheets
+ if( GetCurrScTab() > GetScMaxPos().Tab() )
+ {
+ XclTools::SkipSubStream( maStrm );
+ // #i29930# show warning box
+ GetAddressConverter().CheckScTab( GetCurrScTab(), true );
+ eAkt = EXC_STATE_END;
+ }
+ else
+ {
+ Bof5();
+ NeueTabelle();
+ switch( pExcRoot->eDateiTyp )
+ {
+ case Biff8: // worksheet
+ case Biff8M4: // macro sheet
+ eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
+ aIn.StoreGlobalPosition();
+ break;
+ case Biff8C: // chart sheet
+ GetCurrSheetDrawing().ReadTabChart( maStrm );
+ Eof();
+ GetTracer().TraceChartOnlySheet();
+ break;
+ case Biff8W: // workbook
+ DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" );
+ // run through
+ case Biff8V: // VB module
+ default:
+ // TODO: do not create a sheet in the Calc document
+ pD->SetVisible( GetCurrScTab(), false );
+ XclTools::SkipSubStream( maStrm );
+ IncCurrScTab();
+ }
+ }
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // prefetch for worksheet
+ case EXC_STATE_SHEET_PRE:
+ {
+ switch( nRecId )
+ {
+ // skip chart substream
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( maStrm, false );break;
+ case EXC_ID_SCL: rTabViewSett.ReadScl( maStrm ); break;
+ case EXC_ID_PANE: rTabViewSett.ReadPane( maStrm ); break;
+ case EXC_ID_SELECTION: rTabViewSett.ReadSelection( maStrm ); break;
+
+ case EXC_ID2_DIMENSIONS:
+ case EXC_ID3_DIMENSIONS: ReadDimensions(); break;
+
+ case EXC_ID_CODENAME: ReadCodeName( aIn, false ); bSheetHasCodeName = true; break;
+
+ case 0x0A: // EOF [ 2345 ]
+ {
+ eAkt = EXC_STATE_SHEET;
+ String sName;
+ GetDoc().GetName( GetCurrScTab(), sName );
+ if ( !bSheetHasCodeName )
+ {
+ nTabsWithNoCodeName.push_back( GetCurrScTab() );
+ OSL_TRACE("No Codename for %d", GetCurrScTab() );
+ }
+ else
+ {
+ String sCodeName;
+ GetDoc().GetCodeName( GetCurrScTab(), sCodeName );
+ OSL_TRACE("Have CodeName %s for SheetName %s",
+ rtl::OUStringToOString( sCodeName, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ CodeNames.push_back( sCodeName );
+ }
+
+ bSheetHasCodeName = false; // reset
+
+ aIn.SeekGlobalPosition(); // und zurueck an alte Position
+ break;
+ }
+ case 0x12: SheetProtect(); break;
+ case 0x13: SheetPassword(); break;
+ case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
+ case 0x55: DefColWidth(); break;
+ case 0x7D: Colinfo(); break; // COLINFO [ 345 ]
+ case 0x81: Wsbool(); break; // WSBOOL [ 2345 ]
+ case 0x8C: Country(); break; // COUNTRY [ 345 ]
+ case 0x99: Standardwidth(); break; // STANDARDWIDTH[ 45 ]
+ case 0x9B: FilterMode(); break; // FILTERMODE
+ case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO
+ case 0x9E: AutoFilter(); break; // AUTOFILTER
+ case 0x0208: Row34(); break; // ROW [ 34 ]
+ case EXC_ID2_ARRAY:
+ case EXC_ID3_ARRAY: Array34(); break; // ARRAY [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
+ case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
+ case 0x0867: SheetProtection(); break; // SHEETPROTECTION
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ // worksheet
+ case EXC_STATE_SHEET:
+ {
+ switch( nRecId )
+ {
+ // skip unknown substreams
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( maStrm ); break;
+
+ case EXC_ID_EOF: Eof(); eAkt = EXC_STATE_BEFORE_SHEET; break;
+
+ case EXC_ID2_BLANK:
+ case EXC_ID3_BLANK: ReadBlank(); break;
+ case EXC_ID2_INTEGER: ReadInteger(); break;
+ case EXC_ID2_NUMBER:
+ case EXC_ID3_NUMBER: ReadNumber(); break;
+ case EXC_ID2_LABEL:
+ case EXC_ID3_LABEL: ReadLabel(); break;
+ case EXC_ID2_BOOLERR:
+ case EXC_ID3_BOOLERR: ReadBoolErr(); break;
+ case EXC_ID_RK: ReadRk(); break;
+
+ case 0x0006:
+ case 0x0206:
+ case 0x0406: Formula25(); break; // FORMULA [ 2 5 ]
+ case 0x000C: Calccount(); break; // CALCCOUNT
+ case 0x0010: Delta(); break; // DELTA
+ case 0x0011: Iteration(); break; // ITERATION
+ case 0x007E:
+ case 0x00AE: Scenman(); break; // SCENMAN
+ case 0x00AF: Scenario(); break; // SCENARIO
+ case 0x00BD: Mulrk(); break; // MULRK [ 5 ]
+ case 0x00BE: Mulblank(); break; // MULBLANK [ 5 ]
+ case 0x00D6: Rstring(); break; // RSTRING [ 5 ]
+ case 0x00E5: Cellmerging(); break; // CELLMERGING
+ case 0x00FD: Labelsst(); break; // LABELSST [ 8 ]
+ case 0x0236: TableOp(); break; // TABLE
+
+ case EXC_ID_HORPAGEBREAKS:
+ case EXC_ID_VERPAGEBREAKS: rPageSett.ReadPageBreaks( maStrm ); break;
+ case EXC_ID_HEADER:
+ case EXC_ID_FOOTER: rPageSett.ReadHeaderFooter( maStrm ); break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN: rPageSett.ReadMargin( maStrm ); break;
+ case EXC_ID_PRINTHEADERS: rPageSett.ReadPrintHeaders( maStrm ); break;
+ case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( maStrm ); break;
+ case EXC_ID_HCENTER:
+ case EXC_ID_VCENTER: rPageSett.ReadCenter( maStrm ); break;
+ case EXC_ID_SETUP: rPageSett.ReadSetup( maStrm ); break;
+ case EXC_ID8_IMGDATA: rPageSett.ReadImgData( maStrm ); break;
+
+ case EXC_ID_MSODRAWING: GetCurrSheetDrawing().ReadMsoDrawing( maStrm ); break;
+ // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
+ case EXC_ID_OBJ: GetCurrSheetDrawing().ReadObj( maStrm ); break;
+ case EXC_ID_NOTE: GetCurrSheetDrawing().ReadNote( maStrm ); break;
+
+ case EXC_ID_HLINK: XclImpHyperlink::ReadHlink( maStrm ); break;
+ case EXC_ID_LABELRANGES: XclImpLabelranges::ReadLabelranges( maStrm ); break;
+
+ case EXC_ID_CONDFMT: rCondFmtMgr.ReadCondfmt( maStrm ); break;
+ case EXC_ID_CF: rCondFmtMgr.ReadCF( maStrm ); break;
+
+ case EXC_ID_DVAL: rValidMgr.ReadDval( maStrm ); break;
+ case EXC_ID_DV: rValidMgr.ReadDV( maStrm ); break;
+
+ case EXC_ID_QSI: rWQBfr.ReadQsi( maStrm ); break;
+ case EXC_ID_WQSTRING: rWQBfr.ReadWqstring( maStrm ); break;
+ case EXC_ID_PQRY: rWQBfr.ReadParamqry( maStrm ); break;
+ case EXC_ID_WQSETT: rWQBfr.ReadWqsettings( maStrm ); break;
+ case EXC_ID_WQTABLES: rWQBfr.ReadWqtables( maStrm ); break;
+
+ case EXC_ID_SXVIEW: rPTableMgr.ReadSxview( maStrm ); break;
+ case EXC_ID_SXVD: rPTableMgr.ReadSxvd( maStrm ); break;
+ case EXC_ID_SXVI: rPTableMgr.ReadSxvi( maStrm ); break;
+ case EXC_ID_SXIVD: rPTableMgr.ReadSxivd( maStrm ); break;
+ case EXC_ID_SXPI: rPTableMgr.ReadSxpi( maStrm ); break;
+ case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break;
+ case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break;
+ case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break;
+ case EXC_ID_SHEETEXT: rTabViewSett.ReadTabBgColor( maStrm, rPal ); break;
+ case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break;
+ }
+ }
+ break;
+
+ // ----------------------------------------------------------------
+ default:;
+ }
+ }
+
+ if( eLastErr == eERR_OK )
+ {
+ // In some strange circumstances a the codename might be missing
+ // # Create any missing Sheet CodeNames
+ std::vector < SCTAB >::iterator it_end = nTabsWithNoCodeName.end();
+ for ( std::vector < SCTAB >::iterator it = nTabsWithNoCodeName.begin(); it != it_end; ++it )
+ {
+ SCTAB nTab = 1;
+ OSL_TRACE("Trying to find suitable codename for %d", *it );
+ while ( true )
+ {
+ String sTmpName( RTL_CONSTASCII_USTRINGPARAM("Sheet" ) );
+ sTmpName += String::CreateFromInt32( sal_Int32(nTab++) );
+ std::vector< String >::iterator codeName_It = CodeNames.begin();
+ std::vector< String >::iterator codeName_It_end = CodeNames.end();
+ // search for codename
+ for ( ; codeName_It != codeName_It_end; ++codeName_It )
+ {
+ if ( *codeName_It == sTmpName )
+ break;
+ }
+
+ if ( codeName_It == codeName_It_end ) // generated codename not found
+ {
+ OSL_TRACE("Using generated codename %s", rtl::OUStringToOString( sTmpName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ // Set new codename
+ GetDoc().SetCodeName( *it, sTmpName );
+ // Record newly used codename
+ CodeNames.push_back( sTmpName );
+ // Record those we have created so they can be created in
+ // basic
+ AutoGeneratedCodeNames.push_back( sTmpName );
+ break;
+ }
+ }
+
+ }
+ // #i45843# Convert pivot tables before calculation, so they are available
+ // for the GETPIVOTDATA function.
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().ConvertPivotTables();
+
+ pProgress.reset();
+#if 0
+ // Excel documents look much better without this call; better in the
+ // sense that the row heights are identical to the original heights in
+ // Excel.
+ if (pD->IsAdjustHeightEnabled())
+ AdjustRowHeight();
+#endif
+ PostDocLoad();
+
+ pD->CalcAfterLoad();
+
+ // import change tracking data
+ XclImpChangeTrack aImpChTr( GetRoot(), maStrm );
+ aImpChTr.Apply();
+
+ const XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ if( rAddrConv.IsTabTruncated() )
+ eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
+ else if( bTabTruncated || rAddrConv.IsRowTruncated() )
+ eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
+ else if( rAddrConv.IsColTruncated() )
+ eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().MaybeRefreshPivotTables();
+ }
+
+ return eLastErr;
+}
+
+//___________________________________________________________________
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/tokstack.cxx b/sc/source/filter/excel/tokstack.cxx
new file mode 100644
index 000000000000..36c46e04b15e
--- /dev/null
+++ b/sc/source/filter/excel/tokstack.cxx
@@ -0,0 +1,881 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#ifndef PCH
+#include <string.h>
+#endif
+
+#include "compiler.hxx"
+#include "tokstack.hxx"
+#include "global.hxx"
+#include "scmatrix.hxx"
+
+#include <stdio.h> // printf
+
+const sal_uInt16 TokenPool::nScTokenOff = 8192;
+
+
+TokenStack::TokenStack( sal_uInt16 nNewSize )
+{
+ pStack = new TokenId[ nNewSize ];
+
+ Reset();
+ nSize = nNewSize;
+}
+
+
+TokenStack::~TokenStack()
+{
+ delete[] pStack;
+}
+
+
+
+
+//------------------------------------------------------------------------
+
+// !ACHTUNG!: nach Aussen hin beginnt die Nummerierung mit 1!
+// !ACHTUNG!: SC-Token werden mit einem Offset nScTokenOff abgelegt
+// -> Unterscheidung von anderen Token
+
+
+TokenPool::TokenPool( void )
+{
+ sal_uInt16 nLauf = nScTokenOff;
+
+ // Sammelstelle fuer Id-Folgen
+ nP_Id = 256;
+ pP_Id = new sal_uInt16[ nP_Id ];
+
+ // Sammelstelle fuer Ids
+ nElement = 32;
+ pElement = new sal_uInt16[ nElement ];
+ pType = new E_TYPE[ nElement ];
+ pSize = new sal_uInt16[ nElement ];
+ nP_IdLast = 0;
+
+ // Sammelstelle fuer Strings
+ nP_Str = 4;
+ ppP_Str = new String *[ nP_Str ];
+ for( nLauf = 0 ; nLauf < nP_Str ; nLauf++ )
+ ppP_Str[ nLauf ] = NULL;
+
+ // Sammelstelle fuer double
+ nP_Dbl = 8;
+ pP_Dbl = new double[ nP_Dbl ];
+
+ // Sammelstelle fuer error codes
+ nP_Err = 8;
+ pP_Err = new sal_uInt16[ nP_Err ];
+
+ // Sammelstellen fuer Referenzen
+ nP_RefTr = 32;
+ ppP_RefTr = new ScSingleRefData *[ nP_RefTr ];
+ for( nLauf = 0 ; nLauf < nP_RefTr ; nLauf++ )
+ ppP_RefTr[ nLauf ] = NULL;
+
+ nP_Ext = 32;
+ ppP_Ext = new EXTCONT*[ nP_Ext ];
+ memset( ppP_Ext, 0, sizeof( EXTCONT* ) * nP_Ext );
+
+ nP_Nlf = 16;
+ ppP_Nlf = new NLFCONT*[ nP_Nlf ];
+ memset( ppP_Nlf, 0, sizeof( NLFCONT* ) * nP_Nlf );
+
+ nP_Matrix = 16;
+ ppP_Matrix = new ScMatrix*[ nP_Matrix ];
+ memset( ppP_Matrix, 0, sizeof( ScMatrix* ) * nP_Matrix );
+
+ pScToken = new ScTokenArray;
+
+ Reset();
+}
+
+
+TokenPool::~TokenPool()
+{
+ sal_uInt16 n;
+
+ delete[] pP_Id;
+ delete[] pElement;
+ delete[] pType;
+ delete[] pSize;
+ delete[] pP_Dbl;
+ delete[] pP_Err;
+
+ for( n = 0 ; n < nP_RefTr ; n++/*, pAktTr++*/ )
+ {
+ if( ppP_RefTr[ n ] )
+ delete ppP_RefTr[ n ];
+ }
+ delete[] ppP_RefTr;
+
+ for( n = 0 ; n < nP_Str ; n++/*, pAktStr++*/ )
+ {
+ if( ppP_Str[ n ] )
+ delete ppP_Str[ n ];
+ }
+ delete[] ppP_Str;
+
+ for( n = 0 ; n < nP_Ext ; n++ )
+ {
+ if( ppP_Ext[ n ] )
+ delete ppP_Ext[ n ];
+ }
+ delete[] ppP_Ext;
+
+ for( n = 0 ; n < nP_Nlf ; n++ )
+ {
+ if( ppP_Nlf[ n ] )
+ delete ppP_Nlf[ n ];
+ }
+ delete[] ppP_Nlf;
+
+ for( n = 0 ; n < nP_Matrix ; n++ )
+ {
+ if( ppP_Matrix[ n ] )
+ ppP_Matrix[ n ]->DecRef( );
+ }
+ delete[] ppP_Matrix;
+
+ delete pScToken;
+}
+
+
+void TokenPool::GrowString( void )
+{
+ sal_uInt16 nP_StrNew = nP_Str * 2;
+ sal_uInt16 nL;
+
+ String** ppP_StrNew = new String *[ nP_StrNew ];
+
+ for( nL = 0 ; nL < nP_Str ; nL++ )
+ ppP_StrNew[ nL ] = ppP_Str[ nL ];
+ for( nL = nP_Str ; nL < nP_StrNew ; nL++ )
+ ppP_StrNew[ nL ] = NULL;
+
+ nP_Str = nP_StrNew;
+
+ delete[] ppP_Str;
+ ppP_Str = ppP_StrNew;
+}
+
+
+void TokenPool::GrowDouble( void )
+{
+ sal_uInt16 nP_DblNew = nP_Dbl * 2;
+
+ double* pP_DblNew = new double[ nP_DblNew ];
+
+ for( sal_uInt16 nL = 0 ; nL < nP_Dbl ; nL++ )
+ pP_DblNew[ nL ] = pP_Dbl[ nL ];
+
+ nP_Dbl = nP_DblNew;
+
+ delete[] pP_Dbl;
+ pP_Dbl = pP_DblNew;
+}
+
+void TokenPool::GrowTripel( void )
+{
+ sal_uInt16 nP_RefTrNew = nP_RefTr * 2;
+ sal_uInt16 nL;
+
+ ScSingleRefData** ppP_RefTrNew = new ScSingleRefData *[ nP_RefTrNew ];
+
+ for( nL = 0 ; nL < nP_RefTr ; nL++ )
+ ppP_RefTrNew[ nL ] = ppP_RefTr[ nL ];
+ for( nL = nP_RefTr ; nL < nP_RefTrNew ; nL++ )
+ ppP_RefTrNew[ nL ] = NULL;
+
+ nP_RefTr = nP_RefTrNew;
+
+ delete[] ppP_RefTr;
+ ppP_RefTr = ppP_RefTrNew;
+}
+
+
+void TokenPool::GrowId( void )
+{
+ sal_uInt16 nP_IdNew = nP_Id * 2;
+
+ sal_uInt16* pP_IdNew = new sal_uInt16[ nP_IdNew ];
+
+ for( sal_uInt16 nL = 0 ; nL < nP_Id ; nL++ )
+ pP_IdNew[ nL ] = pP_Id[ nL ];
+
+ nP_Id = nP_IdNew;
+
+ delete[] pP_Id;
+ pP_Id = pP_IdNew;
+}
+
+
+void TokenPool::GrowElement( void )
+{
+ sal_uInt16 nElementNew = nElement * 2;
+
+ sal_uInt16* pElementNew = new sal_uInt16[ nElementNew ];
+ E_TYPE* pTypeNew = new E_TYPE[ nElementNew ];
+ sal_uInt16* pSizeNew = new sal_uInt16[ nElementNew ];
+
+ for( sal_uInt16 nL = 0 ; nL < nElement ; nL++ )
+ {
+ pElementNew[ nL ] = pElement[ nL ];
+ pTypeNew[ nL ] = pType[ nL ];
+ pSizeNew[ nL ] = pSize[ nL ];
+ }
+
+ nElement = nElementNew;
+
+ delete[] pElement;
+ delete[] pType;
+ delete[] pSize;
+ pElement = pElementNew;
+ pType = pTypeNew;
+ pSize = pSizeNew;
+}
+
+
+void TokenPool::GrowExt( void )
+{
+ sal_uInt16 nNewSize = nP_Ext * 2;
+
+ EXTCONT** ppNew = new EXTCONT*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( EXTCONT* ) * nNewSize );
+ memcpy( ppNew, ppP_Ext, sizeof( EXTCONT* ) * nP_Ext );
+
+ delete[] ppP_Ext;
+ ppP_Ext = ppNew;
+ nP_Ext = nNewSize;
+}
+
+
+void TokenPool::GrowNlf( void )
+{
+ sal_uInt16 nNewSize = nP_Nlf * 2;
+
+ NLFCONT** ppNew = new NLFCONT*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( NLFCONT* ) * nNewSize );
+ memcpy( ppNew, ppP_Nlf, sizeof( NLFCONT* ) * nP_Nlf );
+
+ delete[] ppP_Nlf;
+ ppP_Nlf = ppNew;
+ nP_Nlf = nNewSize;
+}
+
+
+void TokenPool::GrowMatrix( void )
+{
+ sal_uInt16 nNewSize = nP_Matrix * 2;
+
+ ScMatrix** ppNew = new ScMatrix*[ nNewSize ];
+
+ memset( ppNew, 0, sizeof( ScMatrix* ) * nNewSize );
+ memcpy( ppNew, ppP_Matrix, sizeof( ScMatrix* ) * nP_Matrix );
+
+ delete[] ppP_Matrix;
+ ppP_Matrix = ppNew;
+ nP_Matrix = nNewSize;
+}
+
+void TokenPool::GetElement( const sal_uInt16 nId )
+{
+ DBG_ASSERT( nId < nElementAkt, "*TokenPool::GetElement(): Id zu gross!?" );
+
+ if( pType[ nId ] == T_Id )
+ GetElementRek( nId );
+ else
+ {
+ switch( pType[ nId ] )
+ {
+#ifdef DBG_UTIL
+ case T_Id:
+ OSL_FAIL( "-TokenPool::GetElement(): hier hast Du nichts zu suchen!" );
+ break;
+#endif
+ case T_Str:
+ pScToken->AddString( ppP_Str[ pElement[ nId ] ]->GetBuffer() );
+ break;
+ case T_D:
+ pScToken->AddDouble( pP_Dbl[ pElement[ nId ] ] );
+ break;
+ case T_Err:
+ break;
+ case T_RefC:
+ pScToken->AddSingleReference( *ppP_RefTr[ pElement[ (sal_uInt16) nId ] ] );
+ break;
+ case T_RefA:
+ {
+ ScComplexRefData aScComplexRefData;
+ aScComplexRefData.Ref1 = *ppP_RefTr[ pElement[ nId ] ];
+ aScComplexRefData.Ref2 = *ppP_RefTr[ pElement[ nId ] + 1 ];
+ pScToken->AddDoubleReference( aScComplexRefData );
+ }
+ break;
+ case T_RN:
+ {
+ sal_uInt16 n = pElement[nId];
+ if (n < maRangeNames.size())
+ {
+ const RangeName& r = maRangeNames[n];
+ pScToken->AddRangeName(r.mnIndex, r.mbGlobal);
+ }
+ }
+ break;
+ case T_Ext:
+ {
+ sal_uInt16 n = pElement[ nId ];
+ EXTCONT* p = ( n < nP_Ext )? ppP_Ext[ n ] : NULL;
+
+ if( p )
+ {
+ if( p->eId == ocEuroConvert )
+ pScToken->AddOpCode( p->eId );
+ else
+ pScToken->AddExternal( p->aText, p->eId );
+ }
+ }
+ break;
+ case T_Nlf:
+ {
+ sal_uInt16 n = pElement[ nId ];
+ NLFCONT* p = ( n < nP_Nlf )? ppP_Nlf[ n ] : NULL;
+
+ if( p )
+ pScToken->AddColRowName( p->aRef );
+ }
+ break;
+ case T_Matrix:
+ {
+ sal_uInt16 n = pElement[ nId ];
+ ScMatrix* p = ( n < nP_Matrix )? ppP_Matrix[ n ] : NULL;
+
+ if( p )
+ pScToken->AddMatrix( p );
+ }
+ break;
+ case T_ExtName:
+ {
+ sal_uInt16 n = pElement[nId];
+ if (n < maExtNames.size())
+ {
+ const ExtName& r = maExtNames[n];
+ pScToken->AddExternalName(r.mnFileId, r.maName);
+ }
+ }
+ break;
+ case T_ExtRefC:
+ {
+ sal_uInt16 n = pElement[nId];
+ if (n < maExtCellRefs.size())
+ {
+ const ExtCellRef& r = maExtCellRefs[n];
+ pScToken->AddExternalSingleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ case T_ExtRefA:
+ {
+ sal_uInt16 n = pElement[nId];
+ if (n < maExtAreaRefs.size())
+ {
+ const ExtAreaRef& r = maExtAreaRefs[n];
+ pScToken->AddExternalDoubleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ default:
+ OSL_FAIL("-TokenPool::GetElement(): Zustand undefiniert!?");
+ }
+ }
+}
+
+
+void TokenPool::GetElementRek( const sal_uInt16 nId )
+{
+#ifdef DBG_UTIL
+ nRek++;
+ DBG_ASSERT( nRek <= nP_Id, "*TokenPool::GetElement(): Rekursion loopt!?" );
+#endif
+
+ DBG_ASSERT( nId < nElementAkt, "*TokenPool::GetElementRek(): Id zu gross!?" );
+
+ DBG_ASSERT( pType[ nId ] == T_Id, "-TokenPool::GetElementRek(): nId nicht Id-Folge!" );
+
+
+ sal_uInt16 nAnz = pSize[ nId ];
+ sal_uInt16* pAkt = &pP_Id[ pElement[ nId ] ];
+ for( ; nAnz > 0 ; nAnz--, pAkt++ )
+ {
+ if( *pAkt < nScTokenOff )
+ {// Rekursion oder nicht?
+ switch( pType[ *pAkt ] )
+ {
+ case T_Id:
+ GetElementRek( *pAkt );
+ break;
+ case T_Str:
+ pScToken->AddString( ppP_Str[ pElement[ *pAkt ] ]->GetBuffer() );
+ break;
+ case T_D:
+ pScToken->AddDouble( pP_Dbl[ pElement[ *pAkt ] ] );
+ break;
+ case T_Err:
+ break;
+ case T_RefC:
+ pScToken->AddSingleReference( *ppP_RefTr[ pElement[ *pAkt ] ] );
+ break;
+ case T_RefA:
+ {
+ ScComplexRefData aScComplexRefData;
+ aScComplexRefData.Ref1 = *ppP_RefTr[ pElement[ *pAkt ] ];
+ aScComplexRefData.Ref2 = *ppP_RefTr[ pElement[ *pAkt ] + 1 ];
+ pScToken->AddDoubleReference( aScComplexRefData );
+ }
+ break;
+ case T_RN:
+ {
+ sal_uInt16 n = pElement[*pAkt];
+ if (n < maRangeNames.size())
+ {
+ const RangeName& r = maRangeNames[n];
+ pScToken->AddRangeName(r.mnIndex, r.mbGlobal);
+ }
+ }
+ break;
+ case T_Ext:
+ {
+ sal_uInt16 n = pElement[ *pAkt ];
+ EXTCONT* p = ( n < nP_Ext )? ppP_Ext[ n ] : NULL;
+
+ if( p )
+ pScToken->AddExternal( p->aText, p->eId );
+ }
+ break;
+ case T_Nlf:
+ {
+ sal_uInt16 n = pElement[ *pAkt ];
+ NLFCONT* p = ( n < nP_Nlf )? ppP_Nlf[ n ] : NULL;
+
+ if( p )
+ pScToken->AddColRowName( p->aRef );
+ }
+ break;
+ case T_Matrix:
+ {
+ sal_uInt16 n = pElement[ *pAkt ];
+ ScMatrix* p = ( n < nP_Matrix )? ppP_Matrix[ n ] : NULL;
+
+ if( p )
+ pScToken->AddMatrix( p );
+ }
+ break;
+ case T_ExtName:
+ {
+ sal_uInt16 n = pElement[*pAkt];
+ if (n < maExtNames.size())
+ {
+ const ExtName& r = maExtNames[n];
+ pScToken->AddExternalName(r.mnFileId, r.maName);
+ }
+ }
+ break;
+ case T_ExtRefC:
+ {
+ sal_uInt16 n = pElement[*pAkt];
+ if (n < maExtCellRefs.size())
+ {
+ const ExtCellRef& r = maExtCellRefs[n];
+ pScToken->AddExternalSingleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ case T_ExtRefA:
+ {
+ sal_uInt16 n = pElement[*pAkt];
+ if (n < maExtAreaRefs.size())
+ {
+ const ExtAreaRef& r = maExtAreaRefs[n];
+ pScToken->AddExternalDoubleReference(r.mnFileId, r.maTabName, r.maRef);
+ }
+ }
+ break;
+ default:
+ OSL_FAIL("-TokenPool::GetElementRek(): Zustand undefiniert!?");
+ }
+ }
+ else // elementarer SC_Token
+ pScToken->AddOpCode( ( DefTokenId ) ( *pAkt - nScTokenOff ) );
+ }
+
+
+#ifdef DBG_UTIL
+ nRek--;
+#endif
+}
+
+
+void TokenPool::operator >>( TokenId& rId )
+{
+ rId = ( TokenId ) ( nElementAkt + 1 );
+
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[ nElementAkt ] = nP_IdLast; // Start der Token-Folge
+ pType[ nElementAkt ] = T_Id; // Typinfo eintragen
+ pSize[ nElementAkt ] = nP_IdAkt - nP_IdLast;
+ // von nP_IdLast bis nP_IdAkt-1 geschrieben -> Laenge der Folge
+
+ nElementAkt++; // Startwerte fuer naechste Folge
+ nP_IdLast = nP_IdAkt;
+}
+
+
+const TokenId TokenPool::Store( const double& rDouble )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_DblAkt >= nP_Dbl )
+ GrowDouble();
+
+ pElement[ nElementAkt ] = nP_DblAkt; // Index in Double-Array
+ pType[ nElementAkt ] = T_D; // Typinfo Double eintragen
+
+ pP_Dbl[ nP_DblAkt ] = rDouble;
+
+ pSize[ nElementAkt ] = 1; // eigentlich Banane
+
+ nElementAkt++;
+ nP_DblAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const sal_uInt16 nIndex )
+{
+ return StoreName(nIndex, true);
+}
+
+
+const TokenId TokenPool::Store( const String& rString )
+{
+ // weitgehend nach Store( const sal_Char* ) kopiert, zur Vermeidung
+ // eines temporaeren Strings in "
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_StrAkt >= nP_Str )
+ GrowString();
+
+ pElement[ nElementAkt ] = nP_StrAkt; // Index in String-Array
+ pType[ nElementAkt ] = T_Str; // Typinfo String eintragen
+
+ // String anlegen
+ if( !ppP_Str[ nP_StrAkt ] )
+ //...aber nur, wenn noch nicht vorhanden
+ ppP_Str[ nP_StrAkt ] = new String( rString );
+ else
+ //...ansonsten nur kopieren
+ *ppP_Str[ nP_StrAkt ] = rString;
+
+ DBG_ASSERT( sizeof( xub_StrLen ) <= 2, "*TokenPool::Store(): StrLen doesn't match!" );
+
+ pSize[ nElementAkt ] = ( sal_uInt16 ) ppP_Str[ nP_StrAkt ]->Len();
+
+ nElementAkt++;
+ nP_StrAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const ScSingleRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_RefTrAkt >= nP_RefTr )
+ GrowTripel();
+
+ pElement[ nElementAkt ] = nP_RefTrAkt;
+ pType[ nElementAkt ] = T_RefC; // Typinfo Cell-Reff eintragen
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr;
+
+ nElementAkt++;
+ nP_RefTrAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const ScComplexRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_RefTrAkt + 1 >= nP_RefTr )
+ GrowTripel();
+
+ pElement[ nElementAkt ] = nP_RefTrAkt;
+ pType[ nElementAkt ] = T_RefA; // Typinfo Area-Reff eintragen
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr.Ref1 );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr.Ref1;
+ nP_RefTrAkt++;
+
+ if( !ppP_RefTr[ nP_RefTrAkt ] )
+ ppP_RefTr[ nP_RefTrAkt ] = new ScSingleRefData( rTr.Ref2 );
+ else
+ *ppP_RefTr[ nP_RefTrAkt ] = rTr.Ref2;
+ nP_RefTrAkt++;
+
+ nElementAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::Store( const DefTokenId e, const String& r )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_ExtAkt >= nP_Ext )
+ GrowExt();
+
+ pElement[ nElementAkt ] = nP_ExtAkt;
+ pType[ nElementAkt ] = T_Ext; // Typinfo String eintragen
+
+ if( ppP_Ext[ nP_ExtAkt ] )
+ {
+ ppP_Ext[ nP_ExtAkt ]->eId = e;
+ ppP_Ext[ nP_ExtAkt ]->aText = r;
+ }
+ else
+ ppP_Ext[ nP_ExtAkt ] = new EXTCONT( e, r );
+
+ nElementAkt++;
+ nP_ExtAkt++;
+
+ return ( const TokenId ) nElementAkt; // Ausgabe von altem Wert + 1!
+}
+
+
+const TokenId TokenPool::StoreNlf( const ScSingleRefData& rTr )
+{
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_NlfAkt >= nP_Nlf )
+ GrowNlf();
+
+ pElement[ nElementAkt ] = nP_NlfAkt;
+ pType[ nElementAkt ] = T_Nlf;
+
+ if( ppP_Nlf[ nP_NlfAkt ] )
+ {
+ ppP_Nlf[ nP_NlfAkt ]->aRef = rTr;
+ }
+ else
+ ppP_Nlf[ nP_NlfAkt ] = new NLFCONT( rTr );
+
+ nElementAkt++;
+ nP_NlfAkt++;
+
+ return ( const TokenId ) nElementAkt;
+}
+
+const TokenId TokenPool::StoreMatrix()
+{
+ ScMatrix* pM;
+
+ if( nElementAkt >= nElement )
+ GrowElement();
+
+ if( nP_MatrixAkt >= nP_Matrix )
+ GrowMatrix();
+
+ pElement[ nElementAkt ] = nP_MatrixAkt;
+ pType[ nElementAkt ] = T_Matrix;
+
+ pM = new ScMatrix( 0, 0 );
+ pM->IncRef( );
+ ppP_Matrix[ nP_MatrixAkt ] = pM;
+
+ nElementAkt++;
+ nP_MatrixAkt++;
+
+ return ( const TokenId ) nElementAkt;
+}
+
+const TokenId TokenPool::StoreName( sal_uInt16 nIndex, bool bGlobal )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<sal_uInt16>(maRangeNames.size());
+ pType[nElementAkt] = T_RN;
+
+ maRangeNames.push_back(RangeName());
+ RangeName& r = maRangeNames.back();
+ r.mnIndex = nIndex;
+ r.mbGlobal = bGlobal;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+const TokenId TokenPool::StoreExtName( sal_uInt16 nFileId, const String& rName )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<sal_uInt16>(maExtNames.size());
+ pType[nElementAkt] = T_ExtName;
+
+ maExtNames.push_back(ExtName());
+ ExtName& r = maExtNames.back();
+ r.mnFileId = nFileId;
+ r.maName = rName;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+const TokenId TokenPool::StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<sal_uInt16>(maExtCellRefs.size());
+ pType[nElementAkt] = T_ExtRefC;
+
+ maExtCellRefs.push_back(ExtCellRef());
+ ExtCellRef& r = maExtCellRefs.back();
+ r.mnFileId = nFileId;
+ r.maTabName = rTabName;
+ r.maRef = rRef;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+const TokenId TokenPool::StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ if ( nElementAkt >= nElement )
+ GrowElement();
+
+ pElement[nElementAkt] = static_cast<sal_uInt16>(maExtAreaRefs.size());
+ pType[nElementAkt] = T_ExtRefA;
+
+ maExtAreaRefs.push_back(ExtAreaRef());
+ ExtAreaRef& r = maExtAreaRefs.back();
+ r.mnFileId = nFileId;
+ r.maTabName = rTabName;
+ r.maRef = rRef;
+
+ ++nElementAkt;
+
+ return static_cast<const TokenId>(nElementAkt);
+}
+
+void TokenPool::Reset( void )
+{
+ nP_IdAkt = nP_IdLast = nElementAkt = nP_StrAkt = nP_DblAkt = nP_ErrAkt = nP_RefTrAkt = nP_ExtAkt = nP_NlfAkt = nP_MatrixAkt = 0;
+ maRangeNames.clear();
+ maExtNames.clear();
+ maExtCellRefs.clear();
+ maExtAreaRefs.clear();
+}
+
+
+sal_Bool TokenPool::IsSingleOp( const TokenId& rId, const DefTokenId eId ) const
+{
+ sal_uInt16 nId = (sal_uInt16) rId;
+ if( nId && nId <= nElementAkt )
+ {// existent?
+ nId--;
+ if( T_Id == pType[ nId ] )
+ {// Tokenfolge?
+ if( pSize[ nId ] == 1 )
+ {// GENAU 1 Token
+ sal_uInt16 nSecId = pP_Id[ pElement[ nId ] ];
+ if( nSecId >= nScTokenOff )
+ {// Default-Token?
+ return ( DefTokenId ) ( nSecId - nScTokenOff ) == eId; // Gesuchter?
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+const String* TokenPool::GetExternal( const TokenId& rId ) const
+{
+ const String* p = NULL;
+ sal_uInt16 n = (sal_uInt16) rId;
+ if( n && n <= nElementAkt )
+ {
+ n--;
+ if( (pType[ n ] == T_Ext) && ppP_Ext[ pElement[ n ] ] )
+ p = &ppP_Ext[ pElement[ n ] ]->aText;
+ }
+
+ return p;
+}
+
+ScMatrix* TokenPool::GetMatrix( unsigned int n ) const
+{
+ if( n < nP_MatrixAkt )
+ return ppP_Matrix[ n ];
+ else
+ printf ("GETMATRIX %d >= %d\n", n, nP_MatrixAkt);
+ return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx
new file mode 100644
index 000000000000..5a37893da6cc
--- /dev/null
+++ b/sc/source/filter/excel/xechart.cxx
@@ -0,0 +1,3525 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xechart.hxx"
+
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
+#include <com/sun/star/chart/ChartAxisPosition.hpp>
+#include <com/sun/star/chart/ChartLegendExpansion.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+#include <com/sun/star/chart/TimeInterval.hpp>
+#include <com/sun/star/chart/TimeUnit.hpp>
+#include <com/sun/star/chart/XAxisSupplier.hpp>
+#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/XDiagram.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/XColorScheme.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/RelativeSize.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/TickmarkStyle.hpp>
+
+#include <vcl/outdev.hxx>
+#include <filter/msfilter/escherex.hxx>
+
+#include "document.hxx"
+#include "rangelst.hxx"
+#include "rangeutl.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+#include "token.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xehelper.hxx"
+#include "xepage.hxx"
+#include "xestyle.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::i18n::XBreakIterator;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XShapes;
+
+using ::com::sun::star::chart2::IncrementData;
+using ::com::sun::star::chart2::RelativePosition;
+using ::com::sun::star::chart2::RelativeSize;
+using ::com::sun::star::chart2::ScaleData;
+using ::com::sun::star::chart2::SubIncrement;
+using ::com::sun::star::chart2::XAxis;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::chart2::XChartTypeContainer;
+using ::com::sun::star::chart2::XColorScheme;
+using ::com::sun::star::chart2::XCoordinateSystem;
+using ::com::sun::star::chart2::XCoordinateSystemContainer;
+using ::com::sun::star::chart2::XChartType;
+using ::com::sun::star::chart2::XDataSeries;
+using ::com::sun::star::chart2::XDataSeriesContainer;
+using ::com::sun::star::chart2::XDiagram;
+using ::com::sun::star::chart2::XFormattedString;
+using ::com::sun::star::chart2::XLegend;
+using ::com::sun::star::chart2::XRegressionCurve;
+using ::com::sun::star::chart2::XRegressionCurveContainer;
+using ::com::sun::star::chart2::XScaling;
+using ::com::sun::star::chart2::XTitle;
+using ::com::sun::star::chart2::XTitled;
+
+using ::com::sun::star::chart2::data::XDataSequence;
+using ::com::sun::star::chart2::data::XDataSource;
+using ::com::sun::star::chart2::data::XLabeledDataSequence;
+
+using ::formula::FormulaGrammar;
+using ::formula::FormulaToken;
+
+namespace cssc = ::com::sun::star::chart;
+namespace cssc2 = ::com::sun::star::chart2;
+
+// Helpers ====================================================================
+
+namespace {
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclChRectangle& rRect )
+{
+ return rStrm << rRect.mnX << rRect.mnY << rRect.mnWidth << rRect.mnHeight;
+}
+
+inline void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec )
+{
+ if( xRec )
+ xRec->Save( rStrm );
+}
+
+/** Saves the passed record (group) together with a leading value record. */
+template< typename Type >
+void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec, sal_uInt16 nRecId, Type nValue )
+{
+ if( xRec )
+ {
+ XclExpValueRecord< Type >( nRecId, nValue ).Save( rStrm );
+ xRec->Save( rStrm );
+ }
+}
+
+template<typename ValueType, typename KeyType>
+void lclSaveRecord(XclExpStream& rStrm, ValueType* pRec, sal_uInt16 nRecId, KeyType nValue)
+{
+ if (pRec)
+ {
+ XclExpValueRecord<KeyType>(nRecId, nValue).Save(rStrm);
+ pRec->Save(rStrm);
+ }
+}
+
+void lclWriteChFrBlockRecord( XclExpStream& rStrm, const XclChFrBlock& rFrBlock, bool bBegin )
+{
+ sal_uInt16 nRecId = bBegin ? EXC_ID_CHFRBLOCKBEGIN : EXC_ID_CHFRBLOCKEND;
+ rStrm.StartRecord( nRecId, 12 );
+ rStrm << nRecId << EXC_FUTUREREC_EMPTYFLAGS << rFrBlock.mnType << rFrBlock.mnContext << rFrBlock.mnValue1 << rFrBlock.mnValue2;
+ rStrm.EndRecord();
+}
+
+template< typename Type >
+inline bool lclIsAutoAnyOrGetValue( Type& rValue, const Any& rAny )
+{
+ return !rAny.hasValue() || !(rAny >>= rValue);
+}
+
+bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogScale )
+{
+ bool bIsAuto = lclIsAutoAnyOrGetValue( rfValue, rAny );
+ if( !bIsAuto && bLogScale )
+ rfValue = log( rfValue ) / log( 10.0 );
+ return bIsAuto;
+}
+
+sal_uInt16 lclGetTimeValue( const XclExpRoot& rRoot, double fSerialDate, sal_uInt16 nTimeUnit )
+{
+ DateTime aDateTime = rRoot.GetDateTimeFromDouble( fSerialDate );
+ switch( nTimeUnit )
+ {
+ case EXC_CHDATERANGE_DAYS:
+ return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
+ case EXC_CHDATERANGE_MONTHS:
+ return ::limit_cast< sal_uInt16, sal_uInt16 >( 12 * (aDateTime.GetYear() - rRoot.GetBaseYear()) + aDateTime.GetMonth() - 1, 0, SAL_MAX_INT16 );
+ case EXC_CHDATERANGE_YEARS:
+ return ::limit_cast< sal_uInt16, sal_uInt16 >( aDateTime.GetYear() - rRoot.GetBaseYear(), 0, SAL_MAX_INT16 );
+ default:
+ OSL_ENSURE( false, "lclGetTimeValue - unexpected time unit" );
+ }
+ return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
+}
+
+bool lclConvertTimeValue( const XclExpRoot& rRoot, sal_uInt16& rnValue, const Any& rAny, sal_uInt16 nTimeUnit )
+{
+ double fSerialDate = 0;
+ bool bAuto = lclIsAutoAnyOrGetValue( fSerialDate, rAny );
+ if( !bAuto )
+ rnValue = lclGetTimeValue( rRoot, fSerialDate, nTimeUnit );
+ return bAuto;
+}
+
+sal_uInt16 lclGetTimeUnit( sal_Int32 nApiTimeUnit )
+{
+ switch( nApiTimeUnit )
+ {
+ case cssc::TimeUnit::DAY: return EXC_CHDATERANGE_DAYS;
+ case cssc::TimeUnit::MONTH: return EXC_CHDATERANGE_MONTHS;
+ case cssc::TimeUnit::YEAR: return EXC_CHDATERANGE_YEARS;
+ default: OSL_ENSURE( false, "lclGetTimeUnit - unexpected time unit" );
+ }
+ return EXC_CHDATERANGE_DAYS;
+}
+
+bool lclConvertTimeInterval( sal_uInt16& rnValue, sal_uInt16& rnTimeUnit, const Any& rAny )
+{
+ cssc::TimeInterval aInterval;
+ bool bAuto = lclIsAutoAnyOrGetValue( aInterval, rAny );
+ if( !bAuto )
+ {
+ rnValue = ::limit_cast< sal_uInt16, sal_Int32 >( aInterval.Number, 1, SAL_MAX_UINT16 );
+ rnTimeUnit = lclGetTimeUnit( aInterval.TimeUnit );
+ }
+ return bAuto;
+}
+
+} // namespace
+
+// Common =====================================================================
+
+/** Stores global data needed in various classes of the Chart export filter. */
+struct XclExpChRootData : public XclChRootData
+{
+ typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
+
+ XclExpChChart& mrChartData; /// The chart data object.
+ XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out.
+ XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out.
+
+ inline explicit XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {}
+
+ /** Registers a new future record level. */
+ void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
+ /** Initializes the current future record level (writes all unwritten CHFRBLOCKBEGIN records). */
+ void InitializeFutureRecBlock( XclExpStream& rStrm );
+ /** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */
+ void FinalizeFutureRecBlock( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
+{
+ maUnwrittenFrBlocks.push_back( rFrBlock );
+}
+
+void XclExpChRootData::InitializeFutureRecBlock( XclExpStream& rStrm )
+{
+ // first call from a future record writes all missing CHFRBLOCKBEGIN records
+ if( !maUnwrittenFrBlocks.empty() )
+ {
+ // write the leading CHFRINFO record
+ if( maWrittenFrBlocks.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_CHFRINFO, 20 );
+ rStrm << EXC_ID_CHFRINFO << EXC_FUTUREREC_EMPTYFLAGS << EXC_CHFRINFO_EXCELXP2003 << EXC_CHFRINFO_EXCELXP2003 << sal_uInt16( 3 );
+ rStrm << sal_uInt16( 0x0850 ) << sal_uInt16( 0x085A ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x086A ) << sal_uInt16( 0x086B );
+ rStrm.EndRecord();
+ }
+ // write all unwritten CHFRBLOCKBEGIN records
+ for( XclChFrBlockVector::const_iterator aIt = maUnwrittenFrBlocks.begin(), aEnd = maUnwrittenFrBlocks.end(); aIt != aEnd; ++aIt )
+ {
+ DBG_ASSERT( aIt->mnType != EXC_CHFRBLOCK_TYPE_UNKNOWN, "XclExpChRootData::InitializeFutureRecBlock - unknown future record block type" );
+ lclWriteChFrBlockRecord( rStrm, *aIt, true );
+ }
+ // move all record infos to vector of written blocks
+ maWrittenFrBlocks.insert( maWrittenFrBlocks.end(), maUnwrittenFrBlocks.begin(), maUnwrittenFrBlocks.end() );
+ maUnwrittenFrBlocks.clear();
+ }
+}
+
+void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !maUnwrittenFrBlocks.empty() || !maWrittenFrBlocks.empty(), "XclExpChRootData::FinalizeFutureRecBlock - no future record level found" );
+ if( !maUnwrittenFrBlocks.empty() )
+ {
+ // no future record has been written, just forget the topmost level
+ maUnwrittenFrBlocks.pop_back();
+ }
+ else if( !maWrittenFrBlocks.empty() )
+ {
+ // write the CHFRBLOCKEND record for the topmost block and delete it
+ lclWriteChFrBlockRecord( rStrm, maWrittenFrBlocks.back(), false );
+ maWrittenFrBlocks.pop_back();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) :
+ XclExpRoot( rRoot ),
+ mxChData( new XclExpChRootData( rChartData ) )
+{
+}
+
+XclExpChRoot::~XclExpChRoot()
+{
+}
+
+Reference< XChartDocument > XclExpChRoot::GetChartDocument() const
+{
+ return mxChData->mxChartDoc;
+}
+
+XclExpChChart& XclExpChRoot::GetChartData() const
+{
+ return mxChData->mrChartData;
+}
+
+const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
+}
+
+const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName );
+}
+
+const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
+}
+
+void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const
+{
+ mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
+}
+
+void XclExpChRoot::FinishConversion() const
+{
+ mxChData->FinishConversion();
+}
+
+bool XclExpChRoot::IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const
+{
+ XclExpPalette& rPal = GetPalette();
+ return rPal.IsSystemColor( nSysColorIdx ) && (rColor == rPal.GetDefColor( nSysColorIdx ));
+}
+
+void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const
+{
+ DBG_ASSERT( GetPalette().IsSystemColor( nSysColorIdx ), "XclExpChRoot::SetSystemColor - invalid color index" );
+ rColor = GetPalette().GetDefColor( nSysColorIdx );
+ rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx );
+}
+
+sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const
+{
+ return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS );
+}
+
+sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const
+{
+ return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS );
+}
+
+XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const
+{
+ XclChRectangle aRect;
+ aRect.mnX = CalcChartXFromHmm( rRect.X );
+ aRect.mnY = CalcChartYFromHmm( rRect.Y );
+ aRect.mnWidth = CalcChartXFromHmm( rRect.Width );
+ aRect.mnHeight = CalcChartYFromHmm( rRect.Height );
+ return aRect;
+}
+
+void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().ReadLineProperties(
+ rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode );
+}
+
+bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ return GetChartPropSetHelper().ReadAreaProperties( rAreaFmt, rPropSet, ePropMode );
+}
+
+void XclExpChRoot::ConvertEscherFormat(
+ XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt,
+ *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode );
+}
+
+sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const
+{
+ XclFontData aFontData;
+ GetFontPropSetHelper().ReadFontProperties( aFontData, rPropSet, EXC_FONTPROPSET_CHART, nScript );
+ return GetFontBuffer().Insert( aFontData, EXC_COLOR_CHARTTEXT );
+}
+
+sal_uInt16 XclExpChRoot::ConvertPieRotation( const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nApiRot = 0;
+ rPropSet.GetProperty( nApiRot, EXC_CHPROP_STARTINGANGLE );
+ return static_cast< sal_uInt16 >( (450 - (nApiRot % 360)) % 360 );
+}
+
+void XclExpChRoot::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
+{
+ mxChData->RegisterFutureRecBlock( rFrBlock );
+}
+
+void XclExpChRoot::InitializeFutureRecBlock( XclExpStream& rStrm )
+{
+ mxChData->InitializeFutureRecBlock( rStrm );
+}
+
+void XclExpChRoot::FinalizeFutureRecBlock( XclExpStream& rStrm )
+{
+ mxChData->FinalizeFutureRecBlock( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChGroupBase::XclExpChGroupBase( const XclExpChRoot& rRoot,
+ sal_uInt16 nFrType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ XclExpChRoot( rRoot ),
+ maFrBlock( nFrType )
+{
+}
+
+XclExpChGroupBase::~XclExpChGroupBase()
+{
+}
+
+void XclExpChGroupBase::Save( XclExpStream& rStrm )
+{
+ // header record
+ XclExpRecord::Save( rStrm );
+ // group records
+ if( HasSubRecords() )
+ {
+ // register the future record context corresponding to this record group
+ RegisterFutureRecBlock( maFrBlock );
+ // CHBEGIN record
+ XclExpEmptyRecord( EXC_ID_CHBEGIN ).Save( rStrm );
+ // embedded records
+ WriteSubRecords( rStrm );
+ // finalize the future records, must be done before the closing CHEND
+ FinalizeFutureRecBlock( rStrm );
+ // CHEND record
+ XclExpEmptyRecord( EXC_ID_CHEND ).Save( rStrm );
+ }
+}
+
+bool XclExpChGroupBase::HasSubRecords() const
+{
+ return true;
+}
+
+void XclExpChGroupBase::SetFutureRecordContext( sal_uInt16 nFrContext, sal_uInt16 nFrValue1, sal_uInt16 nFrValue2 )
+{
+ maFrBlock.mnContext = nFrContext;
+ maFrBlock.mnValue1 = nFrValue1;
+ maFrBlock.mnValue2 = nFrValue2;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFutureRecordBase::XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
+ XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpFutureRecord( eRecType, nRecId, nRecSize ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChFutureRecordBase::Save( XclExpStream& rStrm )
+{
+ InitializeFutureRecBlock( rStrm );
+ XclExpFutureRecord::Save( rStrm );
+}
+
+// Frame formatting ===========================================================
+
+XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) :
+ XclExpRecord( EXC_ID_CHFRAMEPOS, 20 )
+{
+ maData.mnTLMode = nTLMode;
+ maData.mnBRMode = nBRMode;
+}
+
+void XclExpChFramePos::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ),
+ mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChLineFormat::SetDefault( XclChFrameType eDefFrameType )
+{
+ switch( eDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ SetAuto( true );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ SetAuto( false );
+ maData.mnPattern = EXC_CHLINEFORMAT_NONE;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpChLineFormat::SetDefault - unknown frame type" );
+ }
+}
+
+void XclExpChLineFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ rRoot.ConvertLineFormat( maData, rPropSet, rFmtInfo.mePropMode );
+ if( HasLine() )
+ {
+ // detect system color, set color identifier (TODO: detect automatic series line)
+ if( (eObjType != EXC_CHOBJTYPE_LINEARSERIES) && rRoot.IsSystemColor( maData.maColor, rFmtInfo.mnAutoLineColorIdx ) )
+ {
+ // store color index from automatic format data
+ mnColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoLineColorIdx );
+ // try to set automatic mode
+ bool bAuto = (maData.mnPattern == EXC_CHLINEFORMAT_SOLID) && (maData.mnWeight == rFmtInfo.mnAutoLineWeight);
+ ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto );
+ }
+ else
+ {
+ // user defined color - register in palette
+ mnColorId = rRoot.GetPalette().InsertColor( maData.maColor, EXC_COLOR_CHARTLINE );
+ }
+ }
+ else
+ {
+ // no line - set default system color
+ rRoot.SetSystemColor( maData.maColor, mnColorId, EXC_COLOR_CHWINDOWTEXT );
+ }
+}
+
+bool XclExpChLineFormat::IsDefault( XclChFrameType eDefFrameType ) const
+{
+ return
+ ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasLine()) ||
+ ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
+}
+
+void XclExpChLineFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maColor << maData.mnPattern << maData.mnWeight << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ rStrm << rStrm.GetRoot().GetPalette().GetColorIndex( mnColorId );
+}
+
+namespace {
+
+/** Creates a CHLINEFORMAT record from the passed property set. */
+XclExpChLineFormatRef lclCreateLineFormat( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( rRoot ) );
+ xLineFmt->Convert( rRoot, rPropSet, eObjType );
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( rFmtInfo.mbDeleteDefFrame && xLineFmt->IsDefault( rFmtInfo.meDefFrameType ) )
+ xLineFmt.reset();
+ return xLineFmt;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpChAreaFormat::XclExpChAreaFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHAREAFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 16 : 12 ),
+ mnPattColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
+ mnBackColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+bool XclExpChAreaFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ bool bComplexFill = rRoot.ConvertAreaFormat( maData, rPropSet, rFmtInfo.mePropMode );
+ if( HasArea() )
+ {
+ bool bSolid = maData.mnPattern == EXC_PATT_SOLID;
+ // detect system color, set color identifier (TODO: detect automatic series area)
+ if( (eObjType != EXC_CHOBJTYPE_FILLEDSERIES) && rRoot.IsSystemColor( maData.maPattColor, rFmtInfo.mnAutoPattColorIdx ) )
+ {
+ // store color index from automatic format data
+ mnPattColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoPattColorIdx );
+ // set automatic mode
+ ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bSolid );
+ }
+ else
+ {
+ // user defined color - register color in palette
+ mnPattColorId = rRoot.GetPalette().InsertColor( maData.maPattColor, EXC_COLOR_CHARTAREA );
+ }
+ // background color (default system color for solid fills)
+ if( bSolid )
+ rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
+ else
+ mnBackColorId = rRoot.GetPalette().InsertColor( maData.maBackColor, EXC_COLOR_CHARTAREA );
+ }
+ else
+ {
+ // no area - set default system colors
+ rRoot.SetSystemColor( maData.maPattColor, mnPattColorId, EXC_COLOR_CHWINDOWBACK );
+ rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
+ }
+ return bComplexFill;
+}
+
+void XclExpChAreaFormat::SetDefault( XclChFrameType eDefFrameType )
+{
+ switch( eDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ SetAuto( true );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ SetAuto( false );
+ maData.mnPattern = EXC_PATT_NONE;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpChAreaFormat::SetDefault - unknown frame type" );
+ }
+}
+
+bool XclExpChAreaFormat::IsDefault( XclChFrameType eDefFrameType ) const
+{
+ return
+ ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasArea()) ||
+ ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
+}
+
+void XclExpChAreaFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maPattColor << maData.maBackColor << maData.mnPattern << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ rStrm << rPal.GetColorIndex( mnPattColorId ) << rPal.GetColorIndex( mnBackColorId );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChEscherFormat::XclExpChEscherFormat( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_UNKNOWN, EXC_ID_CHESCHERFORMAT ),
+ mnColor1Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
+ mnColor2Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+}
+
+void XclExpChEscherFormat::Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ const XclChFormatInfo& rFmtInfo = GetFormatInfo( eObjType );
+ ConvertEscherFormat( maData, maPicFmt, rPropSet, rFmtInfo.mePropMode );
+ // register colors in palette
+ mnColor1Id = RegisterColor( ESCHER_Prop_fillColor );
+ mnColor2Id = RegisterColor( ESCHER_Prop_fillBackColor );
+}
+
+bool XclExpChEscherFormat::IsValid() const
+{
+ return maData.mxEscherSet;
+}
+
+void XclExpChEscherFormat::Save( XclExpStream& rStrm )
+{
+ if( maData.mxEscherSet )
+ {
+ // replace RGB colors with palette indexes in the Escher container
+ const XclExpPalette& rPal = GetPalette();
+ maData.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, 0x08000000 | rPal.GetColorIndex( mnColor1Id ) );
+ maData.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x08000000 | rPal.GetColorIndex( mnColor2Id ) );
+
+ // save the record group
+ XclExpChGroupBase::Save( rStrm );
+ }
+}
+
+bool XclExpChEscherFormat::HasSubRecords() const
+{
+ // no subrecords for gradients
+ return maPicFmt.mnBmpMode != EXC_CHPICFORMAT_NONE;
+}
+
+void XclExpChEscherFormat::WriteSubRecords( XclExpStream& rStrm )
+{
+ rStrm.StartRecord( EXC_ID_CHPICFORMAT, 14 );
+ rStrm << maPicFmt.mnBmpMode << maPicFmt.mnFormat << maPicFmt.mnFlags << maPicFmt.mfScale;
+ rStrm.EndRecord();
+}
+
+sal_uInt32 XclExpChEscherFormat::RegisterColor( sal_uInt16 nPropId )
+{
+ sal_uInt32 nBGRValue;
+ if( maData.mxEscherSet && maData.mxEscherSet->GetOpt( nPropId, nBGRValue ) )
+ {
+ // swap red and blue
+ Color aColor( RGB_COLORDATA(
+ COLORDATA_BLUE( nBGRValue ),
+ COLORDATA_GREEN( nBGRValue ),
+ COLORDATA_RED( nBGRValue ) ) );
+ return GetPalette().InsertColor( aColor, EXC_COLOR_CHARTAREA );
+ }
+ return XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK );
+}
+
+void XclExpChEscherFormat::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( maData.mxEscherSet, "XclExpChEscherFormat::WriteBody - missing property container" );
+ // write Escher property container via temporary memory stream
+ SvMemoryStream aMemStrm;
+ maData.mxEscherSet->Commit( aMemStrm );
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ rStrm.CopyFromStream( aMemStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrameBase::XclExpChFrameBase()
+{
+}
+
+XclExpChFrameBase::~XclExpChFrameBase()
+{
+}
+
+void XclExpChFrameBase::ConvertFrameBase( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ // line format
+ mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
+ mxLineFmt->Convert( rRoot, rPropSet, eObjType );
+ // area format (only for frame objects)
+ if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
+ {
+ mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
+ bool bComplexFill = mxAreaFmt->Convert( rRoot, rPropSet, eObjType );
+ if( (rRoot.GetBiff() == EXC_BIFF8) && bComplexFill )
+ {
+ mxEscherFmt.reset( new XclExpChEscherFormat( rRoot ) );
+ mxEscherFmt->Convert( rPropSet, eObjType );
+ if( mxEscherFmt->IsValid() )
+ mxAreaFmt->SetAuto( false );
+ else
+ mxEscherFmt.reset();
+ }
+ }
+}
+
+void XclExpChFrameBase::SetDefaultFrameBase( const XclExpChRoot& rRoot,
+ XclChFrameType eDefFrameType, bool bIsFrame )
+{
+ // line format
+ mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
+ mxLineFmt->SetDefault( eDefFrameType );
+ // area format (only for frame objects)
+ if( bIsFrame )
+ {
+ mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
+ mxAreaFmt->SetDefault( eDefFrameType );
+ mxEscherFmt.reset();
+ }
+}
+
+bool XclExpChFrameBase::IsDefaultFrameBase( XclChFrameType eDefFrameType ) const
+{
+ return
+ (!mxLineFmt || mxLineFmt->IsDefault( eDefFrameType )) &&
+ (!mxAreaFmt || mxAreaFmt->IsDefault( eDefFrameType ));
+}
+
+void XclExpChFrameBase::WriteFrameRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxLineFmt );
+ lclSaveRecord( rStrm, mxAreaFmt );
+ lclSaveRecord( rStrm, mxEscherFmt );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrame::XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_FRAME, EXC_ID_CHFRAME, 4 ),
+ meObjType( eObjType )
+{
+}
+
+void XclExpChFrame::Convert( const ScfPropertySet& rPropSet )
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+}
+
+void XclExpChFrame::SetAutoFlags( bool bAutoPos, bool bAutoSize )
+{
+ ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOPOS, bAutoPos );
+ ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOSIZE, bAutoSize );
+}
+
+bool XclExpChFrame::IsDefault() const
+{
+ return IsDefaultFrameBase( GetFormatInfo( meObjType ).meDefFrameType );
+}
+
+bool XclExpChFrame::IsDeleteable() const
+{
+ return IsDefault() && GetFormatInfo( meObjType ).mbDeleteDefFrame;
+}
+
+void XclExpChFrame::Save( XclExpStream& rStrm )
+{
+ switch( meObjType )
+ {
+ // wall/floor frame without CHFRAME header record
+ case EXC_CHOBJTYPE_WALL3D:
+ case EXC_CHOBJTYPE_FLOOR3D:
+ WriteFrameRecords( rStrm );
+ break;
+ default:
+ XclExpChGroupBase::Save( rStrm );
+ }
+}
+
+void XclExpChFrame::WriteSubRecords( XclExpStream& rStrm )
+{
+ WriteFrameRecords( rStrm );
+}
+
+void XclExpChFrame::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnFormat << maData.mnFlags;
+}
+
+namespace {
+
+/** Creates a CHFRAME record from the passed property set. */
+XclExpChFrameRef lclCreateFrame( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ XclExpChFrameRef xFrame( new XclExpChFrame( rRoot, eObjType ) );
+ xFrame->Convert( rPropSet );
+ if( xFrame->IsDeleteable() )
+ xFrame.reset();
+ return xFrame;
+}
+
+} // namespace
+
+// Source links ===============================================================
+
+namespace {
+
+void lclAddDoubleRefData(
+ ScTokenArray& orArray, const FormulaToken& rToken,
+ SCsTAB nScTab1, SCsCOL nScCol1, SCsROW nScRow1,
+ SCsTAB nScTab2, SCsCOL nScCol2, SCsROW nScRow2 )
+{
+ ScComplexRefData aComplexRef;
+ aComplexRef.InitFlags();
+ aComplexRef.Ref1.SetFlag3D( true );
+ aComplexRef.Ref1.nTab = nScTab1;
+ aComplexRef.Ref1.nCol = nScCol1;
+ aComplexRef.Ref1.nRow = nScRow1;
+ aComplexRef.Ref2.nTab = nScTab2;
+ aComplexRef.Ref2.nCol = nScCol2;
+ aComplexRef.Ref2.nRow = nScRow2;
+
+ if( orArray.GetLen() > 0 )
+ orArray.AddOpCode( ocUnion );
+
+ DBG_ASSERT( (rToken.GetType() == ::formula::svDoubleRef) || (rToken.GetType() == ::formula::svExternalDoubleRef),
+ "lclAddDoubleRefData - double reference token expected");
+ if( rToken.GetType() == ::formula::svExternalDoubleRef )
+ orArray.AddExternalDoubleReference( rToken.GetIndex(), rToken.GetString(), aComplexRef );
+ else
+ orArray.AddDoubleReference( aComplexRef );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpChSourceLink::XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType ) :
+ XclExpRecord( EXC_ID_CHSOURCELINK ),
+ XclExpChRoot( rRoot )
+{
+ maData.mnDestType = nDestType;
+ maData.mnLinkType = EXC_CHSRCLINK_DIRECTLY;
+}
+
+sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount )
+{
+ mxLinkFmla.reset();
+ maData.mnLinkType = EXC_CHSRCLINK_DEFAULT;
+
+ if( !xDataSeq.is() )
+ return nDefCount;
+
+ // Compile the range representation string into token array. Note that the
+ // source range text depends on the current grammar.
+ OUString aRangeRepr = xDataSeq->getSourceRangeRepresentation();
+ ScCompiler aComp( GetDocPtr(), ScAddress() );
+ aComp.SetGrammar( GetDocPtr()->GetGrammar() );
+ ScTokenArray* pArray = aComp.CompileString( aRangeRepr );
+ if( !pArray )
+ return nDefCount;
+
+ ScTokenArray aArray;
+ sal_uInt32 nValueCount = 0;
+ pArray->Reset();
+ for( const FormulaToken* pToken = pArray->First(); pToken; pToken = pArray->Next() )
+ {
+ switch( pToken->GetType() )
+ {
+ case ::formula::svSingleRef:
+ case ::formula::svExternalSingleRef:
+ // for a single ref token, just add it to the new token array as is
+ if( aArray.GetLen() > 0 )
+ aArray.AddOpCode( ocUnion );
+ aArray.AddToken( *pToken );
+ ++nValueCount;
+ break;
+
+ case ::formula::svDoubleRef:
+ case ::formula::svExternalDoubleRef:
+ {
+ // split 3-dimensional ranges into single sheets
+ const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
+ const ScSingleRefData& rRef1 = rComplexRef.Ref1;
+ const ScSingleRefData& rRef2 = rComplexRef.Ref2;
+ for( SCsTAB nScTab = rRef1.nTab; nScTab <= rRef2.nTab; ++nScTab )
+ {
+ // split 2-dimensional ranges into single columns
+ if( bSplitToColumns && (rRef1.nCol < rRef2.nCol) && (rRef1.nRow < rRef2.nRow) )
+ for( SCsCOL nScCol = rRef1.nCol; nScCol <= rRef2.nCol; ++nScCol )
+ lclAddDoubleRefData( aArray, *pToken, nScTab, nScCol, rRef1.nRow, nScTab, nScCol, rRef2.nRow );
+ else
+ lclAddDoubleRefData( aArray, *pToken, nScTab, rRef1.nCol, rRef1.nRow, nScTab, rRef2.nCol, rRef2.nRow );
+ }
+ sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
+ sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
+ sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
+ nValueCount += nCols * nRows * nTabs;
+ }
+ break;
+
+ default:;
+ }
+ }
+
+ const ScAddress aBaseCell;
+ mxLinkFmla = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aArray, &aBaseCell );
+ maData.mnLinkType = EXC_CHSRCLINK_WORKSHEET;
+ return ulimit_cast< sal_uInt16 >( nValueCount, EXC_CHDATAFORMAT_MAXPOINTCOUNT );
+}
+
+sal_uInt16 XclExpChSourceLink::ConvertStringSequence( const Sequence< Reference< XFormattedString > >& rStringSeq )
+{
+ mxString.reset();
+ sal_uInt16 nFontIdx = EXC_FONT_APP;
+ if( rStringSeq.hasElements() )
+ {
+ mxString = XclExpStringHelper::CreateString( GetRoot(), String::EmptyString(), EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
+ Reference< XBreakIterator > xBreakIt = GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ // convert all formatted string entries from the sequence
+ const Reference< XFormattedString >* pBeg = rStringSeq.getConstArray();
+ const Reference< XFormattedString >* pEnd = pBeg + rStringSeq.getLength();
+ for( const Reference< XFormattedString >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ if( pIt->is() )
+ {
+ sal_uInt16 nWstrnFontIdx = EXC_FONT_NOTFOUND;
+ sal_uInt16 nAsianFontIdx = EXC_FONT_NOTFOUND;
+ sal_uInt16 nCmplxFontIdx = EXC_FONT_NOTFOUND;
+ OUString aText = (*pIt)->getString();
+ ScfPropertySet aStrProp( *pIt );
+
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( GetRoot(), aText );
+
+ // process all script portions
+ sal_Int32 nPortionPos = 0;
+ sal_Int32 nTextLen = aText.getLength();
+ while( nPortionPos < nTextLen )
+ {
+ // get script type and end position of next script portion
+ sal_Int16 nScript = xBreakIt->getScriptType( aText, nPortionPos );
+ sal_Int32 nPortionEnd = xBreakIt->endOfScript( aText, nPortionPos, nScript );
+
+ // reuse previous script for following weak portions
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = mxString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *mxString, GetRoot(), aText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
+ if( nXclPortionStart < mxString->Len() )
+ {
+ // find font index variable dependent on script type
+ sal_uInt16& rnFontIdx = (nScript == ApiScriptType::COMPLEX) ? nCmplxFontIdx :
+ ((nScript == ApiScriptType::ASIAN) ? nAsianFontIdx : nWstrnFontIdx);
+
+ // insert font into buffer (if not yet done)
+ if( rnFontIdx == EXC_FONT_NOTFOUND )
+ rnFontIdx = ConvertFont( aStrProp, nScript );
+
+ // insert font index into format run vector
+ mxString->AppendFormat( nXclPortionStart, rnFontIdx );
+ }
+
+ // go to next script portion
+ nLastScript = nScript;
+ nPortionPos = nPortionEnd;
+ }
+ }
+ }
+ if( !mxString->IsEmpty() )
+ {
+ // get leading font index
+ const XclFormatRunVec& rFormats = mxString->GetFormats();
+ DBG_ASSERT( !rFormats.empty() && (rFormats.front().mnChar == 0),
+ "XclExpChSourceLink::ConvertStringSequenc - missing leading format" );
+ // remove leading format run, if entire string is equally formatted
+ if( rFormats.size() == 1 )
+ nFontIdx = mxString->RemoveLeadingFont();
+ else if( !rFormats.empty() )
+ nFontIdx = rFormats.front().mnFontIdx;
+ // add trailing format run, if string is rich-formatted
+ if( mxString->IsRich() )
+ mxString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ }
+ return nFontIdx;
+}
+
+void XclExpChSourceLink::ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent )
+{
+ sal_Int32 nApiNumFmt = 0;
+ if( bPercent ? rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_PERCENTAGENUMFMT ) : rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
+ {
+ ::set_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
+ maData.mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
+ }
+}
+
+void XclExpChSourceLink::AppendString( const String& rStr )
+{
+ if (!mxString)
+ return;
+ XclExpStringHelper::AppendString( *mxString, GetRoot(), rStr );
+}
+
+void XclExpChSourceLink::Save( XclExpStream& rStrm )
+{
+ // CHFORMATRUNS record
+ if( mxString && mxString->IsRich() )
+ {
+ sal_Size nRecSize = (1 + mxString->GetFormatsCount()) * ((GetBiff() == EXC_BIFF8) ? 2 : 1);
+ rStrm.StartRecord( EXC_ID_CHFORMATRUNS, nRecSize );
+ mxString->WriteFormats( rStrm, true );
+ rStrm.EndRecord();
+ }
+ // CHSOURCELINK record
+ XclExpRecord::Save( rStrm );
+ // CHSTRING record
+ if( mxString && !mxString->IsEmpty() )
+ {
+ rStrm.StartRecord( EXC_ID_CHSTRING, 2 + mxString->GetSize() );
+ rStrm << sal_uInt16( 0 ) << *mxString;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpChSourceLink::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnDestType
+ << maData.mnLinkType
+ << maData.mnFlags
+ << maData.mnNumFmtIdx
+ << mxLinkFmla;
+}
+
+// Text =======================================================================
+
+XclExpChFont::XclExpChFont( sal_uInt16 nFontIdx ) :
+ XclExpUInt16Record( EXC_ID_CHFONT, nFontIdx )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChObjectLink::XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos ) :
+ XclExpRecord( EXC_ID_CHOBJECTLINK, 6 )
+{
+ maData.mnTarget = nLinkTarget;
+ maData.maPointPos = rPointPos;
+}
+
+void XclExpChObjectLink::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnTarget << maData.maPointPos.mnSeriesIdx << maData.maPointPos.mnPointIdx;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFrLabelProps::XclExpChFrLabelProps( const XclExpChRoot& rRoot ) :
+ XclExpChFutureRecordBase( rRoot, EXC_FUTUREREC_UNUSEDREF, EXC_ID_CHFRLABELPROPS, 4 )
+{
+}
+
+void XclExpChFrLabelProps::Convert( const ScfPropertySet& rPropSet, bool bShowSeries,
+ bool bShowCateg, bool bShowValue, bool bShowPercent, bool bShowBubble )
+{
+ // label value flags
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWSERIES, bShowSeries );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWCATEG, bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWVALUE, bShowValue );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWPERCENT, bShowPercent );
+ ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWBUBBLE, bShowBubble );
+
+ // label value separator
+ rPropSet.GetStringProperty( maData.maSeparator, EXC_CHPROP_LABELSEPARATOR );
+ if( maData.maSeparator.Len() == 0 )
+ maData.maSeparator = String( sal_Unicode( ' ' ) );
+}
+
+void XclExpChFrLabelProps::WriteBody( XclExpStream& rStrm )
+{
+ XclExpString aXclSep( maData.maSeparator, EXC_STR_FORCEUNICODE | EXC_STR_SMARTFLAGS );
+ rStrm << maData.mnFlags << aXclSep;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChFontBase::~XclExpChFontBase()
+{
+}
+
+void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx )
+{
+ if( const XclExpFont* pFont = rRoot.GetFontBuffer().GetFont( nFontIdx ) )
+ {
+ XclExpChFontRef xFont( new XclExpChFont( nFontIdx ) );
+ SetFont( xFont, pFont->GetFontData().maColor, pFont->GetFontColorId() );
+ }
+}
+
+void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet )
+{
+ ConvertFontBase( rRoot, rRoot.ConvertFont( rPropSet, rRoot.GetDefApiScript() ) );
+}
+
+void XclExpChFontBase::ConvertRotationBase(
+ const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked )
+{
+ sal_uInt16 nRotation = rRoot.GetChartPropSetHelper().ReadRotationProperties( rPropSet, bSupportsStacked );
+ SetRotation( nRotation );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChText::XclExpChText( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TEXT, EXC_ID_CHTEXT, (rRoot.GetBiff() == EXC_BIFF8) ? 32 : 26 ),
+ mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChText::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
+{
+ mxFont = xFont;
+ maData.maTextColor = rColor;
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, rColor == COL_AUTO );
+ mnTextColorId = nColorId;
+}
+
+void XclExpChText::SetRotation( sal_uInt16 nRotation )
+{
+ maData.mnRotation = nRotation;
+ ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 8, 3 );
+}
+
+void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget, const String* pSubTitle )
+{
+ switch( nTarget )
+ {
+ case EXC_CHOBJLINK_TITLE: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_TITLE ); break;
+ case EXC_CHOBJLINK_YAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 1 ); break;
+ case EXC_CHOBJLINK_XAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 0 ); break;
+ case EXC_CHOBJLINK_ZAXIS: SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 2 ); break;
+ }
+
+ mxSrcLink.reset();
+ mxObjLink.reset( new XclExpChObjectLink( nTarget, XclChDataPointPos( 0, 0 ) ) );
+
+ if( xTitle.is() )
+ {
+ // title frame formatting
+ ScfPropertySet aTitleProp( xTitle );
+ mxFrame = lclCreateFrame( GetChRoot(), aTitleProp, EXC_CHOBJTYPE_TEXT );
+
+ // string sequence
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ sal_uInt16 nFontIdx = mxSrcLink->ConvertStringSequence( xTitle->getText() );
+ if (pSubTitle)
+ {
+ // append subtitle as the 2nd line of the title.
+ String aSubTitle = String::CreateFromAscii("\n");
+ aSubTitle.Append(*pSubTitle);
+ mxSrcLink->AppendString(aSubTitle);
+ }
+
+ ConvertFontBase( GetChRoot(), nFontIdx );
+
+ // rotation
+ ConvertRotationBase( GetChRoot(), aTitleProp, true );
+
+ // manual text position - only for main title
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
+ if( nTarget == EXC_CHOBJLINK_TITLE )
+ {
+ Any aRelPos;
+ if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try
+ {
+ // calculate absolute position for CHTEXT record
+ Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW );
+ ::com::sun::star::awt::Point aPos = xTitleShape->getPosition();
+ ::com::sun::star::awt::Size aSize = xTitleShape->getSize();
+ ::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height );
+ maData.maRect = CalcChartRectFromHmm( aRect );
+ ::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 );
+ // manual title position implies manual plot area
+ GetChartData().SetManualPlotArea();
+ // calculate the default title position in chart units
+ sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 );
+ sal_Int32 nDefPosY = 85;
+ // set the position relative to the standard position
+ XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect;
+ rFrameRect.mnX = maData.maRect.mnX - nDefPosX;
+ rFrameRect.mnY = maData.maRect.mnY - nDefPosY;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ else
+ {
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED );
+ }
+}
+
+void XclExpChText::ConvertLegend( const ScfPropertySet& rPropSet )
+{
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOGEN );
+ ConvertFontBase( GetChRoot(), rPropSet );
+}
+
+bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
+ const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos )
+{
+ SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx );
+
+ cssc2::DataPointLabel aPointLabel;
+ if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) )
+ return false;
+
+ // percentage only allowed in pie and donut charts
+ bool bIsPie = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE;
+ // bubble sizes only allowed in bubble charts
+ bool bIsBubble = rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES;
+ DBG_ASSERT( (GetBiff() == EXC_BIFF8) || !bIsBubble, "XclExpChText::ConvertDataLabel - bubble charts only in BIFF8" );
+
+ // raw show flags
+ bool bShowValue = !bIsBubble && aPointLabel.ShowNumber; // Chart2 uses 'ShowNumber' for bubble size
+ bool bShowPercent = bIsPie && aPointLabel.ShowNumberInPercent; // percentage only in pie/donut charts
+ bool bShowCateg = aPointLabel.ShowCategoryName;
+ bool bShowBubble = bIsBubble && aPointLabel.ShowNumber; // Chart2 uses 'ShowNumber' for bubble size
+ bool bShowAny = bShowValue || bShowPercent || bShowCateg || bShowBubble;
+
+ // create the CHFRLABELPROPS record for extended settings in BIFF8
+ if( bShowAny && (GetBiff() == EXC_BIFF8) )
+ {
+ mxLabelProps.reset( new XclExpChFrLabelProps( GetChRoot() ) );
+ mxLabelProps->Convert( rPropSet, false, bShowCateg, bShowValue, bShowPercent, bShowBubble );
+ }
+
+ // restrict to combinations allowed in CHTEXT
+ if( bShowPercent ) bShowValue = false; // percent wins over value
+ if( bShowValue ) bShowCateg = false; // value wins over category
+ if( bShowValue || bShowCateg ) bShowBubble = false; // value or category wins over bubble size
+
+ // set all flags
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bShowValue );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bShowPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bShowPercent && bShowCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWBUBBLE, bShowBubble );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL, bShowAny && aPointLabel.ShowLegendSymbol );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bShowAny );
+
+ if( bShowAny )
+ {
+ // font settings
+ ConvertFontBase( GetChRoot(), rPropSet );
+ ConvertRotationBase( GetChRoot(), rPropSet, false );
+ // label placement
+ sal_Int32 nPlacement = 0;
+ sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO;
+ if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) )
+ {
+ using namespace cssc::DataLabelPlacement;
+ if( nPlacement == rTypeInfo.mnDefaultLabelPos )
+ {
+ nLabelPos = EXC_CHTEXT_POS_DEFAULT;
+ }
+ else switch( nPlacement )
+ {
+ case AVOID_OVERLAP: nLabelPos = EXC_CHTEXT_POS_AUTO; break;
+ case CENTER: nLabelPos = EXC_CHTEXT_POS_CENTER; break;
+ case TOP: nLabelPos = EXC_CHTEXT_POS_ABOVE; break;
+ case TOP_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case BOTTOM_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
+ case BOTTOM: nLabelPos = EXC_CHTEXT_POS_BELOW; break;
+ case BOTTOM_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case TOP_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
+ case INSIDE: nLabelPos = EXC_CHTEXT_POS_INSIDE; break;
+ case OUTSIDE: nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break;
+ case NEAR_ORIGIN: nLabelPos = EXC_CHTEXT_POS_AXIS; break;
+ default: DBG_ERRORFILE( "XclExpChText::ConvertDataLabel - unknown label placement type" );
+ }
+ }
+ ::insert_value( maData.mnFlags2, nLabelPos, 0, 4 );
+ // source link (contains number format)
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ if( bShowValue || bShowPercent )
+ // percentage format wins over value format
+ mxSrcLink->ConvertNumFmt( rPropSet, bShowPercent );
+ // object link
+ mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
+ }
+
+ /* Return true to indicate valid label settings:
+ - for existing labels at entire series
+ - for any settings at single data point (to be able to delete a point label) */
+ return bShowAny || (rPointPos.mnPointIdx != EXC_CHDATAFORMAT_ALLPOINTS);
+}
+
+void XclExpChText::ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos )
+{
+ // required flags
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ); // must set this to make equation visible in Excel
+ // frame formatting
+ mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_TEXT );
+ // font settings
+ maData.mnHAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
+ maData.mnVAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
+ ConvertFontBase( GetChRoot(), rPropSet );
+ // source link (contains number format)
+ mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ mxSrcLink->ConvertNumFmt( rPropSet, false );
+ // object link
+ mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
+}
+
+sal_uInt16 XclExpChText::GetAttLabelFlags() const
+{
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWVALUE, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWPERCENT, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEGPERC, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC ) );
+ ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEG, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ) );
+ return nFlags;
+}
+
+void XclExpChText::WriteSubRecords( XclExpStream& rStrm )
+{
+ // CHFRAMEPOS record
+ lclSaveRecord( rStrm, mxFramePos );
+ // CHFONT record
+ lclSaveRecord( rStrm, mxFont );
+ // CHSOURCELINK group
+ lclSaveRecord( rStrm, mxSrcLink );
+ // CHFRAME group
+ lclSaveRecord( rStrm, mxFrame );
+ // CHOBJECTLINK record
+ lclSaveRecord( rStrm, mxObjLink );
+ // CHFRLABELPROPS record
+ lclSaveRecord( rStrm, mxLabelProps );
+}
+
+void XclExpChText::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnHAlign
+ << maData.mnVAlign
+ << maData.mnBackMode
+ << maData.maTextColor
+ << maData.maRect
+ << maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ rStrm << GetPalette().GetColorIndex( mnTextColorId )
+ << maData.mnFlags2
+ << maData.mnRotation;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Creates and returns an Excel text object from the passed title. */
+XclExpChTextRef lclCreateTitle( const XclExpChRoot& rRoot, Reference< XTitled > xTitled, sal_uInt16 nTarget,
+ const String* pSubTitle = NULL )
+{
+ Reference< XTitle > xTitle;
+ if( xTitled.is() )
+ xTitle = xTitled->getTitleObject();
+
+ XclExpChTextRef xText( new XclExpChText( rRoot ) );
+ xText->ConvertTitle( xTitle, nTarget, pSubTitle );
+ /* Do not delete the CHTEXT group for the main title. A missing CHTEXT
+ will be interpreted as auto-generated title showing the series title in
+ charts that contain exactly one data series. */
+ if( (nTarget != EXC_CHOBJLINK_TITLE) && !xText->HasString() )
+ xText.reset();
+
+ return xText;
+}
+
+}
+
+// Data series ================================================================
+
+XclExpChMarkerFormat::XclExpChMarkerFormat( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHMARKERFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 20 : 12 ),
+ mnLineColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) ),
+ mnFillColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
+{
+}
+
+void XclExpChMarkerFormat::Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
+{
+ rRoot.GetChartPropSetHelper().ReadMarkerProperties( maData, rPropSet, nFormatIdx );
+ /* Set marker line/fill color to series line color.
+ TODO: remove this if OOChart supports own colors in markers. */
+ Color aLineColor;
+ if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
+ maData.maLineColor = maData.maFillColor = aLineColor;
+ // register colors in palette
+ RegisterColors( rRoot );
+}
+
+void XclExpChMarkerFormat::ConvertStockSymbol( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, bool bCloseSymbol )
+{
+ // clear the automatic flag
+ ::set_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
+ // symbol type and color
+ if( bCloseSymbol )
+ {
+ // set symbol type for the 'close' data series
+ maData.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ;
+ maData.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE;
+ // set symbol line/fill color to series line color
+ Color aLineColor;
+ if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
+ {
+ maData.maLineColor = maData.maFillColor = aLineColor;
+ RegisterColors( rRoot );
+ }
+ }
+ else
+ {
+ // set invisible symbol
+ maData.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
+ }
+}
+
+void XclExpChMarkerFormat::RegisterColors( const XclExpChRoot& rRoot )
+{
+ if( HasMarker() )
+ {
+ if( HasLineColor() )
+ mnLineColorId = rRoot.GetPalette().InsertColor( maData.maLineColor, EXC_COLOR_CHARTLINE );
+ if( HasFillColor() )
+ mnFillColorId = rRoot.GetPalette().InsertColor( maData.maFillColor, EXC_COLOR_CHARTAREA );
+ }
+}
+
+void XclExpChMarkerFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maLineColor << maData.maFillColor << maData.mnMarkerType << maData.mnFlags;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ rStrm << rPal.GetColorIndex( mnLineColorId ) << rPal.GetColorIndex( mnFillColorId ) << maData.mnMarkerSize;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChPieFormat::XclExpChPieFormat() :
+ XclExpUInt16Record( EXC_ID_CHPIEFORMAT, 0 )
+{
+}
+
+void XclExpChPieFormat::Convert( const ScfPropertySet& rPropSet )
+{
+ double fApiDist(0.0);
+ if( rPropSet.GetProperty( fApiDist, EXC_CHPROP_OFFSET ) )
+ SetValue( limit_cast< sal_uInt16 >( fApiDist * 100.0, 0, 100 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCh3dDataFormat::XclExpCh3dDataFormat() :
+ XclExpRecord( EXC_ID_CH3DDATAFORMAT, 2 )
+{
+}
+
+void XclExpCh3dDataFormat::Convert( const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nApiType(0);
+ if( rPropSet.GetProperty( nApiType, EXC_CHPROP_GEOMETRY3D ) )
+ {
+ using namespace cssc2::DataPointGeometry3D;
+ switch( nApiType )
+ {
+ case CUBOID:
+ maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
+ maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
+ break;
+ case PYRAMID:
+ maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
+ maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
+ break;
+ case CYLINDER:
+ maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
+ maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
+ break;
+ case CONE:
+ maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
+ maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpCh3dDataFormat::Convert - unknown 3D bar format" );
+ }
+ }
+}
+
+void XclExpCh3dDataFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnBase << maData.mnTop;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChAttachedLabel::XclExpChAttachedLabel( sal_uInt16 nFlags ) :
+ XclExpUInt16Record( EXC_ID_CHATTACHEDLABEL, nFlags )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChDataFormat::XclExpChDataFormat( const XclExpChRoot& rRoot,
+ const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DATAFORMAT, EXC_ID_CHDATAFORMAT, 8 )
+{
+ maData.maPointPos = rPointPos;
+ maData.mnFormatIdx = nFormatIdx;
+}
+
+void XclExpChDataFormat::ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo )
+{
+ // line and area formatting
+ ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType() );
+
+ // data point symbols
+ bool bIsFrame = rTypeInfo.IsSeriesFrameFormat();
+ if( !bIsFrame )
+ {
+ mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
+ mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx );
+ }
+
+ // pie segments
+ if( rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE )
+ {
+ mxPieFmt.reset( new XclExpChPieFormat );
+ mxPieFmt->Convert( rPropSet );
+ }
+
+ // 3D bars (only allowed for entire series in BIFF8)
+ if( IsSeriesFormat() && (GetBiff() == EXC_BIFF8) && rTypeInfo.mb3dChart && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
+ {
+ mx3dDataFmt.reset( new XclExpCh3dDataFormat );
+ mx3dDataFmt->Convert( rPropSet );
+ }
+
+ // spline
+ if( IsSeriesFormat() && rTypeInfo.mbSpline && !bIsFrame )
+ mxSeriesFmt.reset( new XclExpUInt16Record( EXC_ID_CHSERIESFORMAT, EXC_CHSERIESFORMAT_SMOOTHED ) );
+
+ // data point labels
+ XclExpChTextRef xLabel( new XclExpChText( GetChRoot() ) );
+ if( xLabel->ConvertDataLabel( rPropSet, rTypeInfo, maData.maPointPos ) )
+ {
+ // CHTEXT groups for data labels are stored in global CHCHART group
+ GetChartData().SetDataLabel( xLabel );
+ mxAttLabel.reset( new XclExpChAttachedLabel( xLabel->GetAttLabelFlags() ) );
+ }
+}
+
+void XclExpChDataFormat::ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol )
+{
+ // set line format to invisible
+ SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, false );
+ // set symbols to invisible or to 'close' series symbol
+ mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
+ mxMarkerFmt->ConvertStockSymbol( GetChRoot(), rPropSet, bCloseSymbol );
+}
+
+void XclExpChDataFormat::ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, eObjType );
+}
+
+void XclExpChDataFormat::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mx3dDataFmt );
+ WriteFrameRecords( rStrm );
+ lclSaveRecord( rStrm, mxPieFmt );
+ lclSaveRecord( rStrm, mxMarkerFmt );
+ lclSaveRecord( rStrm, mxSeriesFmt );
+ lclSaveRecord( rStrm, mxAttLabel );
+}
+
+void XclExpChDataFormat::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maPointPos.mnPointIdx
+ << maData.maPointPos.mnSeriesIdx
+ << maData.mnFormatIdx
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChSerTrendLine::XclExpChSerTrendLine( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHSERTRENDLINE, 28 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+bool XclExpChSerTrendLine::Convert( Reference< XRegressionCurve > xRegCurve, sal_uInt16 nSeriesIdx )
+{
+ if( !xRegCurve.is() )
+ return false;
+
+ // trend line type
+ ScfPropertySet aCurveProp( xRegCurve );
+ OUString aService = aCurveProp.GetServiceName();
+ if( aService == SERVICE_CHART2_LINEARREGCURVE )
+ {
+ maData.mnLineType = EXC_CHSERTREND_POLYNOMIAL;
+ maData.mnOrder = 1;
+ }
+ else if( aService == SERVICE_CHART2_EXPREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_EXPONENTIAL;
+ else if( aService == SERVICE_CHART2_LOGREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_LOGARITHMIC;
+ else if( aService == SERVICE_CHART2_POTREGCURVE )
+ maData.mnLineType = EXC_CHSERTREND_POWER;
+ else
+ return false;
+
+ // line formatting
+ XclChDataPointPos aPointPos( nSeriesIdx );
+ mxDataFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, 0 ) );
+ mxDataFmt->ConvertLine( aCurveProp, EXC_CHOBJTYPE_TRENDLINE );
+
+ // #i83100# show equation and correlation coefficient
+ ScfPropertySet aEquationProp( xRegCurve->getEquationProperties() );
+ maData.mnShowEquation = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWEQUATION ) ? 1 : 0;
+ maData.mnShowRSquared = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWCORRELATION ) ? 1 : 0;
+
+ // #i83100# formatting of the equation text box
+ if( (maData.mnShowEquation != 0) || (maData.mnShowRSquared != 0) )
+ {
+ mxLabel.reset( new XclExpChText( GetChRoot() ) );
+ mxLabel->ConvertTrendLineEquation( aEquationProp, aPointPos );
+ }
+
+ // missing features
+ // #i20819# polynomial trend lines
+ // #i66819# moving average trend lines
+ // #i5085# manual trend line size
+ // #i34093# manual crossing point
+ return true;
+}
+
+void XclExpChSerTrendLine::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnLineType
+ << maData.mnOrder
+ << maData.mfIntercept
+ << maData.mnShowEquation
+ << maData.mnShowRSquared
+ << maData.mfForecastFor
+ << maData.mfForecastBack;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChSerErrorBar::XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType ) :
+ XclExpRecord( EXC_ID_CHSERERRORBAR, 14 ),
+ XclExpChRoot( rRoot )
+{
+ maData.mnBarType = nBarType;
+}
+
+bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet )
+{
+ sal_Int32 nBarStyle = 0;
+ bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE );
+ if( bOk )
+ {
+ switch( nBarStyle )
+ {
+ case cssc::ErrorBarStyle::ABSOLUTE:
+ maData.mnSourceType = EXC_CHSERERR_FIXED;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
+ break;
+ case cssc::ErrorBarStyle::RELATIVE:
+ maData.mnSourceType = EXC_CHSERERR_PERCENT;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
+ break;
+ case cssc::ErrorBarStyle::STANDARD_DEVIATION:
+ maData.mnSourceType = EXC_CHSERERR_STDDEV;
+ rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_WEIGHT );
+ break;
+ case cssc::ErrorBarStyle::STANDARD_ERROR:
+ maData.mnSourceType = EXC_CHSERERR_STDERR;
+ break;
+ case cssc::ErrorBarStyle::FROM_DATA:
+ {
+ bOk = false;
+ maData.mnSourceType = EXC_CHSERERR_CUSTOM;
+ Reference< XDataSource > xDataSource( rPropSet.GetApiPropertySet(), UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ // find first sequence with current role
+ OUString aRole = XclChartHelper::GetErrorBarValuesRole( maData.mnBarType );
+ Reference< XDataSequence > xValueSeq;
+
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xValueSeq.is() && (pIt != pEnd); ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aCurrRole;
+ if( aValueProp.GetProperty( aCurrRole, EXC_CHPROP_ROLE ) && (aCurrRole == aRole) )
+ xValueSeq = xTmpValueSeq;
+ }
+ if( xValueSeq.is() )
+ {
+ // #i86465# pass value count back to series
+ rnValueCount = maData.mnValueCount = rValueLink.ConvertDataSequence( xValueSeq, true );
+ bOk = maData.mnValueCount > 0;
+ }
+ }
+ }
+ break;
+ default:
+ bOk = false;
+ }
+ }
+ return bOk;
+}
+
+void XclExpChSerErrorBar::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnBarType
+ << maData.mnSourceType
+ << maData.mnLineEnd
+ << sal_uInt8( 1 ) // must be 1 to make line visible
+ << maData.mfValue
+ << maData.mnValueCount;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns the property set of the specified data point. */
+ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_Int32 nPointIdx )
+{
+ ScfPropertySet aPropSet;
+ try
+ {
+ aPropSet.Set( xDataSeries->getDataPointByIndex( nPointIdx ) );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
+ }
+ return aPropSet;
+}
+
+} // namespace
+
+XclExpChSeries::XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_SERIES, EXC_ID_CHSERIES, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 8 ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE ),
+ mnSeriesIdx( nSeriesIdx ),
+ mnParentIdx( EXC_CHSERIES_INVALID )
+{
+ // CHSOURCELINK records are always required, even if unused
+ mxTitleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
+ mxValueLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_VALUES ) );
+ mxCategLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_CATEGORY ) );
+ if( GetBiff() == EXC_BIFF8 )
+ mxBubbleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_BUBBLES ) );
+}
+
+bool XclExpChSeries::ConvertDataSeries(
+ Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries,
+ const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx )
+{
+ bool bOk = false;
+ Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq, xBubbleSeq;
+
+ // find first sequence with role 'values-y'
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aRole;
+ if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) )
+ {
+ if( !xYValueSeq.is() && (aRole == EXC_CHPROP_ROLE_YVALUES) )
+ {
+ xYValueSeq = xTmpValueSeq;
+ if( !xTitleSeq.is() )
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ else if( !xXValueSeq.is() && !rTypeInfo.mbCategoryAxis && (aRole == EXC_CHPROP_ROLE_XVALUES) )
+ {
+ xXValueSeq = xTmpValueSeq;
+ }
+ else if( !xBubbleSeq.is() && (rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES) && (aRole == EXC_CHPROP_ROLE_SIZEVALUES) )
+ {
+ xBubbleSeq = xTmpValueSeq;
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ }
+ }
+
+ bOk = xYValueSeq.is();
+ if( bOk )
+ {
+ // chart type group index
+ mnGroupIdx = nGroupIdx;
+
+ // convert source links
+ maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
+ mxTitleLink->ConvertDataSequence( xTitleSeq, true );
+
+ // X values of XY charts
+ maData.mnCategCount = mxCategLink->ConvertDataSequence( xXValueSeq, false, maData.mnValueCount );
+
+ // size values of bubble charts
+ if( mxBubbleLink )
+ mxBubbleLink->ConvertDataSequence( xBubbleSeq, false, maData.mnValueCount );
+
+ // series formatting
+ XclChDataPointPos aPointPos( mnSeriesIdx );
+ ScfPropertySet aSeriesProp( xDataSeries );
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
+ mxSeriesFmt->ConvertDataSeries( aSeriesProp, rTypeInfo );
+
+ // trend lines
+ CreateTrendLines( xDataSeries );
+
+ // error bars
+ CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARX, EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
+ CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARY, EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
+
+ if( maData.mnValueCount > 0 )
+ {
+ const sal_Int32 nMaxPointCount = maData.mnValueCount;
+
+ /* #i91063# Create missing fill properties in pie/doughnut charts.
+ If freshly created (never saved to ODF), these charts show
+ varying point colors but do not return these points via API. */
+ if( xDiagram.is() && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE) )
+ {
+ Reference< XColorScheme > xColorScheme = xDiagram->getDefaultColorScheme();
+ if( xColorScheme.is() )
+ {
+ const OUString aFillStyleName = CREATE_OUSTRING( "FillStyle" );
+ const OUString aColorName = CREATE_OUSTRING( "Color" );
+ namespace cssd = ::com::sun::star::drawing;
+ for( sal_Int32 nPointIdx = 0; nPointIdx < nMaxPointCount; ++nPointIdx )
+ {
+ aPointPos.mnPointIdx = static_cast< sal_uInt16 >( nPointIdx );
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
+ // test that the point fill style is solid, but no color is set
+ cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
+ if( aPointProp.GetProperty( eFillStyle, aFillStyleName ) &&
+ (eFillStyle == cssd::FillStyle_SOLID) &&
+ !aPointProp.HasProperty( aColorName ) )
+ {
+ aPointProp.SetProperty( aColorName, xColorScheme->getColorByIndex( nPointIdx ) );
+ }
+ }
+ }
+ }
+
+ // data point formatting
+ Sequence< sal_Int32 > aPointIndexes;
+ if( aSeriesProp.GetProperty( aPointIndexes, EXC_CHPROP_ATTRIBDATAPOINTS ) && aPointIndexes.hasElements() )
+ {
+ const sal_Int32* pnBeg = aPointIndexes.getConstArray();
+ const sal_Int32* pnEnd = pnBeg + aPointIndexes.getLength();
+ for( const sal_Int32* pnIt = pnBeg; (pnIt != pnEnd) && (*pnIt < nMaxPointCount); ++pnIt )
+ {
+ aPointPos.mnPointIdx = static_cast< sal_uInt16 >( *pnIt );
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, *pnIt );
+ XclExpChDataFormatRef xPointFmt( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
+ xPointFmt->ConvertDataSeries( aPointProp, rTypeInfo );
+ maPointFmts.AppendRecord( xPointFmt );
+ }
+ }
+ }
+ }
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertStockSeries( XDataSeriesRef xDataSeries,
+ const OUString& rValueRole, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol )
+{
+ bool bOk = false;
+ Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
+ if( xDataSource.is() )
+ {
+ Reference< XDataSequence > xYValueSeq, xTitleSeq;
+
+ // find first sequence with passed role
+ Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
+ const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
+ const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
+ for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xYValueSeq.is() && (pIt != pEnd); ++pIt )
+ {
+ Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
+ ScfPropertySet aValueProp( xTmpValueSeq );
+ OUString aRole;
+ if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) && (aRole == rValueRole) )
+ {
+ xYValueSeq = xTmpValueSeq;
+ xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ }
+ }
+
+ bOk = xYValueSeq.is();
+ if( bOk )
+ {
+ // chart type group index
+ mnGroupIdx = nGroupIdx;
+ // convert source links
+ maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
+ mxTitleLink->ConvertDataSequence( xTitleSeq, true );
+ // series formatting
+ ScfPropertySet aSeriesProp( xDataSeries );
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), nFormatIdx ) );
+ mxSeriesFmt->ConvertStockSeries( aSeriesProp, bCloseSymbol );
+ }
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertTrendLine( const XclExpChSeries& rParent, Reference< XRegressionCurve > xRegCurve )
+{
+ InitFromParent( rParent );
+ mxTrendLine.reset( new XclExpChSerTrendLine( GetChRoot() ) );
+ bool bOk = mxTrendLine->Convert( xRegCurve, mnSeriesIdx );
+ if( bOk )
+ {
+ mxSeriesFmt = mxTrendLine->GetDataFormat();
+ GetChartData().SetDataLabel( mxTrendLine->GetDataLabel() );
+ }
+ return bOk;
+}
+
+bool XclExpChSeries::ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId )
+{
+ InitFromParent( rParent );
+ // error bar settings
+ mxErrorBar.reset( new XclExpChSerErrorBar( GetChRoot(), nBarId ) );
+ bool bOk = mxErrorBar->Convert( *mxValueLink, maData.mnValueCount, rPropSet );
+ if( bOk )
+ {
+ // error bar formatting
+ mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), 0 ) );
+ mxSeriesFmt->ConvertLine( rPropSet, EXC_CHOBJTYPE_ERRORBAR );
+ }
+ return bOk;
+}
+
+void XclExpChSeries::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
+{
+ if( xCategSeq.is() )
+ maData.mnCategCount = mxCategLink->ConvertDataSequence( xCategSeq->getValues(), false );
+}
+
+void XclExpChSeries::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxTitleLink );
+ lclSaveRecord( rStrm, mxValueLink );
+ lclSaveRecord( rStrm, mxCategLink );
+ lclSaveRecord( rStrm, mxBubbleLink );
+ lclSaveRecord( rStrm, mxSeriesFmt );
+ maPointFmts.Save( rStrm );
+ if( mnGroupIdx != EXC_CHSERGROUP_NONE )
+ XclExpUInt16Record( EXC_ID_CHSERGROUP, mnGroupIdx ).Save( rStrm );
+ if( mnParentIdx != EXC_CHSERIES_INVALID )
+ XclExpUInt16Record( EXC_ID_CHSERPARENT, mnParentIdx ).Save( rStrm );
+ lclSaveRecord( rStrm, mxTrendLine );
+ lclSaveRecord( rStrm, mxErrorBar );
+}
+
+void XclExpChSeries::InitFromParent( const XclExpChSeries& rParent )
+{
+ // index to parent series is stored 1-based
+ mnParentIdx = rParent.mnSeriesIdx + 1;
+ /* #i86465# MSO2007 SP1 expects correct point counts in child series
+ (there was no problem in Excel2003 or Excel2007 without SP1...) */
+ maData.mnCategCount = rParent.maData.mnCategCount;
+ maData.mnValueCount = rParent.maData.mnValueCount;
+}
+
+void XclExpChSeries::CreateTrendLines( XDataSeriesRef xDataSeries )
+{
+ Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
+ if( xRegCurveCont.is() )
+ {
+ Sequence< Reference< XRegressionCurve > > aRegCurveSeq = xRegCurveCont->getRegressionCurves();
+ const Reference< XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
+ const Reference< XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
+ for( const Reference< XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries && !xSeries->ConvertTrendLine( *this, *pIt ) )
+ GetChartData().RemoveLastSeries();
+ }
+ }
+}
+
+void XclExpChSeries::CreateErrorBars( const ScfPropertySet& rPropSet,
+ const OUString& rBarPropName, sal_uInt8 nPosBarId, sal_uInt8 nNegBarId )
+{
+ Reference< XPropertySet > xErrorBar;
+ if( rPropSet.GetProperty( xErrorBar, rBarPropName ) && xErrorBar.is() )
+ {
+ ScfPropertySet aErrorProp( xErrorBar );
+ CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWPOSITIVEERROR, nPosBarId );
+ CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWNEGATIVEERROR, nNegBarId );
+ }
+}
+
+void XclExpChSeries::CreateErrorBar( const ScfPropertySet& rPropSet,
+ const OUString& rShowPropName, sal_uInt8 nBarId )
+{
+ if( rPropSet.GetBoolProperty( rShowPropName ) )
+ {
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries && !xSeries->ConvertErrorBar( *this, rPropSet, nBarId ) )
+ GetChartData().RemoveLastSeries();
+ }
+}
+
+void XclExpChSeries::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnCategType << maData.mnValueType << maData.mnCategCount << maData.mnValueCount;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnBubbleType << maData.mnBubbleCount;
+}
+
+// Chart type groups ==========================================================
+
+XclExpChType::XclExpChType( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHUNKNOWN ),
+ XclExpChRoot( rRoot ),
+ maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
+{
+}
+
+void XclExpChType::Convert( Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels )
+{
+ if( xChartType.is() )
+ {
+ maTypeInfo = GetChartTypeInfo( xChartType->getChartType() );
+ // special handling for some chart types
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_BAR:
+ {
+ maTypeInfo = GetChartTypeInfo( bSwappedAxesSet ? EXC_CHTYPEID_HORBAR : EXC_CHTYPEID_BAR );
+ ::set_flag( maData.mnFlags, EXC_CHBAR_HORIZONTAL, bSwappedAxesSet );
+ ScfPropertySet aTypeProp( xChartType );
+ Sequence< sal_Int32 > aInt32Seq;
+ maData.mnOverlap = 0;
+ if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_OVERLAPSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
+ maData.mnOverlap = limit_cast< sal_Int16 >( -aInt32Seq[ nApiAxesSetIdx ], -100, 100 );
+ maData.mnGap = 150;
+ if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_GAPWIDTHSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
+ maData.mnGap = limit_cast< sal_uInt16 >( aInt32Seq[ nApiAxesSetIdx ], 0, 500 );
+ }
+ break;
+ case EXC_CHTYPECATEG_RADAR:
+ ::set_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS, bHasXLabels );
+ break;
+ case EXC_CHTYPECATEG_PIE:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ bool bDonut = aTypeProp.GetBoolProperty( EXC_CHPROP_USERINGS );
+ maTypeInfo = GetChartTypeInfo( bDonut ? EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
+ maData.mnPieHole = bDonut ? 50 : 0;
+ // #i85166# starting angle of first pie slice
+ ScfPropertySet aDiaProp( xDiagram );
+ maData.mnRotation = XclExpChRoot::ConvertPieRotation( aDiaProp );
+ }
+ break;
+ case EXC_CHTYPECATEG_SCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maData.mnFlags, EXC_CHSCATTER_BUBBLES, maTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES );
+ break;
+ default:;
+ }
+ SetRecId( maTypeInfo.mnRecId );
+ }
+}
+
+void XclExpChType::SetStacked( bool bPercent )
+{
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ ::set_flag( maData.mnFlags, EXC_CHLINE_STACKED );
+ ::set_flag( maData.mnFlags, EXC_CHLINE_PERCENT, bPercent );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ ::set_flag( maData.mnFlags, EXC_CHBAR_STACKED );
+ ::set_flag( maData.mnFlags, EXC_CHBAR_PERCENT, bPercent );
+ maData.mnOverlap = -100;
+ break;
+ default:;
+ }
+}
+
+void XclExpChType::WriteBody( XclExpStream& rStrm )
+{
+ switch( GetRecId() )
+ {
+ case EXC_ID_CHBAR:
+ rStrm << maData.mnOverlap << maData.mnGap << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHLINE:
+ case EXC_ID_CHAREA:
+ case EXC_ID_CHRADARLINE:
+ case EXC_ID_CHRADARAREA:
+ rStrm << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHPIE:
+ rStrm << maData.mnRotation << maData.mnPieHole;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnFlags;
+ break;
+
+ case EXC_ID_CHSCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << maData.mnBubbleSize << maData.mnBubbleType << maData.mnFlags;
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclExpChType::WriteBody - unknown chart type" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChChart3d::XclExpChChart3d() :
+ XclExpRecord( EXC_ID_CHCHART3D, 14 )
+{
+}
+
+void XclExpChChart3d::Convert( const ScfPropertySet& rPropSet, bool b3dWallChart )
+{
+ sal_Int32 nRotationY = 0;
+ rPropSet.GetProperty( nRotationY, EXC_CHPROP_ROTATIONVERTICAL );
+ sal_Int32 nRotationX = 0;
+ rPropSet.GetProperty( nRotationX, EXC_CHPROP_ROTATIONHORIZONTAL );
+ sal_Int32 nPerspective = 15;
+ rPropSet.GetProperty( nPerspective, EXC_CHPROP_PERSPECTIVE );
+
+ if( b3dWallChart )
+ {
+ // Y rotation (Excel [0..359], Chart2 [-179,180])
+ if( nRotationY < 0 ) nRotationY += 360;
+ maData.mnRotation = static_cast< sal_uInt16 >( nRotationY );
+ // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
+ maData.mnElevation = limit_cast< sal_Int16 >( nRotationX, -90, 90 );
+ // perspective (Excel and Chart2 [0,100])
+ maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
+ // flags
+ maData.mnFlags = 0;
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D, !rPropSet.GetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES ) );
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_AUTOHEIGHT );
+ ::set_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS );
+ }
+ else
+ {
+ // Y rotation not used in pie charts, but 'first pie slice angle'
+ maData.mnRotation = XclExpChRoot::ConvertPieRotation( rPropSet );
+ // X rotation a.k.a. elevation (map Chart2 [-80,-10] to Excel [10..80])
+ maData.mnElevation = limit_cast< sal_Int16 >( (nRotationX + 270) % 180, 10, 80 );
+ // perspective (Excel and Chart2 [0,100])
+ maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
+ // flags
+ maData.mnFlags = 0;
+ }
+}
+
+void XclExpChChart3d::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnRotation
+ << maData.mnElevation
+ << maData.mnEyeDist
+ << maData.mnRelHeight
+ << maData.mnRelDepth
+ << maData.mnDepthGap
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChLegend::XclExpChLegend( const XclExpChRoot& rRoot ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_LEGEND, EXC_ID_CHLEGEND, 20 )
+{
+}
+
+void XclExpChLegend::Convert( const ScfPropertySet& rPropSet )
+{
+ // frame properties
+ mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_LEGEND );
+ // text properties
+ mxText.reset( new XclExpChText( GetChRoot() ) );
+ mxText->ConvertLegend( rPropSet );
+
+ // legend position and size
+ Any aRelPosAny, aRelSizeAny;
+ rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION );
+ rPropSet.GetAnyProperty( aRelSizeAny, EXC_CHPROP_RELATIVESIZE );
+ cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
+ rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION );
+ if( aRelPosAny.has< RelativePosition >() || ((eApiExpand == cssc::ChartLegendExpansion_CUSTOM) && aRelSizeAny.has< RelativeSize >()) )
+ {
+ try
+ {
+ /* The 'RelativePosition' or 'RelativeSize' properties are used as
+ indicator of manually changed legend position/size, but due to
+ the different anchor modes used by this property (in the
+ RelativePosition.Anchor member) it cannot be used to calculate
+ the position easily. For this, the Chart1 API will be used
+ instead. */
+ Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW );
+ // coordinates in CHLEGEND record written but not used by Excel
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) );
+ XclChFramePos& rFramePos = mxFramePos->GetFramePosData();
+ rFramePos.mnTLMode = EXC_CHFRAMEPOS_CHARTSIZE;
+ ::com::sun::star::awt::Point aLegendPos = xChart1Legend->getPosition();
+ rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( aLegendPos.X );
+ rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( aLegendPos.Y );
+ // legend size, Excel expects points in CHFRAMEPOS record
+ rFramePos.mnBRMode = EXC_CHFRAMEPOS_ABSSIZE_POINTS;
+ ::com::sun::star::awt::Size aLegendSize = xChart1Legend->getSize();
+ rFramePos.maRect.mnWidth = static_cast< sal_uInt16 >( aLegendSize.Width * EXC_POINTS_PER_HMM + 0.5 );
+ rFramePos.maRect.mnHeight = static_cast< sal_uInt16 >( aLegendSize.Height * EXC_POINTS_PER_HMM + 0.5 );
+ maData.maRect.mnWidth = CalcChartXFromHmm( aLegendSize.Width );
+ maData.maRect.mnHeight = CalcChartYFromHmm( aLegendSize.Height );
+ eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
+ // manual legend position implies manual plot area
+ GetChartData().SetManualPlotArea();
+ maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
+ // a CHFRAME record with cleared auto flags is needed
+ if( !mxFrame )
+ mxFrame.reset( new XclExpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
+ mxFrame->SetAutoFlags( false, false );
+ }
+ catch( Exception& )
+ {
+ OSL_FAIL( "XclExpChLegend::Convert - cannot get legend shape" );
+ maData.mnDockMode = EXC_CHLEGEND_RIGHT;
+ eApiExpand = cssc::ChartLegendExpansion_HIGH;
+ }
+ }
+ else
+ {
+ cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
+ rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION );
+ switch( eApiPos )
+ {
+ case cssc2::LegendPosition_LINE_START: maData.mnDockMode = EXC_CHLEGEND_LEFT; break;
+ case cssc2::LegendPosition_LINE_END: maData.mnDockMode = EXC_CHLEGEND_RIGHT; break;
+ case cssc2::LegendPosition_PAGE_START: maData.mnDockMode = EXC_CHLEGEND_TOP; break;
+ case cssc2::LegendPosition_PAGE_END: maData.mnDockMode = EXC_CHLEGEND_BOTTOM; break;
+ default:
+ OSL_FAIL( "XclExpChLegend::Convert - unrecognized legend position" );
+ maData.mnDockMode = EXC_CHLEGEND_RIGHT;
+ eApiExpand = cssc::ChartLegendExpansion_HIGH;
+ }
+ }
+ ::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand == cssc::ChartLegendExpansion_HIGH );
+
+ // other flags
+ ::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES );
+ const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY;
+ ::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
+}
+
+void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxFramePos );
+ lclSaveRecord( rStrm, mxText );
+ lclSaveRecord( rStrm, mxFrame );
+}
+
+void XclExpChLegend::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.maRect << maData.mnDockMode << maData.mnSpacing << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChDropBar::XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DROPBAR, EXC_ID_CHDROPBAR, 2 ),
+ meObjType( eObjType ),
+ mnBarDist( 100 )
+{
+}
+
+void XclExpChDropBar::Convert( const ScfPropertySet& rPropSet )
+{
+ if( rPropSet.Is() )
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+ else
+ SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, true );
+}
+
+void XclExpChDropBar::WriteSubRecords( XclExpStream& rStrm )
+{
+ WriteFrameRecords( rStrm );
+}
+
+void XclExpChDropBar::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnBarDist;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChTypeGroup::XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TYPEGROUP, EXC_ID_CHTYPEGROUP, 20 ),
+ maType( rRoot ),
+ maTypeInfo( maType.GetTypeInfo() )
+{
+ maData.mnGroupIdx = nGroupIdx;
+}
+
+void XclExpChTypeGroup::ConvertType(
+ Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels )
+{
+ // chart type settings
+ maType.Convert( xDiagram, xChartType, nApiAxesSetIdx, bSwappedAxesSet, bHasXLabels );
+
+ // spline - TODO: get from single series (#i66858#)
+ ScfPropertySet aTypeProp( xChartType );
+ cssc2::CurveStyle eCurveStyle;
+ bool bSpline = aTypeProp.GetProperty( eCurveStyle, EXC_CHPROP_CURVESTYLE ) &&
+ (eCurveStyle != cssc2::CurveStyle_LINES);
+
+ // extended type info
+ maTypeInfo.Set( maType.GetTypeInfo(), b3dChart, bSpline );
+
+ // 3d chart settings
+ if( maTypeInfo.mb3dChart ) // only true, if Excel chart supports 3d mode
+ {
+ mxChart3d.reset( new XclExpChChart3d );
+ ScfPropertySet aDiaProp( xDiagram );
+ mxChart3d->Convert( aDiaProp, Is3dWallChart() );
+ }
+}
+
+void XclExpChTypeGroup::ConvertSeries(
+ Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
+ sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectBars )
+{
+ Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
+ if( xSeriesCont.is() )
+ {
+ typedef ::std::vector< Reference< XDataSeries > > XDataSeriesVec;
+ XDataSeriesVec aSeriesVec;
+
+ // copy data series attached to the current axes set to the vector
+ Sequence< Reference< XDataSeries > > aSeriesSeq = xSeriesCont->getDataSeries();
+ const Reference< XDataSeries >* pBeg = aSeriesSeq.getConstArray();
+ const Reference< XDataSeries >* pEnd = pBeg + aSeriesSeq.getLength();
+ for( const Reference< XDataSeries >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ ScfPropertySet aSeriesProp( *pIt );
+ sal_Int32 nSeriesAxesSetIdx(0);
+ if( aSeriesProp.GetProperty( nSeriesAxesSetIdx, EXC_CHPROP_ATTAXISINDEX ) && (nSeriesAxesSetIdx == nGroupAxesSetIdx) )
+ aSeriesVec.push_back( *pIt );
+ }
+
+ // Are there any series in the current axes set?
+ if( !aSeriesVec.empty() )
+ {
+ // stacking direction (stacked/percent/deep 3d) from first series
+ ScfPropertySet aSeriesProp( aSeriesVec.front() );
+ cssc2::StackingDirection eStacking;
+ if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) )
+ eStacking = cssc2::StackingDirection_NO_STACKING;
+
+ // stacked or percent chart
+ if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) )
+ {
+ // percent overrides simple stacking
+ maType.SetStacked( bPercent );
+
+ // connected data points (only in stacked bar charts)
+ if (bConnectBars && (maTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR))
+ {
+ sal_uInt16 nKey = EXC_CHCHARTLINE_CONNECT;
+ maChartLines.insert(nKey, new XclExpChLineFormat(GetChRoot()));
+ }
+ }
+ else
+ {
+ // reverse series order for some unstacked 2D chart types
+ if( maTypeInfo.mbReverseSeries && !Is3dChart() )
+ ::std::reverse( aSeriesVec.begin(), aSeriesVec.end() );
+ }
+
+ // deep 3d chart or clustered 3d chart (stacked is not clustered)
+ if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() )
+ mxChart3d->SetClustered();
+
+ // varied point colors
+ ::set_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS, aSeriesProp.GetBoolProperty( EXC_CHPROP_VARYCOLORSBY ) );
+
+ // process all series
+ for( XDataSeriesVec::const_iterator aIt = aSeriesVec.begin(), aEnd = aSeriesVec.end(); aIt != aEnd; ++aIt )
+ {
+ // create Excel series object, stock charts need special processing
+ if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
+ CreateAllStockSeries( xChartType, *aIt );
+ else
+ CreateDataSeries( xDiagram, *aIt );
+ }
+ }
+ }
+}
+
+void XclExpChTypeGroup::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
+{
+ for( size_t nIdx = 0, nSize = maSeries.GetSize(); nIdx < nSize; ++nIdx )
+ maSeries.GetRecord( nIdx )->ConvertCategSequence( xCategSeq );
+}
+
+void XclExpChTypeGroup::ConvertLegend( const ScfPropertySet& rPropSet )
+{
+ if( rPropSet.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ {
+ mxLegend.reset( new XclExpChLegend( GetChRoot() ) );
+ mxLegend->Convert( rPropSet );
+ }
+}
+
+void XclExpChTypeGroup::WriteSubRecords( XclExpStream& rStrm )
+{
+ maType.Save( rStrm );
+ lclSaveRecord( rStrm, mxChart3d );
+ lclSaveRecord( rStrm, mxLegend );
+ lclSaveRecord( rStrm, mxUpBar );
+ lclSaveRecord( rStrm, mxDownBar );
+ for( XclExpChLineFormatMap::iterator aLIt = maChartLines.begin(), aLEnd = maChartLines.end(); aLIt != aLEnd; ++aLIt )
+ lclSaveRecord( rStrm, aLIt->second, EXC_ID_CHCHARTLINE, aLIt->first );
+}
+
+sal_uInt16 XclExpChTypeGroup::GetFreeFormatIdx() const
+{
+ return static_cast< sal_uInt16 >( maSeries.GetSize() );
+}
+
+void XclExpChTypeGroup::CreateDataSeries(
+ Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries )
+{
+ // let chart create series object with correct series index
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries )
+ {
+ if( xSeries->ConvertDataSeries( xDiagram, xDataSeries, maTypeInfo, GetGroupIdx(), GetFreeFormatIdx() ) )
+ maSeries.AppendRecord( xSeries );
+ else
+ GetChartData().RemoveLastSeries();
+ }
+}
+
+void XclExpChTypeGroup::CreateAllStockSeries(
+ Reference< XChartType > xChartType, Reference< XDataSeries > xDataSeries )
+{
+ // create existing series objects
+ bool bHasOpen = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_OPENVALUES, false );
+ bool bHasHigh = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_HIGHVALUES, false );
+ bool bHasLow = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_LOWVALUES, false );
+ bool bHasClose = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_CLOSEVALUES, !bHasOpen );
+
+ // formatting of special stock chart elements
+ ScfPropertySet aTypeProp( xChartType );
+ // hi-lo lines
+ if( bHasHigh && bHasLow && aTypeProp.GetBoolProperty( EXC_CHPROP_SHOWHIGHLOW ) )
+ {
+ ScfPropertySet aSeriesProp( xDataSeries );
+ XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( GetChRoot() ) );
+ xLineFmt->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
+ sal_uInt16 nKey = EXC_CHCHARTLINE_HILO;
+ maChartLines.insert(nKey, new XclExpChLineFormat(GetChRoot()));
+ }
+ // dropbars
+ if( bHasOpen && bHasClose )
+ {
+ // dropbar type is dependent on position in the file - always create both
+ Reference< XPropertySet > xWhitePropSet, xBlackPropSet;
+ // white dropbar format
+ aTypeProp.GetProperty( xWhitePropSet, EXC_CHPROP_WHITEDAY );
+ ScfPropertySet aWhiteProp( xWhitePropSet );
+ mxUpBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_WHITEDROPBAR ) );
+ mxUpBar->Convert( aWhiteProp );
+ // black dropbar format
+ aTypeProp.GetProperty( xBlackPropSet, EXC_CHPROP_BLACKDAY );
+ ScfPropertySet aBlackProp( xBlackPropSet );
+ mxDownBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_BLACKDROPBAR ) );
+ mxDownBar->Convert( aBlackProp );
+ }
+}
+
+bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries,
+ const OUString& rValueRole, bool bCloseSymbol )
+{
+ bool bOk = false;
+ // let chart create series object with correct series index
+ XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
+ if( xSeries )
+ {
+ bOk = xSeries->ConvertStockSeries( xDataSeries,
+ rValueRole, GetGroupIdx(), GetFreeFormatIdx(), bCloseSymbol );
+ if( bOk )
+ maSeries.AppendRecord( xSeries );
+ else
+ GetChartData().RemoveLastSeries();
+ }
+ return bOk;
+}
+
+void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 16 );
+ rStrm << maData.mnFlags << maData.mnGroupIdx;
+}
+
+// Axes =======================================================================
+
+XclExpChLabelRange::XclExpChLabelRange( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHLABELRANGE, 8 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChLabelRange::Convert( const ScaleData& rScaleData, const ScfPropertySet& rChart1Axis, bool bMirrorOrient )
+{
+ /* Base time unit (using the property 'ExplicitTimeIncrement' from the old
+ chart API allows to detect axis type (date axis, if property exists),
+ and to receive the base time unit currently used in case the base time
+ unit is set to 'automatic'. */
+ cssc::TimeIncrement aTimeIncrement;
+ if( rChart1Axis.GetProperty( aTimeIncrement, EXC_CHPROP_EXPTIMEINCREMENT ) )
+ {
+ // property exists -> this is a date axis currently
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
+
+ // automatic base time unit, if the UNO Any 'rScaleData.TimeIncrement.TimeResolution' does not contain a valid value...
+ bool bAutoBase = !rScaleData.TimeIncrement.TimeResolution.has< cssc::TimeIncrement >();
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE, bAutoBase );
+
+ // ...but get the current base time unit from the property of the old chart API
+ sal_Int32 nApiTimeUnit = 0;
+ bool bValidBaseUnit = aTimeIncrement.TimeResolution >>= nApiTimeUnit;
+ DBG_ASSERT( bValidBaseUnit, "XclExpChLabelRange::Convert - cannot ghet base time unit" );
+ maDateData.mnBaseUnit = bValidBaseUnit ? lclGetTimeUnit( nApiTimeUnit ) : EXC_CHDATERANGE_DAYS;
+
+ /* Min/max values depend on base time unit, they specify the number of
+ days, months, or years starting from null date. */
+ bool bAutoMin = lclConvertTimeValue( GetRoot(), maDateData.mnMinDate, rScaleData.Minimum, maDateData.mnBaseUnit );
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN, bAutoMin );
+ bool bAutoMax = lclConvertTimeValue( GetRoot(), maDateData.mnMaxDate, rScaleData.Maximum, maDateData.mnBaseUnit );
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX, bAutoMax );
+ }
+
+ // automatic axis type detection
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE, rScaleData.AutoDateAxis );
+
+ // increment
+ bool bAutoMajor = lclConvertTimeInterval( maDateData.mnMajorStep, maDateData.mnMajorUnit, rScaleData.TimeIncrement.MajorTimeInterval );
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR, bAutoMajor );
+ bool bAutoMinor = lclConvertTimeInterval( maDateData.mnMinorStep, maDateData.mnMinorUnit, rScaleData.TimeIncrement.MinorTimeInterval );
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR, bAutoMinor );
+
+ // origin
+ double fOrigin = 0.0;
+ if( !lclIsAutoAnyOrGetValue( fOrigin, rScaleData.Origin ) )
+ maLabelData.mnCross = limit_cast< sal_uInt16 >( fOrigin, 1, 31999 );
+
+ // reverse order
+ if( (rScaleData.Orientation == cssc2::AxisOrientation_REVERSE) != bMirrorOrient )
+ ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE );
+}
+
+void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
+{
+ cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
+ rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION );
+ double fCrossingPos = 1.0;
+ rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE );
+
+ bool bDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
+ switch( eAxisPos )
+ {
+ case cssc::ChartAxisPosition_ZERO:
+ case cssc::ChartAxisPosition_START:
+ maLabelData.mnCross = 1;
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
+ break;
+ case cssc::ChartAxisPosition_END:
+ ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_MAXCROSS );
+ break;
+ case cssc::ChartAxisPosition_VALUE:
+ maLabelData.mnCross = limit_cast< sal_uInt16 >( fCrossingPos, 1, 31999 );
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS, false );
+ if( bDateAxis )
+ maDateData.mnCross = lclGetTimeValue( GetRoot(), fCrossingPos, maDateData.mnBaseUnit );
+ break;
+ default:
+ maLabelData.mnCross = 1;
+ ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
+ }
+}
+
+void XclExpChLabelRange::Save( XclExpStream& rStrm )
+{
+ // the CHLABELRANGE record
+ XclExpRecord::Save( rStrm );
+
+ // the CHDATERANGE record with date axis settings (BIFF8 only)
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ rStrm.StartRecord( EXC_ID_CHDATERANGE, 18 );
+ rStrm << maDateData.mnMinDate
+ << maDateData.mnMaxDate
+ << maDateData.mnMajorStep
+ << maDateData.mnMajorUnit
+ << maDateData.mnMinorStep
+ << maDateData.mnMinorUnit
+ << maDateData.mnBaseUnit
+ << maDateData.mnCross
+ << maDateData.mnFlags;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpChLabelRange::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maLabelData.mnCross << maLabelData.mnLabelFreq << maLabelData.mnTickFreq << maLabelData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChValueRange::XclExpChValueRange( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHVALUERANGE, 42 ),
+ XclExpChRoot( rRoot )
+{
+}
+
+void XclExpChValueRange::Convert( const ScaleData& rScaleData )
+{
+ // scaling algorithm
+ bool bLogScale = ScfApiHelper::GetServiceName( rScaleData.Scaling ) == SERVICE_CHART2_LOGSCALING;
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, bLogScale );
+
+ // min/max
+ bool bAutoMin = lclIsAutoAnyOrGetScaledValue( maData.mfMin, rScaleData.Minimum, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN, bAutoMin );
+ bool bAutoMax = lclIsAutoAnyOrGetScaledValue( maData.mfMax, rScaleData.Maximum, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX, bAutoMax );
+
+ // origin
+ bool bAutoCross = lclIsAutoAnyOrGetScaledValue( maData.mfCross, rScaleData.Origin, bLogScale );
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, bAutoCross );
+
+ // major increment
+ const IncrementData& rIncrementData = rScaleData.IncrementData;
+ bool bAutoMajor = lclIsAutoAnyOrGetValue( maData.mfMajorStep, rIncrementData.Distance ) || (maData.mfMajorStep <= 0.0);
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR, bAutoMajor );
+ // minor increment
+ const Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
+ sal_Int32 nCount = 0;
+ bool bAutoMinor = bLogScale || bAutoMajor || (rSubIncrementSeq.getLength() < 1) ||
+ lclIsAutoAnyOrGetValue( nCount, rSubIncrementSeq[ 0 ].IntervalCount ) || (nCount < 1);
+ if( !bAutoMinor )
+ maData.mfMinorStep = maData.mfMajorStep / nCount;
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor );
+
+ // reverse order
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE );
+}
+
+void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
+{
+ cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
+ double fCrossingPos = 0.0;
+ if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) )
+ {
+ switch( eAxisPos )
+ {
+ case cssc::ChartAxisPosition_ZERO:
+ case cssc::ChartAxisPosition_START:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ break;
+ case cssc::ChartAxisPosition_END:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
+ break;
+ case cssc::ChartAxisPosition_VALUE:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, false );
+ maData.mfCross = ::get_flagvalue< double >( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, log( fCrossingPos ) / log( 10.0 ), fCrossingPos );
+ break;
+ default:
+ ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ }
+ }
+}
+
+void XclExpChValueRange::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mfMin
+ << maData.mfMax
+ << maData.mfMajorStep
+ << maData.mfMinorStep
+ << maData.mfCross
+ << maData.mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_uInt8 lclGetXclTickPos( sal_Int32 nApiTickmarks )
+{
+ using namespace cssc2::TickmarkStyle;
+ sal_uInt8 nXclTickPos = 0;
+ ::set_flag( nXclTickPos, EXC_CHTICK_INSIDE, ::get_flag( nApiTickmarks, INNER ) );
+ ::set_flag( nXclTickPos, EXC_CHTICK_OUTSIDE, ::get_flag( nApiTickmarks, OUTER ) );
+ return nXclTickPos;
+}
+
+} // namespace
+
+XclExpChTick::XclExpChTick( const XclExpChRoot& rRoot ) :
+ XclExpRecord( EXC_ID_CHTICK, (rRoot.GetBiff() == EXC_BIFF8) ? 30 : 26 ),
+ XclExpChRoot( rRoot ),
+ mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
+{
+}
+
+void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType )
+{
+ // tick mark style
+ sal_Int32 nApiTickmarks = 0;
+ if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MAJORTICKS ) )
+ maData.mnMajor = lclGetXclTickPos( nApiTickmarks );
+ if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MINORTICKS ) )
+ maData.mnMinor = lclGetXclTickPos( nApiTickmarks );
+
+ // axis labels
+ if( (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) && (nAxisType == EXC_CHAXIS_X) )
+ {
+ /* Radar charts disable their category labels via chart type, not via
+ axis, and axis labels are always 'near axis'. */
+ maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ else if( !rPropSet.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS ) )
+ {
+ // no labels
+ maData.mnLabelPos = EXC_CHTICK_NOLABEL;
+ }
+ else if( rTypeInfo.mb3dChart && (nAxisType == EXC_CHAXIS_Y) )
+ {
+ // Excel expects 'near axis' at Y axes in 3D charts
+ maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ else
+ {
+ cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS;
+ rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION );
+ switch( eApiLabelPos )
+ {
+ case cssc::ChartAxisLabelPosition_NEAR_AXIS:
+ case cssc::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE: maData.mnLabelPos = EXC_CHTICK_NEXT; break;
+ case cssc::ChartAxisLabelPosition_OUTSIDE_START: maData.mnLabelPos = EXC_CHTICK_LOW; break;
+ case cssc::ChartAxisLabelPosition_OUTSIDE_END: maData.mnLabelPos = EXC_CHTICK_HIGH; break;
+ default: maData.mnLabelPos = EXC_CHTICK_NEXT;
+ }
+ }
+}
+
+void XclExpChTick::SetFontColor( const Color& rColor, sal_uInt32 nColorId )
+{
+ maData.maTextColor = rColor;
+ ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR, rColor == COL_AUTO );
+ mnTextColorId = nColorId;
+}
+
+void XclExpChTick::SetRotation( sal_uInt16 nRotation )
+{
+ maData.mnRotation = nRotation;
+ ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOROT, false );
+ ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 2, 3 );
+}
+
+void XclExpChTick::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnMajor
+ << maData.mnMinor
+ << maData.mnLabelPos
+ << maData.mnBackMode;
+ rStrm.WriteZeroBytes( 16 );
+ rStrm << maData.maTextColor
+ << maData.mnFlags;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns an API axis object from the passed coordinate system. */
+Reference< XAxis > lclGetApiAxis( Reference< XCoordinateSystem > xCoordSystem,
+ sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
+{
+ Reference< XAxis > xAxis;
+ if( (nApiAxisDim >= 0) && xCoordSystem.is() ) try
+ {
+ xAxis = xCoordSystem->getAxisByDimension( nApiAxisDim, nApiAxesSetIdx );
+ }
+ catch( Exception& )
+ {
+ }
+ return xAxis;
+}
+
+Reference< cssc::XAxis > lclGetApiChart1Axis( Reference< XChartDocument > xChartDoc,
+ sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
+{
+ Reference< cssc::XAxis > xChart1Axis;
+ try
+ {
+ Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY_THROW );
+ Reference< cssc::XAxisSupplier > xChart1AxisSupp( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
+ switch( nApiAxesSetIdx )
+ {
+ case EXC_CHART_AXESSET_PRIMARY:
+ xChart1Axis = xChart1AxisSupp->getAxis( nApiAxisDim );
+ break;
+ case EXC_CHART_AXESSET_SECONDARY:
+ xChart1Axis = xChart1AxisSupp->getSecondaryAxis( nApiAxisDim );
+ break;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return xChart1Axis;
+}
+
+} // namespace
+
+XclExpChAxis::XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXIS, EXC_ID_CHAXIS, 18 ),
+ mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
+{
+ maData.mnType = nAxisType;
+}
+
+void XclExpChAxis::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
+{
+ mxFont = xFont;
+ if( mxTick )
+ mxTick->SetFontColor( rColor, nColorId );
+}
+
+void XclExpChAxis::SetRotation( sal_uInt16 nRotation )
+{
+ if( mxTick )
+ mxTick->SetRotation( nRotation );
+}
+
+void XclExpChAxis::Convert( Reference< XAxis > xAxis, Reference< XAxis > xCrossingAxis,
+ Reference< cssc::XAxis > xChart1Axis, const XclChExtTypeInfo& rTypeInfo )
+{
+ ScfPropertySet aAxisProp( xAxis );
+ bool bCategoryAxis = ((GetAxisType() == EXC_CHAXIS_X) && rTypeInfo.mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z);
+
+ // axis line format -------------------------------------------------------
+
+ mxAxisLine.reset( new XclExpChLineFormat( GetChRoot() ) );
+ mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
+ // #i58688# axis enabled
+ mxAxisLine->SetShowAxis( aAxisProp.GetBoolProperty( EXC_CHPROP_SHOW ) );
+
+ // axis scaling and increment ---------------------------------------------
+
+ ScfPropertySet aCrossingProp( xCrossingAxis );
+ if( bCategoryAxis )
+ {
+ mxLabelRange.reset( new XclExpChLabelRange( GetChRoot() ) );
+ mxLabelRange->SetTicksBetweenCateg( rTypeInfo.mbTicksBetweenCateg );
+ if( xAxis.is() )
+ {
+ ScfPropertySet aChart1AxisProp( xChart1Axis );
+ // #i71684# radar charts have reversed rotation direction
+ mxLabelRange->Convert( xAxis->getScaleData(), aChart1AxisProp, (GetAxisType() == EXC_CHAXIS_X) && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) );
+ }
+ // get position of crossing axis on this axis from passed axis object
+ if( aCrossingProp.Is() )
+ mxLabelRange->ConvertAxisPosition( aCrossingProp );
+ }
+ else
+ {
+ mxValueRange.reset( new XclExpChValueRange( GetChRoot() ) );
+ if( xAxis.is() )
+ mxValueRange->Convert( xAxis->getScaleData() );
+ // get position of crossing axis on this axis from passed axis object
+ if( aCrossingProp.Is() )
+ mxValueRange->ConvertAxisPosition( aCrossingProp );
+ }
+
+ // axis caption text ------------------------------------------------------
+
+ // axis ticks properties
+ mxTick.reset( new XclExpChTick( GetChRoot() ) );
+ mxTick->Convert( aAxisProp, rTypeInfo, GetAxisType() );
+
+ // axis label formatting and rotation
+ ConvertFontBase( GetChRoot(), aAxisProp );
+ ConvertRotationBase( GetChRoot(), aAxisProp, true );
+
+ // axis number format
+ sal_Int32 nApiNumFmt = 0;
+ if( !bCategoryAxis && aAxisProp.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
+ mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
+
+ // grid -------------------------------------------------------------------
+
+ if( xAxis.is() )
+ {
+ // main grid
+ ScfPropertySet aGridProp( xAxis->getGridProperties() );
+ if( aGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ mxMajorGrid = lclCreateLineFormat( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ // sub grid
+ Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
+ if( aSubGridPropSeq.hasElements() )
+ {
+ ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
+ if( aSubGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
+ mxMinorGrid = lclCreateLineFormat( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ }
+ }
+}
+
+void XclExpChAxis::ConvertWall( XDiagramRef xDiagram )
+{
+ if( xDiagram.is() ) switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ {
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxWallFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_WALL3D );
+ }
+ break;
+ case EXC_CHAXIS_Y:
+ {
+ ScfPropertySet aFloorProp( xDiagram->getFloor() );
+ mxWallFrame = lclCreateFrame( GetChRoot(), aFloorProp, EXC_CHOBJTYPE_FLOOR3D );
+ }
+ break;
+ default:
+ mxWallFrame.reset();
+ }
+}
+
+void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxLabelRange );
+ lclSaveRecord( rStrm, mxValueRange );
+ if( mnNumFmtIdx != EXC_FORMAT_NOTFOUND )
+ XclExpUInt16Record( EXC_ID_CHFORMAT, mnNumFmtIdx ).Save( rStrm );
+ lclSaveRecord( rStrm, mxTick );
+ lclSaveRecord( rStrm, mxFont );
+ lclSaveRecord( rStrm, mxAxisLine, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_AXISLINE );
+ lclSaveRecord( rStrm, mxMajorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MAJORGRID );
+ lclSaveRecord( rStrm, mxMinorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MINORGRID );
+ lclSaveRecord( rStrm, mxWallFrame, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_WALLS );
+}
+
+void XclExpChAxis::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnType;
+ rStrm.WriteZeroBytes( 16 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
+ XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXESSET, EXC_ID_CHAXESSET, 18 )
+{
+ maData.mnAxesSetId = nAxesSetId;
+ SetFutureRecordContext( 0, nAxesSetId );
+
+ /* Need to set a reasonable size for the plot area, otherwise Excel will
+ move away embedded shapes while auto-sizing the plot area. This is just
+ a wild guess, but will be fixed with implementing manual positioning of
+ chart elements. */
+ maData.maRect.mnX = 262;
+ maData.maRect.mnY = 626;
+ maData.maRect.mnWidth = 3187;
+ maData.maRect.mnHeight = 2633;
+}
+
+sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx )
+{
+ /* First unused chart type group index is passed to be able to continue
+ counting of chart type groups for secondary axes set. */
+ sal_uInt16 nGroupIdx = nFirstGroupIdx;
+ Reference< XCoordinateSystemContainer > xCoordSysCont( xDiagram, UNO_QUERY );
+ if( xCoordSysCont.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCoordSysSeq = xCoordSysCont->getCoordinateSystems();
+ if( aCoordSysSeq.getLength() > 0 )
+ {
+ /* Process first coordinate system only. Import filter puts all
+ chart types into one coordinate system. */
+ Reference< XCoordinateSystem > xCoordSystem = aCoordSysSeq[ 0 ];
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+
+ // 3d mode
+ bool b3dChart = xCoordSystem.is() && (xCoordSystem->getDimension() == 3);
+
+ // percent charts
+ namespace ApiAxisType = cssc2::AxisType;
+ Reference< XAxis > xApiYAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_Y, nApiAxesSetIdx );
+ bool bPercent = xApiYAxis.is() && (xApiYAxis->getScaleData().AxisType == ApiAxisType::PERCENT);
+
+ // connector lines in bar charts
+ ScfPropertySet aDiaProp( xDiagram );
+ bool bConnectBars = aDiaProp.GetBoolProperty( EXC_CHPROP_CONNECTBARS );
+
+ // swapped axes sets
+ ScfPropertySet aCoordSysProp( xCoordSystem );
+ bool bSwappedAxesSet = aCoordSysProp.GetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS );
+
+ // X axis for later use
+ Reference< XAxis > xApiXAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_X, nApiAxesSetIdx );
+ // X axis labels
+ ScfPropertySet aXAxisProp( xApiXAxis );
+ bool bHasXLabels = aXAxisProp.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS );
+
+ // process chart types
+ Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
+ if( xChartTypeCont.is() )
+ {
+ Sequence< Reference< XChartType > > aChartTypeSeq = xChartTypeCont->getChartTypes();
+ const Reference< XChartType >* pBeg = aChartTypeSeq.getConstArray();
+ const Reference< XChartType >* pEnd = pBeg + aChartTypeSeq.getLength();
+ for( const Reference< XChartType >* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ XclExpChTypeGroupRef xTypeGroup( new XclExpChTypeGroup( GetChRoot(), nGroupIdx ) );
+ xTypeGroup->ConvertType( xDiagram, *pIt, nApiAxesSetIdx, b3dChart, bSwappedAxesSet, bHasXLabels );
+ /* If new chart type group cannot be inserted into a combination
+ chart with existing type groups, insert all series into last
+ contained chart type group instead of creating a new group. */
+ XclExpChTypeGroupRef xLastGroup = GetLastTypeGroup();
+ if( xLastGroup && !(xTypeGroup->IsCombinable2d() && xLastGroup->IsCombinable2d()) )
+ {
+ xLastGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
+ }
+ else
+ {
+ xTypeGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
+ if( xTypeGroup->IsValidGroup() )
+ {
+ maTypeGroups.AppendRecord( xTypeGroup );
+ ++nGroupIdx;
+ }
+ }
+ }
+ }
+
+ if( XclExpChTypeGroup* pGroup = GetFirstTypeGroup().get() )
+ {
+ const XclChExtTypeInfo& rTypeInfo = pGroup->GetTypeInfo();
+
+ // create axes according to chart type (no axes for pie and donut charts)
+ if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
+ {
+ ConvertAxis( mxXAxis, EXC_CHAXIS_X, mxXAxisTitle, EXC_CHOBJLINK_XAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_Y );
+ ConvertAxis( mxYAxis, EXC_CHAXIS_Y, mxYAxisTitle, EXC_CHOBJLINK_YAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_X );
+ if( pGroup->Is3dDeepChart() )
+ ConvertAxis( mxZAxis, EXC_CHAXIS_Z, mxZAxisTitle, EXC_CHOBJLINK_ZAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_NONE );
+ }
+
+ // X axis category ranges
+ if( rTypeInfo.mbCategoryAxis && xApiXAxis.is() )
+ {
+ const ScaleData aScaleData = xApiXAxis->getScaleData();
+ for( size_t nIdx = 0, nSize = maTypeGroups.GetSize(); nIdx < nSize; ++nIdx )
+ maTypeGroups.GetRecord( nIdx )->ConvertCategSequence( aScaleData.Categories );
+ }
+
+ // legend
+ if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
+ {
+ Reference< XLegend > xLegend = xDiagram->getLegend();
+ if( xLegend.is() )
+ {
+ ScfPropertySet aLegendProp( xLegend );
+ pGroup->ConvertLegend( aLegendProp );
+ }
+ }
+ }
+ }
+ }
+
+ // wall/floor/diagram frame formatting
+ if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
+ {
+ XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup && xTypeGroup->Is3dWallChart() )
+ {
+ // wall/floor formatting (3D charts)
+ if( mxXAxis )
+ mxXAxis->ConvertWall( xDiagram );
+ if( mxYAxis )
+ mxYAxis->ConvertWall( xDiagram );
+ }
+ else
+ {
+ // diagram background formatting
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxPlotFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_PLOTFRAME );
+ }
+ }
+
+ // inner and outer plot area position and size
+ try
+ {
+ Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
+ Reference< cssc::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
+ // set manual flag in chart data
+ if( !xPositioning->isAutomaticDiagramPositioning() )
+ GetChartData().SetManualPlotArea();
+ // the CHAXESSET record contains the inner plot area
+ maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() );
+ // the embedded CHFRAMEPOS record contains the outer plot area
+ mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
+ // for pie charts, always use inner plot area size to exclude the data labels as Excel does
+ const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get();
+ bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE);
+ mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect :
+ CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // return first unused chart type group index for next axes set
+ return nGroupIdx;
+}
+
+bool XclExpChAxesSet::Is3dChart() const
+{
+ XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ return xTypeGroup && xTypeGroup->Is3dChart();
+}
+
+void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm )
+{
+ lclSaveRecord( rStrm, mxFramePos );
+ lclSaveRecord( rStrm, mxXAxis );
+ lclSaveRecord( rStrm, mxYAxis );
+ lclSaveRecord( rStrm, mxZAxis );
+ lclSaveRecord( rStrm, mxXAxisTitle );
+ lclSaveRecord( rStrm, mxYAxisTitle );
+ lclSaveRecord( rStrm, mxZAxisTitle );
+ if( mxPlotFrame )
+ {
+ XclExpEmptyRecord( EXC_ID_CHPLOTFRAME ).Save( rStrm );
+ mxPlotFrame->Save( rStrm );
+ }
+ maTypeGroups.Save( rStrm );
+}
+
+XclExpChTypeGroupRef XclExpChAxesSet::GetFirstTypeGroup() const
+{
+ return maTypeGroups.GetFirstRecord();
+}
+
+XclExpChTypeGroupRef XclExpChAxesSet::GetLastTypeGroup() const
+{
+ return maTypeGroups.GetLastRecord();
+}
+
+void XclExpChAxesSet::ConvertAxis(
+ XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
+ XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
+ Reference< XCoordinateSystem > xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
+ sal_Int32 nCrossingAxisDim )
+{
+ // create and convert axis object
+ rxChAxis.reset( new XclExpChAxis( GetChRoot(), nAxisType ) );
+ sal_Int32 nApiAxisDim = rxChAxis->GetApiAxisDimension();
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ Reference< XAxis > xAxis = lclGetApiAxis( xCoordSystem, nApiAxisDim, nApiAxesSetIdx );
+ Reference< XAxis > xCrossingAxis = lclGetApiAxis( xCoordSystem, nCrossingAxisDim, nApiAxesSetIdx );
+ Reference< cssc::XAxis > xChart1Axis = lclGetApiChart1Axis( GetChartDocument(), nApiAxisDim, nApiAxesSetIdx );
+ rxChAxis->Convert( xAxis, xCrossingAxis, xChart1Axis, rTypeInfo );
+
+ // create and convert axis title
+ Reference< XTitled > xTitled( xAxis, UNO_QUERY );
+ rxChAxisTitle = lclCreateTitle( GetChRoot(), xTitled, nTitleTarget );
+}
+
+void XclExpChAxesSet::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maData.mnAxesSetId << maData.maRect;
+}
+
+// The chart object ===========================================================
+
+static void lcl_getChartSubTitle(const Reference<XChartDocument>& xChartDoc,
+ String& rSubTitle)
+{
+ Reference< ::com::sun::star::chart::XChartDocument > xChartDoc1(xChartDoc, UNO_QUERY);
+ if (!xChartDoc1.is())
+ return;
+
+ Reference< XPropertySet > xProp(xChartDoc1->getSubTitle(), UNO_QUERY);
+ if (!xProp.is())
+ return;
+
+ OUString aTitle;
+ Any any = xProp->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("String")) );
+ if (any >>= aTitle)
+ rSubTitle = aTitle;
+}
+
+XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
+ Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) :
+ XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
+{
+ Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
+ // rectangle is stored in 16.16 fixed-point format
+ maRect.mnX = maRect.mnY = 0;
+ maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 );
+ maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 );
+
+ // global chart properties (default values)
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false );
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA );
+ maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;
+
+ // always create both axes set objects
+ mxPrimAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
+ mxSecnAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
+
+ if( xChartDoc.is() )
+ {
+ Reference< XDiagram > xDiagram = xChartDoc->getFirstDiagram();
+
+ // global chart properties (only 'include hidden cells' attribute for now)
+ ScfPropertySet aDiagramProp( xDiagram );
+ bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS );
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden );
+
+ // initialize API conversion (remembers xChartDoc and rChartRect internally)
+ InitConversion( xChartDoc, rChartRect );
+
+ // chart frame
+ ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
+ mxFrame = lclCreateFrame( GetChRoot(), aFrameProp, EXC_CHOBJTYPE_BACKGROUND );
+
+ // chart title
+ Reference< XTitled > xTitled( xChartDoc, UNO_QUERY );
+ String aSubTitle;
+ lcl_getChartSubTitle(xChartDoc, aSubTitle);
+ mxTitle = lclCreateTitle( GetChRoot(), xTitled, EXC_CHOBJLINK_TITLE,
+ aSubTitle.Len() ? &aSubTitle : NULL );
+
+ // diagrams (axes sets)
+ sal_uInt16 nFreeGroupIdx = mxPrimAxesSet->Convert( xDiagram, 0 );
+ if( !mxPrimAxesSet->Is3dChart() )
+ mxSecnAxesSet->Convert( xDiagram, nFreeGroupIdx );
+
+ // treatment of missing values
+ ScfPropertySet aDiaProp( xDiagram );
+ sal_Int32 nMissingValues = 0;
+ if( aDiaProp.GetProperty( nMissingValues, EXC_CHPROP_MISSINGVALUETREATMENT ) )
+ {
+ using namespace cssc::MissingValueTreatment;
+ switch( nMissingValues )
+ {
+ case LEAVE_GAP: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP; break;
+ case USE_ZERO: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_ZERO; break;
+ case CONTINUE: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_INTERPOLATE; break;
+ }
+ }
+
+ // finish API conversion
+ FinishConversion();
+ }
+}
+
+XclExpChSeriesRef XclExpChChart::CreateSeries()
+{
+ XclExpChSeriesRef xSeries;
+ sal_uInt16 nSeriesIdx = static_cast< sal_uInt16 >( maSeries.GetSize() );
+ if( nSeriesIdx <= EXC_CHSERIES_MAXSERIES )
+ {
+ xSeries.reset( new XclExpChSeries( GetChRoot(), nSeriesIdx ) );
+ maSeries.AppendRecord( xSeries );
+ }
+ return xSeries;
+}
+
+void XclExpChChart::RemoveLastSeries()
+{
+ if( !maSeries.IsEmpty() )
+ maSeries.RemoveRecord( maSeries.GetSize() - 1 );
+}
+
+void XclExpChChart::SetDataLabel( XclExpChTextRef xText )
+{
+ if( xText )
+ maLabels.AppendRecord( xText );
+}
+
+void XclExpChChart::SetManualPlotArea()
+{
+ // this flag does not exist in BIFF5
+ if( GetBiff() == EXC_BIFF8 )
+ ::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
+}
+
+void XclExpChChart::WriteSubRecords( XclExpStream& rStrm )
+{
+ // background format
+ lclSaveRecord( rStrm, mxFrame );
+
+ // data series
+ maSeries.Save( rStrm );
+
+ // CHPROPERTIES record
+ rStrm.StartRecord( EXC_ID_CHPROPERTIES, 4 );
+ rStrm << maProps.mnFlags << maProps.mnEmptyMode << sal_uInt8( 0 );
+ rStrm.EndRecord();
+
+ // axes sets (always save primary axes set)
+ sal_uInt16 nUsedAxesSets = mxSecnAxesSet->IsValidAxesSet() ? 2 : 1;
+ XclExpUInt16Record( EXC_ID_CHUSEDAXESSETS, nUsedAxesSets ).Save( rStrm );
+ mxPrimAxesSet->Save( rStrm );
+ if( mxSecnAxesSet->IsValidAxesSet() )
+ mxSecnAxesSet->Save( rStrm );
+
+ // chart title and data labels
+ lclSaveRecord( rStrm, mxTitle );
+ maLabels.Save( rStrm );
+}
+
+void XclExpChChart::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maRect;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot,
+ const Reference< XModel >& rxModel, const Size& rChartSize ) :
+ XclExpRoot( rRoot )
+{
+ if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) )
+ {
+ ScfPropertySet aPropSet( rxModel );
+ Reference< XShapes > xShapes;
+ if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) )
+ {
+ /* Create a new independent object manager with own DFF stream for the
+ DGCONTAINER, pass global manager as parent for shared usage of
+ global DFF data (picture container etc.). */
+ mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) );
+ // initialize the drawing object list
+ mxObjMgr->StartSheet();
+ // process the draw page (convert all shapes)
+ mxObjRecs = mxObjMgr->ProcessDrawing( xShapes );
+ // finalize the DFF stream
+ mxObjMgr->EndDocument();
+ }
+ }
+}
+
+XclExpChartDrawing::~XclExpChartDrawing()
+{
+}
+
+void XclExpChartDrawing::Save( XclExpStream& rStrm )
+{
+ if( mxObjRecs )
+ mxObjRecs->Save( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) :
+ XclExpSubStream( EXC_BOF_CHART ),
+ XclExpRoot( rRoot )
+{
+ AppendNewRecord( new XclExpChartPageSettings( rRoot ) );
+ AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) );
+ AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) );
+ AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) );
+
+ Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
+ AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xecontent.cxx b/sc/source/filter/excel/xecontent.cxx
new file mode 100644
index 000000000000..b25cc7f20b1e
--- /dev/null
+++ b/sc/source/filter/excel/xecontent.cxx
@@ -0,0 +1,1496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xecontent.hxx"
+
+#include <list>
+#include <algorithm>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/itemset.hxx>
+#include <formula/grammar.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include "document.hxx"
+#include "validat.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "rangenam.hxx"
+#include "tokenarray.hxx"
+#include "stlpool.hxx"
+#include "patattr.hxx"
+#include "fapihelper.hxx"
+#include "xehelper.hxx"
+#include "xestyle.hxx"
+#include "xename.hxx"
+
+using namespace ::oox;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::XAreaLinks;
+using ::com::sun::star::sheet::XAreaLink;
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// Shared string table ========================================================
+
+// 1 = SST hash table statistics prompt
+#define EXC_INCL_SST_STATISTICS 0
+
+// ----------------------------------------------------------------------------
+
+/** A single string entry in the hash table. */
+struct XclExpHashEntry
+{
+ const XclExpString* mpString; /// Pointer to the string (no ownership).
+ sal_uInt32 mnSstIndex; /// The SST index of this string.
+ inline explicit XclExpHashEntry( const XclExpString* pString = 0, sal_uInt32 nSstIndex = 0 ) :
+ mpString( pString ), mnSstIndex( nSstIndex ) {}
+};
+
+/** Function object for strict weak ordering. */
+struct XclExpHashEntrySWO
+{
+ inline bool operator()( const XclExpHashEntry& rLeft, const XclExpHashEntry& rRight ) const
+ { return *rLeft.mpString < *rRight.mpString; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the SST export.
+ @descr Stores all passed strings in a hash table and prevents repeated
+ insertion of equal strings. */
+class XclExpSstImpl
+{
+public:
+ explicit XclExpSstImpl();
+
+ /** Inserts the passed string, if not already inserted, and returns the unique SST index. */
+ sal_uInt32 Insert( XclExpStringRef xString );
+
+ /** Writes the complete SST and EXTSST records. */
+ void Save( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef ::std::list< XclExpStringRef > XclExpStringList;
+ typedef ::std::vector< XclExpHashEntry > XclExpHashVec;
+ typedef ::std::vector< XclExpHashVec > XclExpHashTab;
+
+ XclExpStringList maStringList; /// List of unique strings (in SST ID order).
+ XclExpHashTab maHashTab; /// Hashed table that manages string pointers.
+ sal_uInt32 mnTotal; /// Total count of strings (including doubles).
+ sal_uInt32 mnSize; /// Size of the SST (count of unique strings).
+};
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 EXC_SST_HASHTABLE_SIZE = 2048;
+
+XclExpSstImpl::XclExpSstImpl() :
+ maHashTab( EXC_SST_HASHTABLE_SIZE ),
+ mnTotal( 0 ),
+ mnSize( 0 )
+{
+}
+
+sal_uInt32 XclExpSstImpl::Insert( XclExpStringRef xString )
+{
+ DBG_ASSERT( xString.get(), "XclExpSstImpl::Insert - empty pointer not allowed" );
+ if( !xString.get() )
+ xString.reset( new XclExpString );
+
+ ++mnTotal;
+ sal_uInt32 nSstIndex = 0;
+
+ // calculate hash value in range [0,EXC_SST_HASHTABLE_SIZE)
+ sal_uInt16 nHash = xString->GetHash();
+ (nHash ^= (nHash / EXC_SST_HASHTABLE_SIZE)) %= EXC_SST_HASHTABLE_SIZE;
+
+ XclExpHashVec& rVec = maHashTab[ nHash ];
+ XclExpHashEntry aEntry( xString.get(), mnSize );
+ XclExpHashVec::iterator aIt = ::std::lower_bound( rVec.begin(), rVec.end(), aEntry, XclExpHashEntrySWO() );
+ if( (aIt == rVec.end()) || (*aIt->mpString != *xString) )
+ {
+ nSstIndex = mnSize;
+ maStringList.push_back( xString );
+ rVec.insert( aIt, aEntry );
+ ++mnSize;
+ }
+ else
+ {
+ nSstIndex = aIt->mnSstIndex;
+ }
+
+ return nSstIndex;
+}
+
+void XclExpSstImpl::Save( XclExpStream& rStrm )
+{
+ if( maStringList.empty() )
+ return;
+
+#if (OSL_DEBUG_LEVEL > 1) && EXC_INCL_SST_STATISTICS
+ { // own scope for the statistics
+#define APPENDINT( value ) Append( ByteString::CreateFromInt32( value ) )
+ ScfUInt32Vec aVec;
+ size_t nPerBucket = mnSize / EXC_SST_HASHTABLE_SIZE + 1, nEff = 0;
+ for( XclExpHashTab::const_iterator aTIt = maHashTab.begin(), aTEnd = maHashTab.end(); aTIt != aTEnd; ++aTIt )
+ {
+ size_t nSize = aTIt->size();
+ if( nSize >= aVec.size() ) aVec.resize( nSize + 1, 0 );
+ ++aVec[ nSize ];
+ if( nSize > nPerBucket ) nEff += nSize - nPerBucket;
+ }
+ ByteString aStr( "SST HASHING STATISTICS\n\n" );
+ aStr.Append( "Total count:\t" ).APPENDINT( mnTotal ).Append( " strings\n" );
+ aStr.Append( "Reduced to:\t" ).APPENDINT( mnSize ).Append( " strings (" );
+ aStr.APPENDINT( 100 * mnSize / mnTotal ).Append( "%)\n" );
+ aStr.Append( "Effectivity:\t\t" ).APPENDINT( 100 - 100 * nEff / mnSize );
+ aStr.Append( "% (best: " ).APPENDINT( nPerBucket ).Append( " strings per bucket)\n" );
+ aStr.Append( "\t\tCount of buckets\nBucket size\ttotal\tmax\tTotal strings\n" );
+ for( size_t nIx = 0, nSize = aVec.size(), nInc = 1; nIx < nSize; nIx += nInc )
+ {
+ if( (nIx == 10) || (nIx == 100) || (nIx == 1000) ) nInc = nIx;
+ size_t nMaxIx = ::std::min( nIx + nInc, nSize ), nCount = 0, nMaxCount = 0, nStrings = 0;
+ for( size_t nSubIx = nIx; nSubIx < nMaxIx; ++nSubIx )
+ {
+ nCount += aVec[ nSubIx ];
+ if( aVec[ nSubIx ] > nMaxCount ) nMaxCount = aVec[ nSubIx ];
+ nStrings += nSubIx * aVec[ nSubIx ];
+ }
+ if( nMaxCount )
+ {
+ aStr.APPENDINT( nIx );
+ if( nMaxIx - nIx > 1 ) aStr.Append( '-' ).APPENDINT( nMaxIx - 1 );
+ aStr.Append( "\t\t" ).APPENDINT( nCount ).Append( '\t' ).APPENDINT( nMaxCount );
+ aStr.Append( '\t' ).APPENDINT( nStrings ).Append( '\n' );
+ }
+ }
+ DBG_ERRORFILE( aStr.GetBuffer() );
+#undef APPENDINT
+ }
+#endif
+
+ SvMemoryStream aExtSst( 8192 );
+
+ sal_uInt32 nBucket = mnSize;
+ while( nBucket > 0x0100 )
+ nBucket /= 2;
+
+ sal_uInt16 nPerBucket = llimit_cast< sal_uInt16 >( nBucket, 8 );
+ sal_uInt16 nBucketIndex = 0;
+
+ // *** write the SST record ***
+
+ rStrm.StartRecord( EXC_ID_SST, 8 );
+
+ rStrm << mnTotal << mnSize;
+ for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
+ {
+ if( !nBucketIndex )
+ {
+ // write bucket info before string to get correct record position
+ sal_uInt32 nStrmPos = static_cast< sal_uInt32 >( rStrm.GetSvStreamPos() );
+ sal_uInt16 nRecPos = rStrm.GetRawRecPos() + 4;
+ aExtSst << nStrmPos // stream position
+ << nRecPos // position from start of SST or CONTINUE
+ << sal_uInt16( 0 ); // reserved
+ }
+
+ rStrm << **aIt;
+
+ if( ++nBucketIndex == nPerBucket )
+ nBucketIndex = 0;
+ }
+
+ rStrm.EndRecord();
+
+ // *** write the EXTSST record ***
+
+ rStrm.StartRecord( EXC_ID_EXTSST, 0 );
+
+ rStrm << nPerBucket;
+ rStrm.SetSliceSize( 8 ); // size of one bucket info
+ aExtSst.Seek( STREAM_SEEK_TO_BEGIN );
+ rStrm.CopyFromStream( aExtSst );
+
+ rStrm.EndRecord();
+}
+
+void XclExpSstImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maStringList.empty() )
+ return;
+
+ sax_fastparser::FSHelperPtr pSst = rStrm.CreateOutputStream(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/sharedStrings.xml") ),
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "sharedStrings.xml" )),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" );
+ rStrm.PushStream( pSst );
+
+ pSst->startElement( XML_sst,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ XML_count, OString::valueOf( (sal_Int32) mnTotal ).getStr(),
+ XML_uniqueCount, OString::valueOf( (sal_Int32) mnSize ).getStr(),
+ FSEND );
+
+ for( XclExpStringList::const_iterator aIt = maStringList.begin(), aEnd = maStringList.end(); aIt != aEnd; ++aIt )
+ {
+ pSst->startElement( XML_si, FSEND );
+ (*aIt)->WriteXml( rStrm );
+ pSst->endElement( XML_si );
+ }
+
+ pSst->endElement( XML_sst );
+
+ rStrm.PopStream();
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpSst::XclExpSst() :
+ mxImpl( new XclExpSstImpl )
+{
+}
+
+XclExpSst::~XclExpSst()
+{
+}
+
+sal_uInt32 XclExpSst::Insert( XclExpStringRef xString )
+{
+ return mxImpl->Insert( xString );
+}
+
+void XclExpSst::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+void XclExpSst::SaveXml( XclExpXmlStream& rStrm )
+{
+ mxImpl->SaveXml( rStrm );
+}
+
+// Merged cells ===============================================================
+
+XclExpMergedcells::XclExpMergedcells( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpMergedcells::AppendRange( const ScRange& rRange, sal_uInt32 nBaseXFId )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ maMergedRanges.Append( rRange );
+ maBaseXFIds.push_back( nBaseXFId );
+ }
+}
+
+sal_uInt32 XclExpMergedcells::GetBaseXFId( const ScAddress& rPos ) const
+{
+ DBG_ASSERT( maBaseXFIds.size() == maMergedRanges.size(), "XclExpMergedcells::GetBaseXFId - invalid lists" );
+ ScfUInt32Vec::const_iterator aIt = maBaseXFIds.begin();
+ ScRangeList& rNCRanges = const_cast< ScRangeList& >( maMergedRanges );
+ for ( size_t i = 0, nRanges = rNCRanges.size(); i < nRanges; ++i, ++aIt )
+ {
+ const ScRange* pScRange = rNCRanges[ i ];
+ if( pScRange->In( rPos ) )
+ return *aIt;
+ }
+ return EXC_XFID_NOTFOUND;
+}
+
+void XclExpMergedcells::Save( XclExpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ XclRangeList aXclRanges;
+ GetAddressConverter().ConvertRangeList( aXclRanges, maMergedRanges, true );
+ size_t nFirstRange = 0;
+ size_t nRemainingRanges = aXclRanges.size();
+ while( nRemainingRanges > 0 )
+ {
+ size_t nRangeCount = ::std::min< size_t >( nRemainingRanges, EXC_MERGEDCELLS_MAXCOUNT );
+ rStrm.StartRecord( EXC_ID_MERGEDCELLS, 2 + 8 * nRangeCount );
+ aXclRanges.WriteSubList( rStrm, nFirstRange, nRangeCount );
+ rStrm.EndRecord();
+ nFirstRange += nRangeCount;
+ nRemainingRanges -= nRangeCount;
+ }
+ }
+}
+
+void XclExpMergedcells::SaveXml( XclExpXmlStream& rStrm )
+{
+ size_t nCount = maMergedRanges.size();
+ if( !nCount )
+ return;
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_mergeCells,
+ XML_count, OString::valueOf( (sal_Int32) nCount ).getStr(),
+ FSEND );
+ for( size_t i = 0; i < nCount; ++i )
+ {
+ if( const ScRange* pRange = maMergedRanges[ i ] )
+ {
+ rWorksheet->singleElement( XML_mergeCell,
+ XML_ref, XclXmlUtils::ToOString( *pRange ).getStr(),
+ FSEND );
+ }
+ }
+ rWorksheet->endElement( XML_mergeCells );
+}
+
+// Hyperlinks =================================================================
+
+XclExpHyperlink::XclExpHyperlink( const XclExpRoot& rRoot, const SvxURLField& rUrlField, const ScAddress& rScPos ) :
+ XclExpRecord( EXC_ID_HLINK ),
+ maScPos( rScPos ),
+ mxVarData( new SvMemoryStream ),
+ mnFlags( 0 )
+{
+ const String& rUrl = rUrlField.GetURL();
+ const String& rRepr = rUrlField.GetRepresentation();
+ INetURLObject aUrlObj( rUrl );
+ const INetProtocol eProtocol = aUrlObj.GetProtocol();
+ bool bWithRepr = rRepr.Len() > 0;
+ XclExpStream aXclStrm( *mxVarData, rRoot ); // using in raw write mode.
+
+ // description
+ if( bWithRepr )
+ {
+ XclExpString aDescr( rRepr, EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << sal_uInt32( aDescr.Len() + 1 ); // string length + 1 trailing zero word
+ aDescr.WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_DESCR;
+ mxRepr.reset( new String( rRepr ) );
+ }
+
+ // file link or URL
+ if( eProtocol == INET_PROT_FILE || eProtocol == INET_PROT_SMB )
+ {
+ sal_uInt16 nLevel;
+ bool bRel;
+ String aFileName( BuildFileName( nLevel, bRel, rUrl, rRoot ) );
+
+ if( eProtocol == INET_PROT_SMB )
+ {
+ // #n382718# (and #n261623#) Convert smb notation to '\\'
+ aFileName = aUrlObj.GetMainURL( INetURLObject::NO_DECODE );
+ aFileName = String( aFileName.GetBuffer() + 4 ); // skip the 'smb:' part
+ aFileName.SearchAndReplaceAll( '/', '\\' );
+ }
+
+ if( !bRel )
+ mnFlags |= EXC_HLINK_ABS;
+ mnFlags |= EXC_HLINK_BODY;
+
+ ByteString aAsciiLink( aFileName, rRoot.GetTextEncoding() );
+ XclExpString aLink( aFileName, EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << XclTools::maGuidFileMoniker
+ << nLevel
+ << sal_uInt32( aAsciiLink.Len() + 1 ); // string length + 1 trailing zero byte
+ aXclStrm.Write( aAsciiLink.GetBuffer(), aAsciiLink.Len() );
+ aXclStrm << sal_uInt8( 0 )
+ << sal_uInt32( 0xDEADFFFF );
+ aXclStrm.WriteZeroBytes( 20 );
+ aXclStrm << sal_uInt32( aLink.GetBufferSize() + 6 )
+ << sal_uInt32( aLink.GetBufferSize() ) // byte count, not string length
+ << sal_uInt16( 0x0003 );
+ aLink.WriteBuffer( aXclStrm ); // NO flags
+
+ if( !mxRepr.get() )
+ mxRepr.reset( new String( aFileName ) );
+
+ msTarget = XclXmlUtils::ToOUString( aLink );
+ }
+ else if( eProtocol != INET_PROT_NOT_VALID )
+ {
+ XclExpString aUrl( aUrlObj.GetURLNoMark(), EXC_STR_FORCEUNICODE, 255 );
+ aXclStrm << XclTools::maGuidUrlMoniker
+ << sal_uInt32( aUrl.GetBufferSize() + 2 ); // byte count + 1 trailing zero word
+ aUrl.WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_BODY | EXC_HLINK_ABS;
+ if( !mxRepr.get() )
+ mxRepr.reset( new String( rUrl ) );
+
+ msTarget = XclXmlUtils::ToOUString( aUrl );
+ }
+ else if( rUrl.GetChar( 0 ) == '#' ) // hack for #89066#
+ {
+ String aTextMark( rUrl.Copy( 1 ) );
+
+ xub_StrLen nSepPos = aTextMark.SearchAndReplace( '.', '!' );
+ String aSheetName( aTextMark.Copy(0, nSepPos));
+
+ if ( aSheetName.Search(' ') != STRING_NOTFOUND && aSheetName.GetChar(0) != '\'')
+ {
+ aTextMark.Insert('\'', nSepPos);
+ aTextMark.Insert('\'', 0);
+ }
+
+ mxTextMark.reset( new XclExpString( aTextMark, EXC_STR_FORCEUNICODE, 255 ) );
+ }
+
+ // text mark
+ if( !mxTextMark.get() && aUrlObj.HasMark() )
+ mxTextMark.reset( new XclExpString( aUrlObj.GetMark(), EXC_STR_FORCEUNICODE, 255 ) );
+
+ if( mxTextMark.get() )
+ {
+ aXclStrm << sal_uInt32( mxTextMark->Len() + 1 ); // string length + 1 trailing zero word
+ mxTextMark->WriteBuffer( aXclStrm ); // NO flags
+ aXclStrm << sal_uInt16( 0 );
+
+ mnFlags |= EXC_HLINK_MARK;
+ }
+
+ SetRecSize( 32 + mxVarData->Tell() );
+}
+
+XclExpHyperlink::~XclExpHyperlink()
+{
+}
+
+String XclExpHyperlink::BuildFileName(
+ sal_uInt16& rnLevel, bool& rbRel, const String& rUrl, const XclExpRoot& rRoot ) const
+{
+ String aDosName( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ rnLevel = 0;
+ rbRel = rRoot.IsRelUrl();
+
+ if( rbRel )
+ {
+ // try to convert to relative file name
+ String aTmpName( aDosName );
+ aDosName = INetURLObject::GetRelURL( rRoot.GetBasePath(), rUrl,
+ INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
+
+ if( aDosName.SearchAscii( INET_FILE_SCHEME ) == 0 )
+ {
+ // not converted to rel -> back to old, return absolute flag
+ aDosName = aTmpName;
+ rbRel = false;
+ }
+ else if( aDosName.SearchAscii( "./" ) == 0 )
+ {
+ aDosName.Erase( 0, 2 );
+ }
+ else
+ {
+ while( aDosName.SearchAndReplaceAscii( "../", EMPTY_STRING ) == 0 )
+ ++rnLevel;
+ }
+ }
+ return aDosName;
+}
+
+void XclExpHyperlink::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( maScPos.Col() );
+ sal_uInt16 nXclRow = static_cast< sal_uInt16 >( maScPos.Row() );
+ rStrm << nXclRow << nXclRow << nXclCol << nXclCol;
+ WriteEmbeddedData( rStrm );
+}
+
+void XclExpHyperlink::WriteEmbeddedData( XclExpStream& rStrm )
+{
+ rStrm << XclTools::maGuidStdLink
+ << sal_uInt32( 2 )
+ << mnFlags;
+
+ mxVarData->Seek( STREAM_SEEK_TO_BEGIN );
+ rStrm.CopyFromStream( *mxVarData );
+}
+
+void XclExpHyperlink::SaveXml( XclExpXmlStream& rStrm )
+{
+ OUString sId = msTarget.getLength() ? rStrm.addRelation( rStrm.GetCurrentStream()->getOutputStream(),
+ XclXmlUtils::ToOUString( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
+ msTarget,
+ XclXmlUtils::ToOUString( "External" ) ) : OUString();
+ rStrm.GetCurrentStream()->singleElement( XML_hyperlink,
+ XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
+ FSNS( XML_r, XML_id ), sId.getLength()
+ ? XclXmlUtils::ToOString( sId ).getStr()
+ : NULL,
+ XML_location, mxTextMark.get() != NULL
+ ? XclXmlUtils::ToOString( *mxTextMark ).getStr()
+ : NULL,
+ // OOXTODO: XML_tooltip, from record HLinkTooltip 800h wzTooltip
+ XML_display, XclXmlUtils::ToOString( *mxRepr ).getStr(),
+ FSEND );
+}
+
+// Label ranges ===============================================================
+
+XclExpLabelranges::XclExpLabelranges( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ SCTAB nScTab = GetCurrScTab();
+ // row label ranges
+ FillRangeList( maRowRanges, rRoot.GetDoc().GetRowNameRangesRef(), nScTab );
+ // row labels only over 1 column (restriction of Excel97/2000/XP)
+ for ( size_t i = 0, nRanges = maRowRanges.size(); i < nRanges; ++i )
+ {
+ ScRange* pScRange = maRowRanges[ i ];
+ if( pScRange->aStart.Col() != pScRange->aEnd.Col() )
+ pScRange->aEnd.SetCol( pScRange->aStart.Col() );
+ }
+ // col label ranges
+ FillRangeList( maColRanges, rRoot.GetDoc().GetColNameRangesRef(), nScTab );
+}
+
+void XclExpLabelranges::FillRangeList( ScRangeList& rScRanges,
+ ScRangePairListRef xLabelRangesRef, SCTAB nScTab )
+{
+ for ( size_t i = 0, nPairs = xLabelRangesRef->size(); i < nPairs; ++i )
+ {
+ ScRangePair* pRangePair = (*xLabelRangesRef)[i];
+ const ScRange& rScRange = pRangePair->GetRange( 0 );
+ if( rScRange.aStart.Tab() == nScTab )
+ rScRanges.Append( rScRange );
+ }
+}
+
+void XclExpLabelranges::Save( XclExpStream& rStrm )
+{
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ XclRangeList aRowXclRanges, aColXclRanges;
+ rAddrConv.ConvertRangeList( aRowXclRanges, maRowRanges, false );
+ rAddrConv.ConvertRangeList( aColXclRanges, maColRanges, false );
+ if( !aRowXclRanges.empty() || !aColXclRanges.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_LABELRANGES, 4 + 8 * (aRowXclRanges.size() + aColXclRanges.size()) );
+ rStrm << aRowXclRanges << aColXclRanges;
+ rStrm.EndRecord();
+ }
+}
+
+// Conditional formatting ====================================================
+
+/** Represents a CF record that contains one condition of a conditional format. */
+class XclExpCFImpl : protected XclExpRoot
+{
+public:
+ explicit XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry );
+
+ /** Writes the body of the CF record. */
+ void WriteBody( XclExpStream& rStrm );
+
+private:
+ const ScCondFormatEntry& mrFormatEntry; /// Calc conditional format entry.
+ XclFontData maFontData; /// Font formatting attributes.
+ XclExpCellBorder maBorder; /// Border formatting attributes.
+ XclExpCellArea maArea; /// Pattern formatting attributes.
+ XclTokenArrayRef mxTokArr1; /// Formula for first condition.
+ XclTokenArrayRef mxTokArr2; /// Formula for second condition.
+ sal_uInt32 mnFontColorId; /// Font color ID.
+ sal_uInt8 mnType; /// Type of the condition (cell/formula).
+ sal_uInt8 mnOperator; /// Comparison operator for cell type.
+ bool mbFontUsed; /// true = Any font attribute used.
+ bool mbHeightUsed; /// true = Font height used.
+ bool mbWeightUsed; /// true = Font weight used.
+ bool mbColorUsed; /// true = Font color used.
+ bool mbUnderlUsed; /// true = Font underline type used.
+ bool mbItalicUsed; /// true = Font posture used.
+ bool mbStrikeUsed; /// true = Font strikeout used.
+ bool mbBorderUsed; /// true = Border attribute used.
+ bool mbPattUsed; /// true = Pattern attribute used.
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry ) :
+ XclExpRoot( rRoot ),
+ mrFormatEntry( rFormatEntry ),
+ mnFontColorId( 0 ),
+ mnType( EXC_CF_TYPE_CELL ),
+ mnOperator( EXC_CF_CMP_NONE ),
+ mbFontUsed( false ),
+ mbHeightUsed( false ),
+ mbWeightUsed( false ),
+ mbColorUsed( false ),
+ mbUnderlUsed( false ),
+ mbItalicUsed( false ),
+ mbStrikeUsed( false ),
+ mbBorderUsed( false ),
+ mbPattUsed( false )
+{
+ /* Get formatting attributes here, and not in WriteBody(). This is needed to
+ correctly insert all colors into the palette. */
+
+ if( SfxStyleSheetBase* pStyleSheet = GetDoc().GetStyleSheetPool()->Find( mrFormatEntry.GetStyle(), SFX_STYLE_FAMILY_PARA ) )
+ {
+ const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
+
+ // font
+ mbHeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_HEIGHT, true );
+ mbWeightUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_WEIGHT, true );
+ mbColorUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_COLOR, true );
+ mbUnderlUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_UNDERLINE, true );
+ mbItalicUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_POSTURE, true );
+ mbStrikeUsed = ScfTools::CheckItem( rItemSet, ATTR_FONT_CROSSEDOUT, true );
+ mbFontUsed = mbHeightUsed || mbWeightUsed || mbColorUsed || mbUnderlUsed || mbItalicUsed || mbStrikeUsed;
+ if( mbFontUsed )
+ {
+ Font aFont;
+ ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW );
+ maFontData.FillFromVclFont( aFont );
+ mnFontColorId = GetPalette().InsertColor( maFontData.maColor, EXC_COLOR_CELLTEXT );
+ }
+
+ // border
+ mbBorderUsed = ScfTools::CheckItem( rItemSet, ATTR_BORDER, true );
+ if( mbBorderUsed )
+ maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
+
+ // pattern
+ mbPattUsed = ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, true );
+ if( mbPattUsed )
+ maArea.FillFromItemSet( rItemSet, GetPalette(), GetBiff() );
+ }
+
+ // *** mode and comparison operator ***
+
+ bool bFmla2 = false;
+ switch( rFormatEntry.GetOperation() )
+ {
+ case SC_COND_NONE: mnType = EXC_CF_TYPE_NONE; break;
+ case SC_COND_BETWEEN: mnOperator = EXC_CF_CMP_BETWEEN; bFmla2 = true; break;
+ case SC_COND_NOTBETWEEN: mnOperator = EXC_CF_CMP_NOT_BETWEEN; bFmla2 = true; break;
+ case SC_COND_EQUAL: mnOperator = EXC_CF_CMP_EQUAL; break;
+ case SC_COND_NOTEQUAL: mnOperator = EXC_CF_CMP_NOT_EQUAL; break;
+ case SC_COND_GREATER: mnOperator = EXC_CF_CMP_GREATER; break;
+ case SC_COND_LESS: mnOperator = EXC_CF_CMP_LESS; break;
+ case SC_COND_EQGREATER: mnOperator = EXC_CF_CMP_GREATER_EQUAL; break;
+ case SC_COND_EQLESS: mnOperator = EXC_CF_CMP_LESS_EQUAL; break;
+ case SC_COND_DIRECT: mnType = EXC_CF_TYPE_FMLA; break;
+ default: mnType = EXC_CF_TYPE_NONE;
+ DBG_ERRORFILE( "XclExpCF::WriteBody - unknown condition type" );
+ }
+
+ // *** formulas ***
+
+ XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
+
+ ::std::auto_ptr< ScTokenArray > xScTokArr( mrFormatEntry.CreateTokenArry( 0 ) );
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
+
+ if( bFmla2 )
+ {
+ xScTokArr.reset( mrFormatEntry.CreateTokenArry( 1 ) );
+ mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_CONDFMT, *xScTokArr );
+ }
+}
+
+void XclExpCFImpl::WriteBody( XclExpStream& rStrm )
+{
+ // *** mode and comparison operator ***
+
+ rStrm << mnType << mnOperator;
+
+ // *** formula sizes ***
+
+ sal_uInt16 nFmlaSize1 = mxTokArr1.get() ? mxTokArr1->GetSize() : 0;
+ sal_uInt16 nFmlaSize2 = mxTokArr2.get() ? mxTokArr2->GetSize() : 0;
+ rStrm << nFmlaSize1 << nFmlaSize2;
+
+ // *** formatting blocks ***
+
+ if( mbFontUsed || mbBorderUsed || mbPattUsed )
+ {
+ sal_uInt32 nFlags = EXC_CF_ALLDEFAULT;
+
+ ::set_flag( nFlags, EXC_CF_BLOCK_FONT, mbFontUsed );
+ ::set_flag( nFlags, EXC_CF_BLOCK_BORDER, mbBorderUsed );
+ ::set_flag( nFlags, EXC_CF_BLOCK_AREA, mbPattUsed );
+
+ // attributes used -> set flags to 0.
+ ::set_flag( nFlags, EXC_CF_BORDER_ALL, !mbBorderUsed );
+ ::set_flag( nFlags, EXC_CF_AREA_ALL, !mbPattUsed );
+
+ rStrm << nFlags << sal_uInt16( 0 );
+
+ if( mbFontUsed )
+ {
+ // font height, 0xFFFFFFFF indicates unused
+ sal_uInt32 nHeight = mbHeightUsed ? maFontData.mnHeight : 0xFFFFFFFF;
+ // font style: italic and strikeout
+ sal_uInt32 nStyle = 0;
+ ::set_flag( nStyle, EXC_CF_FONT_STYLE, maFontData.mbItalic );
+ ::set_flag( nStyle, EXC_CF_FONT_STRIKEOUT, maFontData.mbStrikeout );
+ // font color, 0xFFFFFFFF indicates unused
+ sal_uInt32 nColor = mbColorUsed ? GetPalette().GetColorIndex( mnFontColorId ) : 0xFFFFFFFF;
+ // font used flags for italic, weight, and strikeout -> 0 = used, 1 = default
+ sal_uInt32 nFontFlags1 = EXC_CF_FONT_ALLDEFAULT;
+ ::set_flag( nFontFlags1, EXC_CF_FONT_STYLE, !(mbItalicUsed || mbWeightUsed) );
+ ::set_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT, !mbStrikeUsed );
+ // font used flag for underline -> 0 = used, 1 = default
+ sal_uInt32 nFontFlags3 = mbUnderlUsed ? 0 : EXC_CF_FONT_UNDERL;
+
+ rStrm.WriteZeroBytesToRecord( 64 );
+ rStrm << nHeight
+ << nStyle
+ << maFontData.mnWeight
+ << EXC_FONTESC_NONE
+ << maFontData.mnUnderline;
+ rStrm.WriteZeroBytesToRecord( 3 );
+ rStrm << nColor
+ << sal_uInt32( 0 )
+ << nFontFlags1
+ << EXC_CF_FONT_ESCAPEM // escapement never used -> set the flag
+ << nFontFlags3;
+ rStrm.WriteZeroBytesToRecord( 16 );
+ rStrm << sal_uInt16( 1 ); // must be 1
+ }
+
+ if( mbBorderUsed )
+ {
+ sal_uInt16 nLineStyle = 0;
+ sal_uInt32 nLineColor = 0;
+ maBorder.SetFinalColors( GetPalette() );
+ maBorder.FillToCF8( nLineStyle, nLineColor );
+ rStrm << nLineStyle << nLineColor << sal_uInt16( 0 );
+ }
+
+ if( mbPattUsed )
+ {
+ sal_uInt16 nPattern = 0, nColor = 0;
+ maArea.SetFinalColors( GetPalette() );
+ maArea.FillToCF8( nPattern, nColor );
+ rStrm << nPattern << nColor;
+ }
+ }
+ else
+ {
+ // no data blocks at all
+ rStrm << sal_uInt32( 0 ) << sal_uInt16( 0 );
+ }
+
+ // *** formulas ***
+
+ if( mxTokArr1.get() )
+ mxTokArr1->WriteArray( rStrm );
+ if( mxTokArr2.get() )
+ mxTokArr2->WriteArray( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCF::XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry ) :
+ XclExpRecord( EXC_ID_CF ),
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpCFImpl( rRoot, rFormatEntry ) )
+{
+}
+
+XclExpCF::~XclExpCF()
+{
+}
+
+void XclExpCF::WriteBody( XclExpStream& rStrm )
+{
+ mxImpl->WriteBody( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat& rCondFormat ) :
+ XclExpRecord( EXC_ID_CONDFMT ),
+ XclExpRoot( rRoot )
+{
+ ScRangeList aScRanges;
+ GetDoc().FindConditionalFormat( rCondFormat.GetKey(), aScRanges, GetCurrScTab() );
+ GetAddressConverter().ConvertRangeList( maXclRanges, aScRanges, true );
+ if( !maXclRanges.empty() )
+ {
+ for( sal_uInt16 nIndex = 0, nCount = rCondFormat.Count(); nIndex < nCount; ++nIndex )
+ if( const ScCondFormatEntry* pEntry = rCondFormat.GetEntry( nIndex ) )
+ maCFList.AppendNewRecord( new XclExpCF( GetRoot(), *pEntry ) );
+ aScRanges.Format( msSeqRef, SCA_VALID, NULL, formula::FormulaGrammar::CONV_XL_A1 );
+ }
+}
+
+XclExpCondfmt::~XclExpCondfmt()
+{
+}
+
+bool XclExpCondfmt::IsValid() const
+{
+ return !maCFList.IsEmpty() && !maXclRanges.empty();
+}
+
+void XclExpCondfmt::Save( XclExpStream& rStrm )
+{
+ if( IsValid() )
+ {
+ XclExpRecord::Save( rStrm );
+ maCFList.Save( rStrm );
+ }
+}
+
+void XclExpCondfmt::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !maCFList.IsEmpty(), "XclExpCondfmt::WriteBody - no CF records to write" );
+ DBG_ASSERT( !maXclRanges.empty(), "XclExpCondfmt::WriteBody - no cell ranges found" );
+
+ rStrm << static_cast< sal_uInt16 >( maCFList.GetSize() )
+ << sal_uInt16( 1 )
+ << maXclRanges.GetEnclosingRange()
+ << maXclRanges;
+}
+
+void XclExpCondfmt::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !IsValid() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_conditionalFormatting,
+ XML_sqref, XclXmlUtils::ToOString( msSeqRef ).getStr(),
+ // OOXTODO: XML_pivot,
+ FSEND );
+ maCFList.SaveXml( rStrm );
+ // OOXTODO: XML_extLst
+ rWorksheet->endElement( XML_conditionalFormatting );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCondFormatBuffer::XclExpCondFormatBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ if( const ScConditionalFormatList* pCondFmtList = GetDoc().GetCondFormList() )
+ {
+ if( const ScConditionalFormatPtr* ppCondFmt = pCondFmtList->GetData() )
+ {
+ const ScConditionalFormatPtr* ppCondEnd = ppCondFmt + pCondFmtList->Count();
+ for( ; ppCondFmt < ppCondEnd; ++ppCondFmt )
+ {
+ if( *ppCondFmt )
+ {
+ XclExpCondfmtList::RecordRefType xCondfmtRec( new XclExpCondfmt( GetRoot(), **ppCondFmt ) );
+ if( xCondfmtRec->IsValid() )
+ maCondfmtList.AppendRecord( xCondfmtRec );
+ }
+ }
+ }
+ }
+}
+
+void XclExpCondFormatBuffer::Save( XclExpStream& rStrm )
+{
+ maCondfmtList.Save( rStrm );
+}
+
+void XclExpCondFormatBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ maCondfmtList.SaveXml( rStrm );
+}
+
+// Validation =================================================================
+
+namespace {
+
+/** Writes a formula for the DV record. */
+void lclWriteDvFormula( XclExpStream& rStrm, const XclTokenArray* pXclTokArr )
+{
+ sal_uInt16 nFmlaSize = pXclTokArr ? pXclTokArr->GetSize() : 0;
+ rStrm << nFmlaSize << sal_uInt16( 0 );
+ if( pXclTokArr )
+ pXclTokArr->WriteArray( rStrm );
+}
+
+/** Writes a formula for the DV record, based on a single string. */
+void lclWriteDvFormula( XclExpStream& rStrm, const XclExpString& rString )
+{
+ // fake a formula with a single tStr token
+ rStrm << static_cast< sal_uInt16 >( rString.GetSize() + 1 )
+ << sal_uInt16( 0 )
+ << EXC_TOKID_STR
+ << rString;
+}
+
+const char* lcl_GetValidationType( sal_uInt32 nFlags )
+{
+ switch( nFlags & EXC_DV_MODE_MASK )
+ {
+ case EXC_DV_MODE_ANY: return "none";
+ case EXC_DV_MODE_WHOLE: return "whole";
+ case EXC_DV_MODE_DECIMAL: return "decimal";
+ case EXC_DV_MODE_LIST: return "list";
+ case EXC_DV_MODE_DATE: return "date";
+ case EXC_DV_MODE_TIME: return "time";
+ case EXC_DV_MODE_TEXTLEN: return "textLength";
+ case EXC_DV_MODE_CUSTOM: return "custom";
+ }
+ return NULL;
+}
+
+const char* lcl_GetOperatorType( sal_uInt32 nFlags )
+{
+ switch( nFlags & EXC_DV_COND_MASK )
+ {
+ case EXC_DV_COND_BETWEEN: return "between";
+ case EXC_DV_COND_NOTBETWEEN: return "notBetween";
+ case EXC_DV_COND_EQUAL: return "equal";
+ case EXC_DV_COND_NOTEQUAL: return "notEqual";
+ case EXC_DV_COND_GREATER: return "greaterThan";
+ case EXC_DV_COND_LESS: return "lessThan";
+ case EXC_DV_COND_EQGREATER: return "greaterThanOrEqual";
+ case EXC_DV_COND_EQLESS: return "lessThanOrEqual";
+ }
+ return NULL;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uLong nScHandle ) :
+ XclExpRecord( EXC_ID_DV ),
+ XclExpRoot( rRoot ),
+ mnFlags( 0 ),
+ mnScHandle( nScHandle )
+{
+ if( const ScValidationData* pValData = GetDoc().GetValidationEntry( mnScHandle ) )
+ {
+ // prompt box - empty string represented by single NUL character
+ String aTitle, aText;
+ bool bShowPrompt = (pValData->GetInput( aTitle, aText ) == sal_True);
+ if( aTitle.Len() )
+ maPromptTitle.Assign( aTitle );
+ else
+ maPromptTitle.Assign( '\0' );
+ if( aText.Len() )
+ maPromptText.Assign( aText );
+ else
+ maPromptText.Assign( '\0' );
+
+ // error box - empty string represented by single NUL character
+ ScValidErrorStyle eScErrorStyle;
+ bool bShowError = (pValData->GetErrMsg( aTitle, aText, eScErrorStyle ) == sal_True);
+ if( aTitle.Len() )
+ maErrorTitle.Assign( aTitle );
+ else
+ maErrorTitle.Assign( '\0' );
+ if( aText.Len() )
+ maErrorText.Assign( aText );
+ else
+ maErrorText.Assign( '\0' );
+
+ // flags
+ switch( pValData->GetDataMode() )
+ {
+ case SC_VALID_ANY: mnFlags |= EXC_DV_MODE_ANY; break;
+ case SC_VALID_WHOLE: mnFlags |= EXC_DV_MODE_WHOLE; break;
+ case SC_VALID_DECIMAL: mnFlags |= EXC_DV_MODE_DECIMAL; break;
+ case SC_VALID_LIST: mnFlags |= EXC_DV_MODE_LIST; break;
+ case SC_VALID_DATE: mnFlags |= EXC_DV_MODE_DATE; break;
+ case SC_VALID_TIME: mnFlags |= EXC_DV_MODE_TIME; break;
+ case SC_VALID_TEXTLEN: mnFlags |= EXC_DV_MODE_TEXTLEN; break;
+ case SC_VALID_CUSTOM: mnFlags |= EXC_DV_MODE_CUSTOM; break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown mode" );
+ }
+
+ switch( pValData->GetOperation() )
+ {
+ case SC_COND_NONE:
+ case SC_COND_EQUAL: mnFlags |= EXC_DV_COND_EQUAL; break;
+ case SC_COND_LESS: mnFlags |= EXC_DV_COND_LESS; break;
+ case SC_COND_GREATER: mnFlags |= EXC_DV_COND_GREATER; break;
+ case SC_COND_EQLESS: mnFlags |= EXC_DV_COND_EQLESS; break;
+ case SC_COND_EQGREATER: mnFlags |= EXC_DV_COND_EQGREATER; break;
+ case SC_COND_NOTEQUAL: mnFlags |= EXC_DV_COND_NOTEQUAL; break;
+ case SC_COND_BETWEEN: mnFlags |= EXC_DV_COND_BETWEEN; break;
+ case SC_COND_NOTBETWEEN: mnFlags |= EXC_DV_COND_NOTBETWEEN; break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown condition" );
+ }
+ switch( eScErrorStyle )
+ {
+ case SC_VALERR_STOP: mnFlags |= EXC_DV_ERROR_STOP; break;
+ case SC_VALERR_WARNING: mnFlags |= EXC_DV_ERROR_WARNING; break;
+ case SC_VALERR_INFO: mnFlags |= EXC_DV_ERROR_INFO; break;
+ case SC_VALERR_MACRO:
+ // set INFO for validity with macro call, delete title
+ mnFlags |= EXC_DV_ERROR_INFO;
+ maErrorTitle.Assign( '\0' ); // contains macro name
+ break;
+ default: DBG_ERRORFILE( "XclExpDV::XclExpDV - unknown error style" );
+ }
+ ::set_flag( mnFlags, EXC_DV_IGNOREBLANK, pValData->IsIgnoreBlank() );
+ ::set_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN, pValData->GetListType() == ValidListType::INVISIBLE );
+ ::set_flag( mnFlags, EXC_DV_SHOWPROMPT, bShowPrompt );
+ ::set_flag( mnFlags, EXC_DV_SHOWERROR, bShowError );
+
+ // formulas
+ XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
+ ::std::auto_ptr< ScTokenArray > xScTokArr;
+
+ // first formula
+ xScTokArr.reset( pValData->CreateTokenArry( 0 ) );
+ if( xScTokArr.get() )
+ {
+ if( pValData->GetDataMode() == SC_VALID_LIST )
+ {
+ String aString;
+ if( XclTokenArrayHelper::GetStringList( aString, *xScTokArr, '\n' ) )
+ {
+ OUStringBuffer sFormulaBuf;
+ sFormulaBuf.append( (sal_Unicode) '"' );
+ /* Formula is a list of string tokens -> build the Excel string.
+ Data validity is BIFF8 only (important for the XclExpString object).
+ Excel uses the NUL character as string list separator. */
+ mxString1.reset( new XclExpString( EXC_STR_8BITLENGTH ) );
+ xub_StrLen nTokenCnt = aString.GetTokenCount( '\n' );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aString.GetToken( 0, '\n', nStringIx ) );
+ if( nToken > 0 )
+ {
+ mxString1->Append( '\0' );
+ sFormulaBuf.append( (sal_Unicode) ',' );
+ }
+ mxString1->Append( aToken );
+ sFormulaBuf.append( XclXmlUtils::ToOUString( aToken ) );
+ }
+ ::set_flag( mnFlags, EXC_DV_STRINGLIST );
+
+ sFormulaBuf.append( (sal_Unicode) '"' );
+ msFormula1 = sFormulaBuf.makeStringAndClear();
+ }
+ else
+ {
+ /* All other formulas in validation are stored like conditional
+ formatting formulas (with tRefN/tAreaN tokens as value or
+ array class). But NOT the cell references and defined names
+ in list validation - they are stored as reference class
+ tokens... Example:
+ 1) Cell must be equal to A1 -> formula is =A1 -> writes tRefNV token
+ 2) List is taken from A1 -> formula is =A1 -> writes tRefNR token
+ Formula compiler supports this by offering two different functions
+ CreateDataValFormula() and CreateListValFormula(). */
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_LISTVAL, *xScTokArr );
+ msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+ else
+ {
+ // no list validation -> convert the formula
+ mxTokArr1 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
+ msFormula1 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+
+ // second formula
+ xScTokArr.reset( pValData->CreateTokenArry( 1 ) );
+ if( xScTokArr.get() )
+ {
+ mxTokArr2 = rFmlaComp.CreateFormula( EXC_FMLATYPE_DATAVAL, *xScTokArr );
+ msFormula2 = XclXmlUtils::ToOUString( GetDoc(), pValData->GetSrcPos(), xScTokArr.get() );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpDV::XclExpDV - missing core data" );
+ mnScHandle = ULONG_MAX;
+ }
+}
+
+XclExpDV::~XclExpDV()
+{
+}
+
+void XclExpDV::InsertCellRange( const ScRange& rRange )
+{
+ maScRanges.Join( rRange );
+}
+
+bool XclExpDV::Finalize()
+{
+ GetAddressConverter().ConvertRangeList( maXclRanges, maScRanges, true );
+ return (mnScHandle != ULONG_MAX) && !maXclRanges.empty();
+}
+
+void XclExpDV::WriteBody( XclExpStream& rStrm )
+{
+ // flags and strings
+ rStrm << mnFlags << maPromptTitle << maErrorTitle << maPromptText << maErrorText;
+ // condition formulas
+ if( mxString1.get() )
+ lclWriteDvFormula( rStrm, *mxString1 );
+ else
+ lclWriteDvFormula( rStrm, mxTokArr1.get() );
+ lclWriteDvFormula( rStrm, mxTokArr2.get() );
+ // cell ranges
+ rStrm << maXclRanges;
+}
+
+void XclExpDV::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_dataValidation,
+ XML_allowBlank, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_IGNOREBLANK ) ),
+ XML_error, XESTRING_TO_PSZ( maErrorText ),
+ // OOXTODO: XML_errorStyle,
+ XML_errorTitle, XESTRING_TO_PSZ( maErrorTitle ),
+ // OOXTODO: XML_imeMode,
+ XML_operator, lcl_GetOperatorType( mnFlags ),
+ XML_prompt, XESTRING_TO_PSZ( maPromptText ),
+ XML_promptTitle, XESTRING_TO_PSZ( maPromptTitle ),
+ // showDropDown should have been showNoDropDown - check oox/xlsx import for details
+ XML_showDropDown, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SUPPRESSDROPDOWN ) ),
+ XML_showErrorMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWERROR ) ),
+ XML_showInputMessage, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_DV_SHOWPROMPT ) ),
+ XML_sqref, XclXmlUtils::ToOString( maScRanges ).getStr(),
+ XML_type, lcl_GetValidationType( mnFlags ),
+ FSEND );
+ if( msFormula1.getLength() )
+ {
+ rWorksheet->startElement( XML_formula1, FSEND );
+ rWorksheet->writeEscaped( msFormula1 );
+ rWorksheet->endElement( XML_formula1 );
+ }
+ if( msFormula2.getLength() )
+ {
+ rWorksheet->startElement( XML_formula2, FSEND );
+ rWorksheet->writeEscaped( msFormula2 );
+ rWorksheet->endElement( XML_formula2 );
+ }
+ rWorksheet->endElement( XML_dataValidation );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDval::XclExpDval( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_DVAL, 18 ),
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpDval::~XclExpDval()
+{
+}
+
+void XclExpDval::InsertCellRange( const ScRange& rRange, sal_uLong nScHandle )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ XclExpDV& rDVRec = SearchOrCreateDv( nScHandle );
+ rDVRec.InsertCellRange( rRange );
+ }
+}
+
+void XclExpDval::Save( XclExpStream& rStrm )
+{
+ // check all records
+ size_t nPos = maDVList.GetSize();
+ while( nPos )
+ {
+ --nPos; // backwards to keep nPos valid
+ XclExpDVRef xDVRec = maDVList.GetRecord( nPos );
+ if( !xDVRec->Finalize() )
+ maDVList.RemoveRecord( nPos );
+ }
+
+ // write the DVAL and the DV's
+ if( !maDVList.IsEmpty() )
+ {
+ XclExpRecord::Save( rStrm );
+ maDVList.Save( rStrm );
+ }
+}
+
+void XclExpDval::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maDVList.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_dataValidations,
+ XML_count, OString::valueOf( (sal_Int32) maDVList.GetSize() ).getStr(),
+ // OOXTODO: XML_disablePrompts,
+ // OOXTODO: XML_xWindow,
+ // OOXTODO: XML_yWindow,
+ FSEND );
+ maDVList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_dataValidations );
+}
+
+XclExpDV& XclExpDval::SearchOrCreateDv( sal_uLong nScHandle )
+{
+ // test last found record
+ if( mxLastFoundDV.get() && (mxLastFoundDV->GetScHandle() == nScHandle) )
+ return *mxLastFoundDV;
+
+ // binary search
+ size_t nCurrPos = 0;
+ if( !maDVList.IsEmpty() )
+ {
+ size_t nFirstPos = 0;
+ size_t nLastPos = maDVList.GetSize() - 1;
+ bool bLoop = true;
+ sal_uLong nCurrScHandle = ::std::numeric_limits< sal_uLong >::max();
+ while( (nFirstPos <= nLastPos) && bLoop )
+ {
+ nCurrPos = (nFirstPos + nLastPos) / 2;
+ mxLastFoundDV = maDVList.GetRecord( nCurrPos );
+ nCurrScHandle = mxLastFoundDV->GetScHandle();
+ if( nCurrScHandle == nScHandle )
+ bLoop = false;
+ else if( nCurrScHandle < nScHandle )
+ nFirstPos = nCurrPos + 1;
+ else if( nCurrPos )
+ nLastPos = nCurrPos - 1;
+ else // special case for nLastPos = -1
+ bLoop = false;
+ }
+ if( nCurrScHandle == nScHandle )
+ return *mxLastFoundDV;
+ else if( nCurrScHandle < nScHandle )
+ ++nCurrPos;
+ }
+
+ // create new DV record
+ mxLastFoundDV.reset( new XclExpDV( *this, nScHandle ) );
+ maDVList.InsertRecord( mxLastFoundDV, nCurrPos );
+ return *mxLastFoundDV;
+}
+
+void XclExpDval::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 10 );
+ rStrm << EXC_DVAL_NOOBJ << static_cast< sal_uInt32 >( maDVList.GetSize() );
+}
+
+// Web Queries ================================================================
+
+XclExpWebQuery::XclExpWebQuery(
+ const String& rRangeName,
+ const String& rUrl,
+ const String& rSource,
+ sal_Int32 nRefrSecs ) :
+ maDestRange( rRangeName ),
+ maUrl( rUrl ),
+ // refresh delay time: seconds -> minutes
+ mnRefresh( ulimit_cast< sal_Int16 >( (nRefrSecs + 59L) / 60L ) ),
+ mbEntireDoc( false )
+{
+ // comma separated list of HTML table names or indexes
+ xub_StrLen nTokenCnt = rSource.GetTokenCount( ';' );
+ String aNewTables, aAppendTable;
+ xub_StrLen nStringIx = 0;
+ bool bExitLoop = false;
+ for( xub_StrLen nToken = 0; (nToken < nTokenCnt) && !bExitLoop; ++nToken )
+ {
+ String aToken( rSource.GetToken( 0, ';', nStringIx ) );
+ mbEntireDoc = ScfTools::IsHTMLDocName( aToken );
+ bExitLoop = mbEntireDoc || ScfTools::IsHTMLTablesName( aToken );
+ if( !bExitLoop && ScfTools::GetHTMLNameFromName( aToken, aAppendTable ) )
+ ScGlobal::AddToken( aNewTables, aAppendTable, ',' );
+ }
+
+ if( !bExitLoop ) // neither HTML_all nor HTML_tables found
+ {
+ if( aNewTables.Len() )
+ mxQryTables.reset( new XclExpString( aNewTables ) );
+ else
+ mbEntireDoc = true;
+ }
+}
+
+XclExpWebQuery::~XclExpWebQuery()
+{
+}
+
+void XclExpWebQuery::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( !mbEntireDoc || !mxQryTables.get(), "XclExpWebQuery::Save - illegal mode" );
+ sal_uInt16 nFlags;
+
+ // QSI record
+ rStrm.StartRecord( EXC_ID_QSI, 10 + maDestRange.GetSize() );
+ rStrm << EXC_QSI_DEFAULTFLAGS
+ << sal_uInt16( 0x0010 )
+ << sal_uInt16( 0x0012 )
+ << sal_uInt32( 0x00000000 )
+ << maDestRange;
+ rStrm.EndRecord();
+
+ // PARAMQRY record
+ nFlags = 0;
+ ::insert_value( nFlags, EXC_PQRYTYPE_WEBQUERY, 0, 3 );
+ ::set_flag( nFlags, EXC_PQRY_WEBQUERY );
+ ::set_flag( nFlags, EXC_PQRY_TABLES, !mbEntireDoc );
+ rStrm.StartRecord( EXC_ID_PQRY, 12 );
+ rStrm << nFlags
+ << sal_uInt16( 0x0000 )
+ << sal_uInt16( 0x0001 );
+ rStrm.WriteZeroBytes( 6 );
+ rStrm.EndRecord();
+
+ // WQSTRING record
+ rStrm.StartRecord( EXC_ID_WQSTRING, maUrl.GetSize() );
+ rStrm << maUrl;
+ rStrm.EndRecord();
+
+ // unknown record 0x0802
+ rStrm.StartRecord( EXC_ID_0802, 16 + maDestRange.GetSize() );
+ rStrm << EXC_ID_0802; // repeated record id ?!?
+ rStrm.WriteZeroBytes( 6 );
+ rStrm << sal_uInt16( 0x0003 )
+ << sal_uInt32( 0x00000000 )
+ << sal_uInt16( 0x0010 )
+ << maDestRange;
+ rStrm.EndRecord();
+
+ // WEBQRYSETTINGS record
+ nFlags = mxQryTables.get() ? EXC_WQSETT_SPECTABLES : EXC_WQSETT_ALL;
+ rStrm.StartRecord( EXC_ID_WQSETT, 28 );
+ rStrm << EXC_ID_WQSETT // repeated record id ?!?
+ << sal_uInt16( 0x0000 )
+ << sal_uInt16( 0x0004 )
+ << sal_uInt16( 0x0000 )
+ << EXC_WQSETT_DEFAULTFLAGS
+ << nFlags;
+ rStrm.WriteZeroBytes( 10 );
+ rStrm << mnRefresh // refresh delay in minutes
+ << EXC_WQSETT_FORMATFULL
+ << sal_uInt16( 0x0000 );
+ rStrm.EndRecord();
+
+ // WEBQRYTABLES record
+ if( mxQryTables.get() )
+ {
+ rStrm.StartRecord( EXC_ID_WQTABLES, 4 + mxQryTables->GetSize() );
+ rStrm << EXC_ID_WQTABLES // repeated record id ?!?
+ << sal_uInt16( 0x0000 )
+ << *mxQryTables; // comma separated list of source tables
+ rStrm.EndRecord();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpWebQueryBuffer::XclExpWebQueryBuffer( const XclExpRoot& rRoot )
+{
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ SfxObjectShell* pShell = rRoot.GetDocShell();
+ if( !pShell ) return;
+ ScfPropertySet aModelProp( pShell->GetModel() );
+ if( !aModelProp.Is() ) return;
+
+ Reference< XAreaLinks > xAreaLinks;
+ aModelProp.GetProperty( xAreaLinks, CREATE_OUSTRING( SC_UNO_AREALINKS ) );
+ Reference< XIndexAccess > xLinksIA( xAreaLinks, UNO_QUERY );
+ if( !xLinksIA.is() ) return;
+
+ for( sal_Int32 nIndex = 0, nCount = xLinksIA->getCount(); nIndex < nCount; ++nIndex )
+ {
+ Reference< XAreaLink > xAreaLink( xLinksIA->getByIndex( nIndex ), UNO_QUERY );
+ if( xAreaLink.is() )
+ {
+ CellRangeAddress aDestRange( xAreaLink->getDestArea() );
+ if( static_cast< SCTAB >( aDestRange.Sheet ) == nScTab )
+ {
+ ScfPropertySet aLinkProp( xAreaLink );
+ OUString aFilter;
+ if( aLinkProp.GetProperty( aFilter, CREATE_OUSTRING( SC_UNONAME_FILTER ) ) &&
+ (aFilter == CREATE_OUSTRING( EXC_WEBQRY_FILTER )) )
+ {
+ // get properties
+ OUString /*aFilterOpt,*/ aUrl;
+ sal_Int32 nRefresh = 0;
+
+// aLinkProp.GetProperty( aFilterOpt, CREATE_OUSTRING( SC_UNONAME_FILTOPT ) );
+ aLinkProp.GetProperty( aUrl, CREATE_OUSTRING( SC_UNONAME_LINKURL ) );
+ aLinkProp.GetProperty( nRefresh, CREATE_OUSTRING( SC_UNONAME_REFDELAY ) );
+
+ String aAbsDoc( ScGlobal::GetAbsDocName( aUrl, pShell ) );
+ INetURLObject aUrlObj( aAbsDoc );
+ String aWebQueryUrl( aUrlObj.getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( !aWebQueryUrl.Len() )
+ aWebQueryUrl = aAbsDoc;
+
+ // find range or create a new range
+ String aRangeName;
+ ScRange aScDestRange;
+ ScUnoConversion::FillScRange( aScDestRange, aDestRange );
+ if( const ScRangeData* pRangeData = rRoot.GetNamedRanges().findByRange( aScDestRange ) )
+ {
+ aRangeName = pRangeData->GetName();
+ }
+ else
+ {
+ XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
+ XclExpNameManager& rNameMgr = rRoot.GetNameManager();
+
+ // create a new unique defined name containing the range
+ XclTokenArrayRef xTokArr = rFmlaComp.CreateFormula( EXC_FMLATYPE_WQUERY, aScDestRange );
+ sal_uInt16 nNameIdx = rNameMgr.InsertUniqueName( aUrlObj.getBase(), xTokArr, nScTab );
+ aRangeName = rNameMgr.GetOrigName( nNameIdx );
+ }
+
+ // create and store the web query record
+ if( aRangeName.Len() )
+ AppendNewRecord( new XclExpWebQuery(
+ aRangeName, aWebQueryUrl, xAreaLink->getSourceArea(), nRefresh ) );
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
new file mode 100644
index 000000000000..30197d25f7d5
--- /dev/null
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -0,0 +1,1641 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xeescher.hxx"
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/awt/VisualEffect.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include <set>
+#include <rtl/ustrbuf.h>
+#include <vcl/bmpacc.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include "editutil.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+
+#include "fapihelper.hxx"
+#include "xechart.hxx"
+#include "xeformula.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xestyle.hxx"
+#include "userdat.hxx"
+#include "drwlayer.hxx"
+#include "svx/unoapi.hxx"
+#include "svx/algitem.hxx"
+#include "scitems.hxx"
+#include <editeng/justifyitem.hxx>
+#include "svx/sdtaitm.hxx"
+#include "attrib.hxx"
+#include "document.hxx"
+#include <svx/svdattr.hxx>
+#include "svx/sdr/properties/properties.hxx"
+#include "detfunc.hxx"
+#include "svx/xflclit.hxx"
+#include "svx/xlnstwit.hxx"
+#include "svx/xlnstit.hxx"
+#include "svx/sxmspitm.hxx"
+
+#include <oox/token/tokens.hxx>
+#include <oox/export/drawingml.hxx>
+#include <oox/export/chartexport.hxx>
+#include <oox/export/utils.hxx>
+#include <boost/shared_ptr.hpp>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XShapes;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::embed::XEmbeddedObject;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::form::binding::XBindableValue;
+using ::com::sun::star::form::binding::XValueBinding;
+using ::com::sun::star::form::binding::XListEntrySink;
+using ::com::sun::star::form::binding::XListEntrySource;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::container::XNamed;
+using ::oox::drawingml::DrawingML;
+using ::oox::drawingml::ChartExport;
+using namespace oox;
+
+#define HMM2XL(x) ((x)/26.5)+0.5
+
+#ifdef XLSX_OOXML_FUTURE
+// these function are only used within that context
+// Static Function Helpers
+static const char *ToHorizAlign( SdrTextHorzAdjust eAdjust )
+{
+ switch( eAdjust )
+ {
+ case SDRTEXTHORZADJUST_CENTER:
+ return "center";
+ case SDRTEXTHORZADJUST_RIGHT:
+ return "right";
+ case SDRTEXTHORZADJUST_BLOCK:
+ return "justify";
+ case SDRTEXTHORZADJUST_LEFT:
+ default:
+ return "left";
+ }
+ return "unknown";
+}
+
+static const char *ToVertAlign( SdrTextVertAdjust eAdjust )
+{
+ switch( eAdjust )
+ {
+ case SDRTEXTVERTADJUST_CENTER:
+ return "center";
+ case SDRTEXTVERTADJUST_BOTTOM:
+ return "bottom";
+ case SDRTEXTVERTADJUST_BLOCK:
+ return "justify";
+ case SDRTEXTVERTADJUST_TOP:
+ default:
+ return "top";
+ }
+ return "unknown";
+}
+
+static void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr rComments, Rectangle &aRect )
+{
+ rComments->startElement( FSNS( XML_xdr, XML_col ), FSEND );
+ rComments->writeEscaped( OUString::valueOf( aRect.Left() ) );
+ rComments->endElement( FSNS( XML_xdr, XML_col ) );
+ rComments->startElement( FSNS( XML_xdr, XML_colOff ), FSEND );
+ rComments->writeEscaped( OUString::valueOf( aRect.Top() ) );
+ rComments->endElement( FSNS( XML_xdr, XML_colOff ) );
+ rComments->startElement( FSNS( XML_xdr, XML_row ), FSEND );
+ rComments->writeEscaped( OUString::valueOf( aRect.Right() ) );
+ rComments->endElement( FSNS( XML_xdr, XML_row ) );
+ rComments->startElement( FSNS( XML_xdr, XML_rowOff ), FSEND );
+ rComments->writeEscaped( OUString::valueOf( aRect.Bottom() ) );
+ rComments->endElement( FSNS( XML_xdr, XML_rowOff ) );
+}
+#endif
+
+static void lcl_GetFromTo( const XclExpRoot& rRoot, const Rectangle &aRect, sal_Int32 nTab, Rectangle &aFrom, Rectangle &aTo )
+{
+ bool bTo = false;
+ sal_Int32 nCol = 0, nRow = 0;
+ sal_Int32 nColOff = 0, nRowOff= 0;
+
+ while(1)
+ {
+ Rectangle r = rRoot.GetDocPtr()->GetMMRect( nCol,nRow,nCol,nRow,nTab );
+ if( !bTo )
+ {
+ if( r.Left() <= aRect.Left() )
+ {
+ nCol++;
+ nColOff = aRect.Left() - r.Left();
+ }
+ if( r.Top() <= aRect.Top() )
+ {
+ nRow++;
+ nRowOff = aRect.Top() - r.Top();
+ }
+ if( r.Left() > aRect.Left() && r.Top() > aRect.Top() )
+ {
+ aFrom = Rectangle( nCol-1, HMM2XL( nColOff ),
+ nRow-1, HMM2XL( nRowOff ) );
+ bTo=true;
+ }
+ }
+ if( bTo )
+ {
+ if( r.Right() < aRect.Right() )
+ nCol++;
+ if( r.Bottom() < aRect.Bottom() )
+ nRow++;
+ if( r.Right() >= aRect.Right() && r.Bottom() >= aRect.Bottom() )
+ {
+ aTo = Rectangle( nCol, HMM2XL( aRect.Right() - r.Left() ),
+ nRow, HMM2XL( aRect.Bottom() - r.Top() ));
+ break;
+ }
+ }
+ }
+ return;
+}
+
+// Escher client anchor =======================================================
+
+XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags ) :
+ XclExpRoot( rRoot ),
+ mnFlags( nFlags )
+{
+}
+
+void XclExpDffAnchorBase::SetFlags( const SdrObject& rSdrObj )
+{
+ ImplSetFlags( rSdrObj );
+}
+
+void XclExpDffAnchorBase::SetSdrObject( const SdrObject& rSdrObj )
+{
+ ImplSetFlags( rSdrObj );
+ ImplCalcAnchorRect( rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM );
+}
+
+void XclExpDffAnchorBase::WriteDffData( EscherEx& rEscherEx ) const
+{
+ rEscherEx.AddAtom( 18, ESCHER_ClientAnchor );
+ rEscherEx.GetStream() << mnFlags << maAnchor;
+}
+
+void XclExpDffAnchorBase::WriteData( EscherEx& rEscherEx, const Rectangle& rRect )
+{
+ // the passed rectangle is in twips
+ ImplCalcAnchorRect( rRect, MAP_TWIP );
+ WriteDffData( rEscherEx );
+}
+
+void XclExpDffAnchorBase::ImplSetFlags( const SdrObject& )
+{
+ OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
+}
+
+void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle&, MapUnit )
+{
+ OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot& rRoot ) :
+ XclExpDffAnchorBase( rRoot ),
+ mnScTab( rRoot.GetCurrScTab() )
+{
+}
+
+void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj )
+{
+ // Special case "page anchor" (X==0,Y==1) -> lock pos and size.
+ const Point& rPos = rSdrObj.GetAnchorPos();
+ mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0;
+}
+
+void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
+{
+ maAnchor.SetRect( GetRoot(), mnScTab, rRect, eMapUnit );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
+ const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
+ XclExpDffAnchorBase( rRoot ),
+ maPageSize( rPageSize ),
+ mnScaleX( nScaleX ),
+ mnScaleY( nScaleY )
+{
+}
+
+void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject& /*rSdrObj*/ )
+{
+ // TODO (unsupported feature): fixed size
+}
+
+void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
+{
+ maAnchor.SetRect( maPageSize, mnScaleX, mnScaleY, rRect, eMapUnit, true );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) :
+ XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED )
+{
+ maAnchor.SetRect( rRoot, rRoot.GetCurrScTab(), rRect, MAP_100TH_MM );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) :
+ XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_POSLOCKED )
+{
+ GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true );
+ maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1;
+ maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1;
+ maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0;
+}
+
+// MSODRAWING* records ========================================================
+
+XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ) :
+ XclExpRecord( nRecId ),
+ mrEscherEx( rEscherEx ),
+ mnFragmentKey( rEscherEx.InitNextDffFragment() )
+{
+}
+
+void XclExpMsoDrawingBase::WriteBody( XclExpStream& rStrm )
+{
+ OSL_ENSURE( mrEscherEx.GetStreamPos() == mrEscherEx.GetDffFragmentPos( mnFragmentKey ),
+ "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
+ rStrm.CopyFromStream( mrEscherEx.GetStream(), mrEscherEx.GetDffFragmentSize( mnFragmentKey ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ) :
+ XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWINGGROUP )
+{
+ SvStream& rDffStrm = mrEscherEx.GetStream();
+
+ // write the DGGCONTAINER with some default settings
+ mrEscherEx.OpenContainer( ESCHER_DggContainer );
+
+ // TODO: stuff the OPT atom with our own document defaults?
+ static const sal_uInt8 spnDffOpt[] = {
+ 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
+ 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
+ 0x00, 0x08
+ };
+ mrEscherEx.AddAtom( sizeof( spnDffOpt ), ESCHER_OPT, 3, 3 );
+ rDffStrm.Write( spnDffOpt, sizeof( spnDffOpt ) );
+
+ // SPLITMENUCOLORS contains colors in toolbar
+ static const sal_uInt8 spnDffSplitMenuColors[] = {
+ 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
+ 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
+ };
+ mrEscherEx.AddAtom( sizeof( spnDffSplitMenuColors ), ESCHER_SplitMenuColors, 0, 4 );
+ rDffStrm.Write( spnDffSplitMenuColors, sizeof( spnDffSplitMenuColors ) );
+
+ // close the DGGCONTAINER
+ mrEscherEx.CloseContainer();
+ mrEscherEx.UpdateDffFragmentEnd();
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx& rEscherEx ) :
+ XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWING )
+{
+}
+
+// ============================================================================
+
+XclExpImgData::XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId ) :
+ maGraphic( rGraphic ),
+ mnRecId( nRecId )
+{
+}
+
+void XclExpImgData::Save( XclExpStream& rStrm )
+{
+ Bitmap aBmp = maGraphic.GetBitmap();
+ if( aBmp.GetBitCount() != 24 )
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ if( BitmapReadAccess* pAccess = aBmp.AcquireReadAccess() )
+ {
+ sal_Int32 nWidth = ::std::min< sal_Int32 >( pAccess->Width(), 0xFFFF );
+ sal_Int32 nHeight = ::std::min< sal_Int32 >( pAccess->Height(), 0xFFFF );
+ if( (nWidth > 0) && (nHeight > 0) )
+ {
+ sal_uInt8 nPadding = static_cast< sal_uInt8 >( nWidth & 0x03 );
+ sal_uInt32 nTmpSize = static_cast< sal_uInt32 >( (nWidth * 3 + nPadding) * nHeight + 12 );
+
+ rStrm.StartRecord( mnRecId, nTmpSize + 4 );
+
+ rStrm << EXC_IMGDATA_BMP // BMP format
+ << EXC_IMGDATA_WIN // Windows
+ << nTmpSize // size after _this_ field
+ << sal_uInt32( 12 ) // BITMAPCOREHEADER size
+ << static_cast< sal_uInt16 >( nWidth ) // width
+ << static_cast< sal_uInt16 >( nHeight ) // height
+ << sal_uInt16( 1 ) // planes
+ << sal_uInt16( 24 ); // bits per pixel
+
+ for( sal_Int32 nY = nHeight - 1; nY >= 0; --nY )
+ {
+ for( sal_Int32 nX = 0; nX < nWidth; ++nX )
+ {
+ const BitmapColor& rBmpColor = pAccess->GetPixel( nY, nX );
+ rStrm << rBmpColor.GetBlue() << rBmpColor.GetGreen() << rBmpColor.GetRed();
+ }
+ rStrm.WriteZeroBytes( nPadding );
+ }
+
+ rStrm.EndRecord();
+ }
+ aBmp.ReleaseAccess( pAccess );
+ }
+}
+
+void XclExpImgData::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetCurrentStream();
+
+ DrawingML aDML( pWorksheet, &rStrm, DrawingML::DOCUMENT_XLSX );
+ OUString rId = aDML.WriteImage( maGraphic );
+ pWorksheet->singleElement( XML_picture,
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( rId ).getStr(),
+ FSEND );
+}
+
+// ============================================================================
+
+XclExpControlHelper::XclExpControlHelper( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnEntryCount( 0 )
+{
+}
+
+XclExpControlHelper::~XclExpControlHelper()
+{
+}
+
+void XclExpControlHelper::ConvertSheetLinks( Reference< XShape > xShape )
+{
+ mxCellLink.reset();
+ mxSrcRange.reset();
+ mnEntryCount = 0;
+
+ // get control model
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ if( !xCtrlModel.is() )
+ return;
+
+ // *** cell link *** ------------------------------------------------------
+
+ Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY );
+ if( xBindable.is() )
+ {
+ Reference< XServiceInfo > xServInfo( xBindable->getValueBinding(), UNO_QUERY );
+ if( xServInfo.is() && xServInfo->supportsService( CREATE_OUSTRING( SC_SERVICENAME_VALBIND ) ) )
+ {
+ ScfPropertySet aBindProp( xServInfo );
+ CellAddress aApiAddress;
+ if( aBindProp.GetProperty( aApiAddress, CREATE_OUSTRING( SC_UNONAME_BOUNDCELL ) ) )
+ {
+ ScAddress aCellLink;
+ ScUnoConversion::FillScAddress( aCellLink, aApiAddress );
+ if( GetTabInfo().IsExportTab( aCellLink.Tab() ) )
+ mxCellLink = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aCellLink );
+ }
+ }
+ }
+
+ // *** source range *** ---------------------------------------------------
+
+ Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY );
+ if( xEntrySink.is() )
+ {
+ Reference< XServiceInfo > xServInfo( xEntrySink->getListEntrySource(), UNO_QUERY );
+ if( xServInfo.is() && xServInfo->supportsService( CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ) ) )
+ {
+ ScfPropertySet aSinkProp( xServInfo );
+ CellRangeAddress aApiRange;
+ if( aSinkProp.GetProperty( aApiRange, CREATE_OUSTRING( SC_UNONAME_CELLRANGE ) ) )
+ {
+ ScRange aSrcRange;
+ ScUnoConversion::FillScRange( aSrcRange, aApiRange );
+ if( (aSrcRange.aStart.Tab() == aSrcRange.aEnd.Tab()) && GetTabInfo().IsExportTab( aSrcRange.aStart.Tab() ) )
+ mxSrcRange = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aSrcRange );
+ mnEntryCount = static_cast< sal_uInt16 >( aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1 );
+ }
+ }
+ }
+}
+
+void XclExpControlHelper::WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr ) const
+{
+ sal_uInt16 nFmlaSize = rTokArr.GetSize();
+ rStrm << nFmlaSize << sal_uInt32( 0 );
+ rTokArr.WriteArray( rStrm );
+ if( nFmlaSize & 1 ) // pad to 16-bit
+ rStrm << sal_uInt8( 0 );
+}
+
+void XclExpControlHelper::WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr ) const
+{
+ rStrm.StartRecord( nSubRecId, (rTokArr.GetSize() + 5) & ~1 );
+ WriteFormula( rStrm, rTokArr );
+ rStrm.EndRecord();
+}
+
+// ----------------------------------------------------------------------------
+
+#if EXC_EXP_OCX_CTRL
+
+XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape,
+ const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_PICTURE, true ),
+ XclExpControlHelper( rObjMgr.GetRoot() ),
+ maClassName( rClassName ),
+ mnStrmStart( nStrmStart ),
+ mnStrmSize( nStrmSize )
+{
+ ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
+
+ // OBJ record flags
+ SetLocked( sal_True );
+ SetPrintable( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
+ SetAutoFill( false );
+ SetAutoLine( false );
+
+ // fill DFF property set
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE );
+ Rectangle aDummyRect;
+ EscherPropertyContainer aPropOpt( mrEscherEx, mrEscherEx.QueryPicStream(), aDummyRect );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+
+ // #i51348# name of the control, may overwrite shape name
+ OUString aCtrlName;
+ if( aCtrlProp.GetProperty( aCtrlName, CREATE_OUSTRING( "Name" ) ) && (aCtrlName.getLength() > 0) )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
+
+ // meta file
+ //! TODO - needs check
+ Reference< XPropertySet > xShapePS( xShape, UNO_QUERY );
+ if( xShapePS.is() && aPropOpt.CreateGraphicProperties( xShapePS, CREATE_STRING( "MetaFile" ), false ) )
+ {
+ sal_uInt32 nBlipId;
+ if( aPropOpt.GetOpt( ESCHER_Prop_pib, nBlipId ) )
+ aPropOpt.AddOpt( ESCHER_Prop_pictureId, nBlipId );
+ }
+
+ // write DFF property set to stream
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // spreadsheet links
+ ConvertSheetLinks( xShape );
+}
+
+void XclExpOcxControlObj::WriteSubRecs( XclExpStream& rStrm )
+{
+ // OBJCF - clipboard format
+ rStrm.StartRecord( EXC_ID_OBJCF, 2 );
+ rStrm << sal_uInt16( 2 );
+ rStrm.EndRecord();
+
+ // OBJFLAGS
+ rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
+ rStrm << sal_uInt16( 0x0031 );
+ rStrm.EndRecord();
+
+ // OBJPICTFMLA
+ XclExpString aClass( maClassName );
+ sal_uInt16 nClassNameSize = static_cast< sal_uInt16 >( aClass.GetSize() );
+ sal_uInt16 nClassNamePad = nClassNameSize & 1;
+ sal_uInt16 nFirstPartSize = 12 + nClassNameSize + nClassNamePad;
+
+ const XclTokenArray* pCellLink = GetCellLinkTokArr();
+ sal_uInt16 nCellLinkSize = pCellLink ? ((pCellLink->GetSize() + 7) & 0xFFFE) : 0;
+
+ const XclTokenArray* pSrcRange = GetSourceRangeTokArr();
+ sal_uInt16 nSrcRangeSize = pSrcRange ? ((pSrcRange->GetSize() + 7) & 0xFFFE) : 0;
+
+ sal_uInt16 nPictFmlaSize = nFirstPartSize + nCellLinkSize + nSrcRangeSize + 18;
+ rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nPictFmlaSize );
+
+ rStrm << sal_uInt16( nFirstPartSize ) // size of first part
+ << sal_uInt16( 5 ) // formula size
+ << sal_uInt32( 0 ) // unknown ID
+ << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
+ << sal_uInt8( 3 ) // pad to word
+ << aClass; // "Forms.***.1"
+ rStrm.WriteZeroBytes( nClassNamePad ); // pad to word
+ rStrm << mnStrmStart // start in 'Ctls' stream
+ << mnStrmSize // size in 'Ctls' stream
+ << sal_uInt32( 0 ); // class ID size
+ // cell link
+ rStrm << nCellLinkSize;
+ if( pCellLink )
+ WriteFormula( rStrm, *pCellLink );
+ // list source range
+ rStrm << nSrcRangeSize;
+ if( pSrcRange )
+ WriteFormula( rStrm, *pSrcRange );
+
+ rStrm.EndRecord();
+}
+
+#else
+
+XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rRoot, Reference< XShape > xShape , const Rectangle* pChildAnchor ) :
+ XclObj( rRoot, EXC_OBJTYPE_UNKNOWN, true ),
+ XclMacroHelper( rRoot ),
+ mnHeight( 0 ),
+ mnState( 0 ),
+ mnLineCount( 0 ),
+ mnSelEntry( 0 ),
+ mnScrollValue( 0 ),
+ mnScrollMin( 0 ),
+ mnScrollMax( 100 ),
+ mnScrollStep( 1 ),
+ mnScrollPage( 10 ),
+ mbFlatButton( false ),
+ mbFlatBorder( false ),
+ mbMultiSel( false ),
+ mbScrollHor( false )
+{
+ namespace FormCompType = ::com::sun::star::form::FormComponentType;
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+
+ ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
+ if( !xShape.is() || !aCtrlProp.Is() )
+ return;
+
+ mnHeight = xShape->getSize().Height;
+ if( mnHeight <= 0 )
+ return;
+
+ // control type
+ sal_Int16 nClassId = 0;
+ if( aCtrlProp.GetProperty( nClassId, CREATE_OUSTRING( "ClassId" ) ) )
+ {
+ switch( nClassId )
+ {
+ case FormCompType::COMMANDBUTTON: mnObjType = EXC_OBJTYPE_BUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::RADIOBUTTON: mnObjType = EXC_OBJTYPE_OPTIONBUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::CHECKBOX: mnObjType = EXC_OBJTYPE_CHECKBOX; meEventType = EXC_TBX_EVENT_ACTION; break;
+ case FormCompType::LISTBOX: mnObjType = EXC_OBJTYPE_LISTBOX; meEventType = EXC_TBX_EVENT_CHANGE; break;
+ case FormCompType::COMBOBOX: mnObjType = EXC_OBJTYPE_DROPDOWN; meEventType = EXC_TBX_EVENT_CHANGE; break;
+ case FormCompType::GROUPBOX: mnObjType = EXC_OBJTYPE_GROUPBOX; meEventType = EXC_TBX_EVENT_MOUSE; break;
+ case FormCompType::FIXEDTEXT: mnObjType = EXC_OBJTYPE_LABEL; meEventType = EXC_TBX_EVENT_MOUSE; break;
+ case FormCompType::SCROLLBAR: mnObjType = EXC_OBJTYPE_SCROLLBAR; meEventType = EXC_TBX_EVENT_VALUE; break;
+ case FormCompType::SPINBUTTON: mnObjType = EXC_OBJTYPE_SPIN; meEventType = EXC_TBX_EVENT_VALUE; break;
+ }
+ }
+ if( mnObjType == EXC_OBJTYPE_UNKNOWN )
+ return;
+
+ // OBJ record flags
+ SetLocked( sal_True );
+ SetPrintable( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
+ SetAutoFill( false );
+ SetAutoLine( false );
+
+ // fill DFF property set
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ bool bVisible = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag
+
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01000100 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // Text ID
+ aPropOpt.AddOpt( ESCHER_Prop_WrapText, 0x00000001 );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x001A0008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00100000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+
+ // #i51348# name of the control, may overwrite shape name
+ OUString aCtrlName;
+ if( aCtrlProp.GetProperty( aCtrlName, CREATE_OUSTRING( "Name" ) ) && (aCtrlName.getLength() > 0) )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
+
+ // write DFF property set to stream
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // control label
+ OUString aString;
+ if( aCtrlProp.GetProperty( aString, CREATE_OUSTRING( "Label" ) ) )
+ {
+ /* Be sure to construct the MSODRAWING record containing the
+ ClientTextbox atom after the base OBJ's MSODRAWING record data is
+ completed. */
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ sal_uInt16 nXclFont = EXC_FONT_APP;
+ if( aString.getLength() > 0 )
+ {
+ XclFontData aFontData;
+ GetFontPropSetHelper().ReadFontProperties( aFontData, aCtrlProp, EXC_FONTPROPSET_CONTROL );
+ if( (aFontData.maName.Len() > 0) && (aFontData.mnHeight > 0) )
+ nXclFont = GetFontBuffer().Insert( aFontData, EXC_COLOR_CTRLTEXT );
+ }
+
+ pTxo = new XclTxo( aString, nXclFont );
+ pTxo->SetHorAlign( (mnObjType == EXC_OBJTYPE_BUTTON) ? EXC_OBJ_HOR_CENTER : EXC_OBJ_HOR_LEFT );
+ pTxo->SetVerAlign( EXC_OBJ_VER_CENTER );
+ }
+
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+
+ // other properties
+ aCtrlProp.GetProperty( mnLineCount, CREATE_OUSTRING( "LineCount" ) );
+
+ // border style
+ sal_Int16 nApiButton = AwtVisualEffect::LOOK3D;
+ sal_Int16 nApiBorder = AwtVisualEffect::LOOK3D;
+ switch( nClassId )
+ {
+ case FormCompType::LISTBOX:
+ case FormCompType::COMBOBOX:
+ aCtrlProp.GetProperty( nApiBorder, CREATE_OUSTRING( "Border" ) );
+ break;
+ case FormCompType::CHECKBOX:
+ case FormCompType::RADIOBUTTON:
+ aCtrlProp.GetProperty( nApiButton, CREATE_OUSTRING( "VisualEffect" ) );
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ // Push button cannot be set to flat in Excel
+ case FormCompType::COMMANDBUTTON:
+ nApiBorder = AwtVisualEffect::LOOK3D;
+ break;
+ // Label does not support a border in Excel
+ case FormCompType::FIXEDTEXT:
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ /* Scroll bar and spin button have a "Border" property, but it is
+ really used for a border, and not for own 3D/flat look (#i34712#). */
+ case FormCompType::SCROLLBAR:
+ case FormCompType::SPINBUTTON:
+ nApiButton = AwtVisualEffect::LOOK3D;
+ nApiBorder = AwtVisualEffect::NONE;
+ break;
+ // Group box does not support flat style (#i34712#)
+ case FormCompType::GROUPBOX:
+ nApiBorder = AwtVisualEffect::LOOK3D;
+ break;
+ }
+ mbFlatButton = nApiButton != AwtVisualEffect::LOOK3D;
+ mbFlatBorder = nApiBorder != AwtVisualEffect::LOOK3D;
+
+ // control state
+ sal_Int16 nApiState = 0;
+ if( aCtrlProp.GetProperty( nApiState, CREATE_OUSTRING( "State" ) ) )
+ {
+ switch( nApiState )
+ {
+ case 0: mnState = EXC_OBJ_CHECKBOX_UNCHECKED; break;
+ case 1: mnState = EXC_OBJ_CHECKBOX_CHECKED; break;
+ case 2: mnState = EXC_OBJ_CHECKBOX_TRISTATE; break;
+ }
+ }
+
+ // special control contents
+ switch( nClassId )
+ {
+ case FormCompType::LISTBOX:
+ {
+ mbMultiSel = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "MultiSelection" ) );
+ Sequence< sal_Int16 > aSelection;
+ if( aCtrlProp.GetProperty( aSelection, CREATE_OUSTRING( "SelectedItems" ) ) )
+ {
+ sal_Int32 nLen = aSelection.getLength();
+ if( nLen > 0 )
+ {
+ mnSelEntry = aSelection[ 0 ] + 1;
+ maMultiSel.resize( nLen );
+ const sal_Int16* pnBegin = aSelection.getConstArray();
+ ::std::copy( pnBegin, pnBegin + nLen, maMultiSel.begin() );
+ }
+ }
+
+ // convert listbox with dropdown button to Excel dropdown
+ if( aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
+ mnObjType = EXC_OBJTYPE_DROPDOWN;
+ }
+ break;
+
+ case FormCompType::COMBOBOX:
+ {
+ Sequence< OUString > aStringList;
+ OUString aDefText;
+ if( aCtrlProp.GetProperty( aStringList, CREATE_OUSTRING( "StringItemList" ) ) &&
+ aCtrlProp.GetProperty( aDefText, CREATE_OUSTRING( "Text" ) ) &&
+ aStringList.getLength() && aDefText.getLength() )
+ {
+ const OUString* pBegin = aStringList.getConstArray();
+ const OUString* pEnd = pBegin + aStringList.getLength();
+ const OUString* pString = ::std::find( pBegin, pEnd, aDefText );
+ if( pString != pEnd )
+ mnSelEntry = static_cast< sal_Int16 >( pString - pBegin + 1 ); // 1-based
+ if( mnSelEntry > 0 )
+ maMultiSel.resize( 1, mnSelEntry - 1 );
+ }
+
+ // convert combobox without dropdown button to Excel listbox
+ if( !aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
+ mnObjType = EXC_OBJTYPE_LISTBOX;
+ }
+ break;
+
+ case FormCompType::SCROLLBAR:
+ {
+ sal_Int32 nApiValue = 0;
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValueMin" ) ) )
+ mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValueMax" ) ) )
+ mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MIN );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "ScrollValue" ) ) )
+ mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "LineIncrement" ) ) )
+ mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "BlockIncrement" ) ) )
+ mnScrollPage = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "Orientation" ) ) )
+ mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
+ }
+ break;
+
+ case FormCompType::SPINBUTTON:
+ {
+ sal_Int32 nApiValue = 0;
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValueMin" ) ) )
+ mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValueMax" ) ) )
+ mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinValue" ) ) )
+ mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "SpinIncrement" ) ) )
+ mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ if( aCtrlProp.GetProperty( nApiValue, CREATE_OUSTRING( "Orientation" ) ) )
+ mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
+ }
+ break;
+ }
+
+ // spreadsheet links
+ ConvertSheetLinks( xShape );
+}
+
+bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor& rEvent )
+{
+ return XclMacroHelper::SetMacroLink( rEvent, meEventType );
+}
+
+void XclExpTbxControlObj::WriteSubRecs( XclExpStream& rStrm )
+{
+ switch( mnObjType )
+ {
+ // *** Push buttons, labels ***
+
+ case EXC_OBJTYPE_BUTTON:
+ case EXC_OBJTYPE_LABEL:
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ break;
+
+ // *** Check boxes, option buttons ***
+
+ case EXC_OBJTYPE_CHECKBOX:
+ case EXC_OBJTYPE_OPTIONBUTTON:
+ {
+ // ftCbls - box properties
+ sal_uInt16 nStyle = 0;
+ ::set_flag( nStyle, EXC_OBJ_CHECKBOX_FLAT, mbFlatButton );
+
+ rStrm.StartRecord( EXC_ID_OBJCBLS, 12 );
+ rStrm << mnState;
+ rStrm.WriteZeroBytes( 8 );
+ rStrm << nStyle;
+ rStrm.EndRecord();
+
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftCblsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJCBLSFMLA );
+
+ // ftCblsData subrecord - box properties, again
+ rStrm.StartRecord( EXC_ID_OBJCBLS, 8 );
+ rStrm << mnState;
+ rStrm.WriteZeroBytes( 4 );
+ rStrm << nStyle;
+ rStrm.EndRecord();
+ }
+ break;
+
+ // *** List boxes, combo boxes ***
+
+ case EXC_OBJTYPE_LISTBOX:
+ case EXC_OBJTYPE_DROPDOWN:
+ {
+ sal_uInt16 nEntryCount = GetSourceEntryCount();
+
+ // ftSbs subrecord - Scroll bars
+ sal_Int32 nLineHeight = XclTools::GetHmmFromTwips( 200 ); // always 10pt
+ if( mnObjType == EXC_OBJTYPE_LISTBOX )
+ mnLineCount = static_cast< sal_uInt16 >( mnHeight / nLineHeight );
+ mnScrollValue = 0;
+ mnScrollMin = 0;
+ sal_uInt16 nInvisLines = (nEntryCount >= mnLineCount) ? (nEntryCount - mnLineCount) : 0;
+ mnScrollMax = limit_cast< sal_uInt16 >( nInvisLines, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ mnScrollStep = 1;
+ mnScrollPage = limit_cast< sal_uInt16 >( mnLineCount, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
+ mbScrollHor = false;
+ WriteSbs( rStrm );
+
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftSbsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
+
+ // ftLbsData - source data range and box properties
+ sal_uInt16 nStyle = 0;
+ ::insert_value( nStyle, mbMultiSel ? EXC_OBJ_LISTBOX_MULTI : EXC_OBJ_LISTBOX_SINGLE, 4, 2 );
+ ::set_flag( nStyle, EXC_OBJ_LISTBOX_FLAT, mbFlatBorder );
+
+ rStrm.StartRecord( EXC_ID_OBJLBSDATA, 0 );
+
+ if( const XclTokenArray* pSrcRange = GetSourceRangeTokArr() )
+ {
+ rStrm << static_cast< sal_uInt16 >( (pSrcRange->GetSize() + 7) & 0xFFFE );
+ WriteFormula( rStrm, *pSrcRange );
+ }
+ else
+ rStrm << sal_uInt16( 0 );
+
+ rStrm << nEntryCount << mnSelEntry << nStyle << sal_uInt16( 0 );
+ if( mnObjType == EXC_OBJTYPE_LISTBOX )
+ {
+ if( nEntryCount )
+ {
+ ScfUInt8Vec aSelEx( nEntryCount, 0 );
+ for( ScfInt16Vec::const_iterator aIt = maMultiSel.begin(), aEnd = maMultiSel.end(); aIt != aEnd; ++aIt )
+ if( *aIt < nEntryCount )
+ aSelEx[ *aIt ] = 1;
+ rStrm.Write( &aSelEx[ 0 ], aSelEx.size() );
+ }
+ }
+ else if( mnObjType == EXC_OBJTYPE_DROPDOWN )
+ {
+ rStrm << sal_uInt16( 0 ) << mnLineCount << sal_uInt16( 0 ) << sal_uInt16( 0 );
+ }
+
+ rStrm.EndRecord();
+ }
+ break;
+
+ // *** Spin buttons, scrollbars ***
+
+ case EXC_OBJTYPE_SPIN:
+ case EXC_OBJTYPE_SCROLLBAR:
+ {
+ // ftSbs subrecord - scroll bars
+ WriteSbs( rStrm );
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+ // ftSbsFmla subrecord - cell link
+ WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
+ }
+ break;
+
+ // *** Group boxes ***
+
+ case EXC_OBJTYPE_GROUPBOX:
+ {
+ // ftMacro - macro link
+ WriteMacroSubRec( rStrm );
+
+ // ftGboData subrecord - group box properties
+ sal_uInt16 nStyle = 0;
+ ::set_flag( nStyle, EXC_OBJ_GROUPBOX_FLAT, mbFlatBorder );
+
+ rStrm.StartRecord( EXC_ID_OBJGBODATA, 6 );
+ rStrm << sal_uInt32( 0 )
+ << nStyle;
+ rStrm.EndRecord();
+ }
+ break;
+ }
+}
+
+void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId )
+{
+ if( const XclTokenArray* pCellLink = GetCellLinkTokArr() )
+ WriteFormulaSubRec( rStrm, nSubRecId, *pCellLink );
+}
+
+void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm )
+{
+ sal_uInt16 nOrient = 0;
+ ::set_flag( nOrient, EXC_OBJ_SCROLLBAR_HOR, mbScrollHor );
+ sal_uInt16 nStyle = EXC_OBJ_SCROLLBAR_DEFFLAGS;
+ ::set_flag( nStyle, EXC_OBJ_SCROLLBAR_FLAT, mbFlatButton );
+
+ rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
+ rStrm << sal_uInt32( 0 ) // reserved
+ << mnScrollValue // thumb position
+ << mnScrollMin // thumb min pos
+ << mnScrollMax // thumb max pos
+ << mnScrollStep // line increment
+ << mnScrollPage // page increment
+ << nOrient // 0 = vertical, 1 = horizontal
+ << sal_uInt16( 15 ) // thumb width
+ << nStyle; // flags/style
+ rStrm.EndRecord();
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+
+XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_CHART ),
+ XclExpRoot( rObjMgr.GetRoot() ), mxShape( xShape )
+{
+ // create the MSODRAWING record contents for the chart object
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x0800004E );
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x0800004D );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 );
+ aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x0800004D );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 );
+ aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00020000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 );
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ // anchor
+ SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape );
+ ImplWriteAnchor( GetRoot(), pSdrObj, pChildAnchor );
+
+ // client data (the following OBJ record)
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData );
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ // load the chart OLE object
+ if( SdrOle2Obj* pSdrOleObj = dynamic_cast< SdrOle2Obj* >( pSdrObj ) )
+ svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj->GetObjRef() );
+
+ // create the chart substream object
+ ScfPropertySet aShapeProp( xShape );
+ Reference< XModel > xModel;
+ aShapeProp.GetProperty( xModel, CREATE_OUSTRING( "Model" ) );
+ mxChartDoc.set( xModel,UNO_QUERY );
+ ::com::sun::star::awt::Rectangle aBoundRect;
+ aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) );
+ Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) );
+ mxChart.reset( new XclExpChart( GetRoot(), xModel, aChartRect ) );
+}
+
+XclExpChartObj::~XclExpChartObj()
+{
+}
+
+void XclExpChartObj::Save( XclExpStream& rStrm )
+{
+ // content of OBJ record
+ XclObj::Save( rStrm );
+ // chart substream
+ mxChart->Save( rStrm );
+}
+
+void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm )
+{
+ OSL_TRACE("XclExpChartObj::SaveXml -- Entry point to export chart");
+ sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
+
+ // FIXME: two cell? it seems the two cell anchor is incorrect.
+ pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
+ XML_editAs, "oneCell",
+ FSEND );
+ Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
+ if (xPropSet.is())
+ {
+ XclObjAny::WriteFromTo( rStrm, mxShape, GetTab() );
+ Reference< XModel > xModel( mxChartDoc, UNO_QUERY );
+ ChartExport aChartExport( XML_xdr, pDrawing, xModel, &rStrm, DrawingML::DOCUMENT_XLSX );
+ static sal_Int32 nChartCount = 0;
+ nChartCount++;
+ aChartExport.WriteChartObj( mxShape, nChartCount );
+ // TODO: get the correcto chart number
+ }
+
+ pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
+ // OOXTODO: XML_fLocksWithSheet
+ // OOXTODO: XML_fPrintsWithSheet
+ FSEND );
+ pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
+}
+
+void XclExpChartObj::WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm )
+{
+ pDrawing->startElement( FSNS( XML_xdr, XML_graphicFrame ), FSEND );
+
+ pDrawing->startElement( FSNS( XML_xdr, XML_nvGraphicFramePr ), FSEND );
+
+ // TODO: get the correct chart name chart id
+ OUString sName = CREATE_OUSTRING("Object 1");
+ Reference< XNamed > xNamed( mxShape, UNO_QUERY );
+ if (xNamed.is())
+ {
+ sName = xNamed->getName();
+ }
+ sal_Int32 nID = rStrm.GetUniqueId();
+
+ pDrawing->singleElement( FSNS( XML_xdr, XML_cNvPr ),
+ XML_id, I32S( nID ),
+ XML_name, USS( sName ),
+ FSEND );
+
+ pDrawing->singleElement( FSNS( XML_xdr, XML_cNvGraphicFramePr ),
+ FSEND );
+
+ pDrawing->endElement( FSNS( XML_xdr, XML_nvGraphicFramePr ) );
+
+ // visual chart properties
+ WriteShapeTransformation( pDrawing, mxShape );
+
+ // writer chart object
+ pDrawing->startElement( FSNS( XML_a, XML_graphic ), FSEND );
+ pDrawing->startElement( FSNS( XML_a, XML_graphicData ),
+ XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
+ FSEND );
+ OUString sId;
+ // TODO:
+ static sal_Int32 nChartCount = 0;
+ nChartCount++;
+ sax_fastparser::FSHelperPtr pChart = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "charts/chart", nChartCount ),
+ XclXmlUtils::GetStreamName( "../", "charts/chart", nChartCount ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
+ &sId );
+
+ pDrawing->singleElement( FSNS( XML_c, XML_chart ),
+ FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+
+ rStrm.PushStream( pChart );
+ Reference< XModel > xModel( mxChartDoc, UNO_QUERY );
+ ChartExport aChartExport( XML_xdr, pChart, xModel, &rStrm, DrawingML::DOCUMENT_XLSX );
+ aChartExport.ExportContent();
+
+ rStrm.PopStream();
+
+ pDrawing->endElement( FSNS( XML_a, XML_graphicData ) );
+ pDrawing->endElement( FSNS( XML_a, XML_graphic ) );
+ pDrawing->endElement( FSNS( XML_xdr, XML_graphicFrame ) );
+
+}
+
+void XclExpChartObj::WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
+{
+ ::com::sun::star::awt::Point aPos = rXShape->getPosition();
+ ::com::sun::star::awt::Size aSize = rXShape->getSize();
+
+ pFS->startElementNS( XML_xdr, XML_xfrm,
+ XML_flipH, bFlipH ? "1" : NULL,
+ XML_flipV, bFlipV ? "1" : NULL,
+ XML_rot, nRotation ? I32S( nRotation ) : NULL,
+ FSEND );
+
+ pFS->singleElementNS( XML_a, XML_off, XML_x, IS( MM100toEMU( aPos.X ) ), XML_y, IS( MM100toEMU( aPos.Y ) ), FSEND );
+ pFS->singleElementNS( XML_a, XML_ext, XML_cx, IS( MM100toEMU( aSize.Width ) ), XML_cy, IS( MM100toEMU( aSize.Height ) ), FSEND );
+
+ pFS->endElementNS( XML_xdr, XML_xfrm );
+}
+
+// ============================================================================
+
+XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
+ const ScPostIt* pScNote, const String& rAddText ) :
+ XclExpRecord( EXC_ID_NOTE ),
+ maScPos( rScPos ),
+ mnObjId( EXC_OBJ_INVALID_ID ),
+ mbVisible( pScNote && pScNote->IsCaptionShown() )
+{
+ // get the main note text
+ String aNoteText;
+ if( pScNote )
+ {
+ aNoteText = pScNote->GetText();
+ const EditTextObject *pEditObj = pScNote->GetEditTextObject();
+ if( pEditObj )
+ mpNoteContents = XclExpStringHelper::CreateString( rRoot, *pEditObj );
+ }
+ // append additional text
+ ScGlobal::AddToken( aNoteText, rAddText, '\n', 2 );
+ maOrigNoteText = aNoteText;
+
+ // initialize record dependent on BIFF type
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF5:
+ maNoteText = ByteString( aNoteText, rRoot.GetTextEncoding() );
+ break;
+
+ case EXC_BIFF8:
+ {
+ // TODO: additional text
+ if( pScNote )
+ if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) )
+ {
+ lcl_GetFromTo( rRoot, pCaption->GetLogicRect(), maScPos.Tab(), maCommentFrom, maCommentTo );
+ if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
+ mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible, maScPos, maCommentFrom, maCommentTo ) );
+
+ SfxItemSet aItemSet = pCaption->GetMergedItemSet();
+ meTVA = pCaption->GetTextVerticalAdjust();
+ meTHA = pCaption->GetTextHorizontalAdjust();
+ mbAutoScale = pCaption->GetFitToSize()?true:false;
+ mbLocked = pCaption->IsMoveProtect() | pCaption->IsResizeProtect();
+
+ // AutoFill style would change if Postit.cxx object creation values are changed
+ OUString aCol(((XFillColorItem &)GETITEM(aItemSet, XFillColorItem , XATTR_FILLCOLOR)).GetValue());
+ mbAutoFill = !aCol.getLength() && (GETITEMVALUE(aItemSet, XFillStyleItem, XATTR_FILLSTYLE, sal_uLong) == XFILL_SOLID);
+ mbAutoLine = true;
+ mbRowHidden = (rRoot.GetDoc().RowHidden(maScPos.Row(),maScPos.Tab()));
+ mbColHidden = (rRoot.GetDoc().ColHidden(maScPos.Col(),maScPos.Tab()));
+ }
+
+ SetRecSize( 9 + maAuthor.GetSize() );
+ }
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpNote::Save( XclExpStream& rStrm )
+{
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ // write the NOTE record directly, there may be the need to create more than one
+ const sal_Char* pcBuffer = maNoteText.GetBuffer();
+ sal_uInt16 nCharsLeft = static_cast< sal_uInt16 >( maNoteText.Len() );
+
+ while( nCharsLeft )
+ {
+ sal_uInt16 nWriteChars = ::std::min( nCharsLeft, EXC_NOTE5_MAXLEN );
+
+ rStrm.StartRecord( EXC_ID_NOTE, 6 + nWriteChars );
+ if( pcBuffer == maNoteText.GetBuffer() )
+ {
+ // first record: row, col, length of complete text
+ rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
+ << static_cast< sal_uInt16 >( maScPos.Col() )
+ << nCharsLeft; // still contains full length
+ }
+ else
+ {
+ // next records: -1, 0, length of current text segment
+ rStrm << sal_uInt16( 0xFFFF )
+ << sal_uInt16( 0 )
+ << nWriteChars;
+ }
+ rStrm.Write( pcBuffer, nWriteChars );
+ rStrm.EndRecord();
+
+ pcBuffer += nWriteChars;
+ nCharsLeft = nCharsLeft - nWriteChars;
+ }
+ }
+ break;
+
+ case EXC_BIFF8:
+ if( mnObjId != EXC_OBJ_INVALID_ID )
+ XclExpRecord::Save( rStrm );
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpNote::WriteBody( XclExpStream& rStrm )
+{
+ // BIFF5/BIFF7 is written separately
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
+
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_NOTE_VISIBLE, mbVisible );
+
+ rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
+ << static_cast< sal_uInt16 >( maScPos.Col() )
+ << nFlags
+ << mnObjId
+ << maAuthor
+ << sal_uInt8( 0 );
+}
+
+void XclExpNote::WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr rComments = rStrm.GetCurrentStream();
+
+ rComments->startElement( XML_comment,
+ XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
+ XML_authorId, OString::valueOf( nAuthorId ).getStr(),
+ // OOXTODO: XML_guid,
+ FSEND );
+ rComments->startElement( XML_text, FSEND );
+ // OOXTODO: phoneticPr, rPh, r
+ if( mpNoteContents )
+ mpNoteContents->WriteXml( rStrm );
+ rComments->endElement( XML_text );
+
+/*
+ Export of commentPr is disabled, since the current (Oct 2010)
+ version of MSO 2010 doesn't yet support commentPr
+ */
+#ifdef XLSX_OOXML_FUTURE
+ if( rStrm.getVersion() == oox::core::ISOIEC_29500_2008 )
+ {
+ rComments->startElement( XML_commentPr,
+ XML_autoFill, XclXmlUtils::ToPsz( mbAutoFill ),
+ XML_autoScale, XclXmlUtils::ToPsz( mbAutoScale ),
+ XML_colHidden, XclXmlUtils::ToPsz( mbColHidden ),
+ XML_locked, XclXmlUtils::ToPsz( mbLocked ),
+ XML_rowHidden, XclXmlUtils::ToPsz( mbRowHidden ),
+ XML_textHAlign, ToHorizAlign( meTHA ),
+ XML_textVAlign, ToVertAlign( meTVA ) ,
+ FSEND );
+ rComments->startElement( XML_anchor,
+ XML_moveWithCells, "false",
+ XML_sizeWithCells, "false",
+ FSEND );
+ rComments->startElement( FSNS( XML_xdr, XML_from ), FSEND );
+ lcl_WriteAnchorVertex( rComments, maCommentFrom );
+ rComments->endElement( FSNS( XML_xdr, XML_from ) );
+ rComments->startElement( FSNS( XML_xdr, XML_to ), FSEND );
+ lcl_WriteAnchorVertex( rComments, maCommentTo );
+ rComments->endElement( FSNS( XML_xdr, XML_to ) );
+ rComments->endElement( XML_anchor );
+ rComments->endElement( XML_commentPr );
+ }
+#endif
+ rComments->endElement( XML_comment );
+}
+
+// ============================================================================
+
+XclMacroHelper::XclMacroHelper( const XclExpRoot& rRoot ) :
+ XclExpControlHelper( rRoot )
+{
+}
+
+XclMacroHelper::~XclMacroHelper()
+{
+}
+
+void XclMacroHelper::WriteMacroSubRec( XclExpStream& rStrm )
+{
+ if( mxMacroLink )
+ WriteFormulaSubRec( rStrm, EXC_ID_OBJMACRO, *mxMacroLink );
+}
+
+bool
+XclMacroHelper::SetMacroLink( const ScriptEventDescriptor& rEvent, const XclTbxEventType& nEventType )
+{
+ String aMacroName = XclControlHelper::ExtractFromMacroDescriptor( rEvent, nEventType, GetDocShell() );
+ if( aMacroName.Len() )
+ {
+ return SetMacroLink( aMacroName );
+ }
+ return false;
+}
+
+bool
+XclMacroHelper::SetMacroLink( const String& rMacroName )
+{
+ OSL_TRACE("SetMacroLink( macroname:=%s )", rtl::OUStringToOString( rMacroName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ if( rMacroName.Len() )
+ {
+ sal_uInt16 nExtSheet = GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC );
+ sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rMacroName, true, false );
+ mxMacroLink = GetFormulaCompiler().CreateNameXFormula( nExtSheet, nNameIdx );
+ return true;
+ }
+ return false;
+}
+
+XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ) :
+ XclObjAny( rRoot, xShape ),
+ XclMacroHelper( rRoot )
+{
+ if( SdrObject* pSdrObj = ::GetSdrObjectFromXShape( xShape ) )
+ {
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pSdrObj );
+ if ( pInfo && pInfo->GetMacro().getLength() )
+// FIXME ooo330-m2: XclControlHelper::GetXclMacroName was removed in upstream sources; they started to call XclTools::GetXclMacroName instead; is this enough? it has only one parameter
+// SetMacroLink( XclControlHelper::GetXclMacroName( pInfo->GetMacro(), rRoot.GetDocShell() ) );
+ SetMacroLink( XclTools::GetXclMacroName( pInfo->GetMacro() ) );
+ }
+}
+
+XclExpShapeObj::~XclExpShapeObj()
+{
+}
+
+void XclExpShapeObj::WriteSubRecs( XclExpStream& rStrm )
+{
+ XclObjAny::WriteSubRecs( rStrm );
+ WriteMacroSubRec( rStrm );
+}
+
+// ============================================================================
+
+XclExpComments::XclExpComments( SCTAB nTab, XclExpRecordList< XclExpNote >& rNotes )
+ : mnTab( nTab ), mrNotes( rNotes )
+{
+}
+
+struct OUStringLess : public std::binary_function<OUString, OUString, bool>
+{
+ bool operator()(const OUString& x, const OUString& y) const
+ {
+ return x.compareTo( y ) < 0;
+ }
+};
+
+void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mrNotes.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr rComments = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "comments", mnTab + 1 ),
+ XclXmlUtils::GetStreamName( "../", "comments", mnTab + 1 ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
+ rStrm.PushStream( rComments );
+
+ rComments->startElement( XML_comments,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS( XML_xmlns, XML_xdr ), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
+ FSEND );
+ rComments->startElement( XML_authors, FSEND );
+
+ typedef std::set< OUString, OUStringLess > Authors;
+ Authors aAuthors;
+
+ size_t nNotes = mrNotes.GetSize();
+ for( size_t i = 0; i < nNotes; ++i )
+ {
+ aAuthors.insert( XclXmlUtils::ToOUString( mrNotes.GetRecord( i )->GetAuthor() ) );
+ }
+
+ for( Authors::const_iterator b = aAuthors.begin(), e = aAuthors.end(); b != e; ++b )
+ {
+ rComments->startElement( XML_author, FSEND );
+ rComments->writeEscaped( *b );
+ rComments->endElement( XML_author );
+ }
+
+ rComments->endElement( XML_authors );
+ rComments->startElement( XML_commentList, FSEND );
+
+ for( size_t i = 0; i < nNotes; ++i )
+ {
+ XclExpNoteList::RecordRefType xNote = mrNotes.GetRecord( i );
+ Authors::iterator aAuthor = aAuthors.find(
+ XclXmlUtils::ToOUString( xNote->GetAuthor() ) );
+ sal_Int32 nAuthorId = distance( aAuthors.begin(), aAuthor );
+ xNote->WriteXml( nAuthorId, rStrm );
+ }
+
+ rComments->endElement( XML_commentList );
+ rComments->endElement( XML_comments );
+
+ rStrm.PopStream();
+}
+
+// object manager =============================================================
+
+XclExpObjectManager::XclExpObjectManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ InitStream( true );
+ mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm ) );
+}
+
+XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager& rParent ) :
+ XclExpRoot( rParent.GetRoot() )
+{
+ InitStream( false );
+ mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm, rParent.mxEscherEx.get() ) );
+}
+
+XclExpObjectManager::~XclExpObjectManager()
+{
+}
+
+XclExpDffAnchorBase* XclExpObjectManager::CreateDffAnchor() const
+{
+ return new XclExpDffSheetAnchor( GetRoot() );
+}
+
+boost::shared_ptr< XclExpRecordBase > XclExpObjectManager::CreateDrawingGroup()
+{
+ return boost::shared_ptr< XclExpRecordBase >( new XclExpMsoDrawingGroup( *mxEscherEx ) );
+}
+
+void XclExpObjectManager::StartSheet()
+{
+ mxObjList.reset( new XclExpObjList( GetRoot(), *mxEscherEx ) );
+}
+
+boost::shared_ptr< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( SdrPage* pSdrPage )
+{
+ if( pSdrPage )
+ mxEscherEx->AddSdrPage( *pSdrPage );
+ // the first dummy object may still be open
+ DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
+ while( mxEscherEx->GetGroupLevel() )
+ mxEscherEx->LeaveGroup();
+ mxObjList->EndSheet();
+ return mxObjList;
+}
+
+boost::shared_ptr< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( const Reference< XShapes >& rxShapes )
+{
+ if( rxShapes.is() )
+ mxEscherEx->AddUnoShapes( rxShapes );
+ // the first dummy object may still be open
+ DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
+ while( mxEscherEx->GetGroupLevel() )
+ mxEscherEx->LeaveGroup();
+ mxObjList->EndSheet();
+ return mxObjList;
+}
+
+void XclExpObjectManager::EndDocument()
+{
+ mxEscherEx->EndDocument();
+}
+
+XclExpMsoDrawing* XclExpObjectManager::GetMsodrawingPerSheet()
+{
+ return mxObjList->GetMsodrawingPerSheet();
+}
+
+bool XclExpObjectManager::HasObj() const
+{
+ return mxObjList->Count() > 0;
+}
+
+sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec )
+{
+ return mxObjList->Add( pObjRec );
+}
+
+XclObj* XclExpObjectManager::RemoveLastObj()
+{
+ XclObj* pLastObj = static_cast< XclObj* >( mxObjList->Last() );
+ mxObjList->Remove(); // remove current, which is the Last()
+ return pLastObj;
+}
+
+void XclExpObjectManager::InitStream( bool bTempFile )
+{
+ if( bTempFile )
+ {
+ mxTempFile.reset( new ::utl::TempFile );
+ if( mxTempFile->IsValid() )
+ {
+ mxTempFile->EnableKillingFile();
+ mxDffStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile->GetURL(), STREAM_STD_READWRITE ) );
+ }
+ }
+
+ if( !mxDffStrm.get() )
+ mxDffStrm.reset( new SvMemoryStream );
+
+ mxDffStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
+ const XclExpObjectManager& rParent, const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
+ XclExpObjectManager( rParent ),
+ maPageSize( rPageSize ),
+ mnScaleX( nScaleX ),
+ mnScaleY( nScaleY )
+{
+}
+
+XclExpDffAnchorBase* XclExpEmbeddedObjectManager::CreateDffAnchor() const
+{
+ return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize, mnScaleX, mnScaleY );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
new file mode 100644
index 000000000000..dab35e4ba7b8
--- /dev/null
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -0,0 +1,2629 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// XXX xelink.hxx MUST be included before xeformula.hxx because of the
+// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx
+// (indirectly included via xelink.hxx) and ../inc/ftools.hxx (indirectly
+// included via xeformula.hxx) that does an undef first. Ugly.
+#include "xelink.hxx"
+#include "xeformula.hxx"
+
+#include <list>
+#include <map>
+#include <memory>
+#include "addincol.hxx"
+#include "compiler.hxx"
+#include "document.hxx"
+#include "externalrefmgr.hxx"
+#include "rangelst.hxx"
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "xehelper.hxx"
+#include "xename.hxx"
+#include "xestream.hxx"
+
+using namespace ::formula;
+
+// External reference log =====================================================
+
+XclExpRefLogEntry::XclExpRefLogEntry() :
+ mpUrl( 0 ),
+ mpFirstTab( 0 ),
+ mpLastTab( 0 ),
+ mnFirstXclTab( EXC_TAB_DELETED ),
+ mnLastXclTab( EXC_TAB_DELETED )
+{
+}
+
+// Formula compiler ===========================================================
+
+namespace {
+
+/** Wrapper structure for a processed Calc formula token with additional
+ settings (whitespaces). */
+struct XclExpScToken
+{
+ const FormulaToken* mpScToken; /// Currently processed Calc token.
+ sal_uInt8 mnSpaces; /// Number of spaces before the Calc token.
+
+ inline explicit XclExpScToken() : mpScToken( 0 ), mnSpaces( 0 ) {}
+ inline bool Is() const { return mpScToken != 0; }
+ inline StackVar GetType() const { return mpScToken ? mpScToken->GetType() : static_cast< StackVar >( svUnknown ); }
+ inline OpCode GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : static_cast< OpCode >( ocNone ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Effective token class conversion types. */
+enum XclExpClassConv
+{
+ EXC_CLASSCONV_ORG, /// Keep original class of the token.
+ EXC_CLASSCONV_VAL, /// Convert ARR tokens to VAL class (REF remains uncahnged).
+ EXC_CLASSCONV_ARR /// Convert VAL tokens to ARR class (REF remains uncahnged).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Token class conversion and position of a token in the token array. */
+struct XclExpTokenConvInfo
+{
+ sal_uInt16 mnTokPos; /// Position of the token in the token array.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
+/** Vector of token position and conversion for all operands of an operator,
+ or for all parameters of a function. */
+struct XclExpOperandList : public ::std::vector< XclExpTokenConvInfo >
+{
+ inline explicit XclExpOperandList() { reserve( 2 ); }
+ void AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType );
+};
+
+void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType )
+{
+ resize( size() + 1 );
+ XclExpTokenConvInfo& rConvInfo = back();
+ rConvInfo.mnTokPos = nTokPos;
+ rConvInfo.meConv = eConv;
+ rConvInfo.mbValType = bValType;
+}
+
+typedef boost::shared_ptr< XclExpOperandList > XclExpOperandListRef;
+typedef ::std::vector< XclExpOperandListRef > XclExpOperandListVector;
+
+// ----------------------------------------------------------------------------
+
+/** Encapsulates all data needed for a call to an external function (macro, add-in). */
+struct XclExpExtFuncData
+{
+ String maFuncName; /// Name of the function.
+ bool mbVBasic; /// True = Visual Basic macro call.
+ bool mbHidden; /// True = Create hidden defined name.
+
+ inline explicit XclExpExtFuncData() : mbVBasic( false ), mbHidden( false ) {}
+ void Set( const String& rFuncName, bool bVBasic, bool bHidden );
+};
+
+void XclExpExtFuncData::Set( const String& rFuncName, bool bVBasic, bool bHidden )
+{
+ maFuncName = rFuncName;
+ mbVBasic = bVBasic;
+ mbHidden = bHidden;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Encapsulates all data needed to process an entire function. */
+class XclExpFuncData
+{
+public:
+ explicit XclExpFuncData(
+ const XclExpScToken& rTokData,
+ const XclFunctionInfo& rFuncInfo,
+ const XclExpExtFuncData& rExtFuncData );
+
+ inline const FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
+ inline OpCode GetOpCode() const { return mrFuncInfo.meOpCode; }
+ inline sal_uInt16 GetXclFuncIdx() const { return mrFuncInfo.mnXclFunc; }
+ inline bool IsVolatile() const { return mrFuncInfo.IsVolatile(); }
+ inline bool IsFixedParamCount() const { return mrFuncInfo.IsFixedParamCount(); }
+ inline bool IsMacroFunc() const { return mrFuncInfo.IsMacroFunc(); }
+ inline sal_uInt8 GetSpaces() const { return mrTokData.mnSpaces; }
+ inline const XclExpExtFuncData& GetExtFuncData() const { return maExtFuncData; }
+ inline sal_uInt8 GetReturnClass() const { return mrFuncInfo.mnRetClass; }
+
+ const XclFuncParamInfo& GetParamInfo() const;
+ bool IsCalcOnlyParam() const;
+ bool IsExcelOnlyParam() const;
+ void IncParamInfoIdx();
+
+ inline sal_uInt8 GetMinParamCount() const { return mrFuncInfo.mnMinParamCount; }
+ inline sal_uInt8 GetMaxParamCount() const { return mrFuncInfo.mnMaxParamCount; }
+ inline sal_uInt8 GetParamCount() const { return static_cast< sal_uInt8 >( mxOperands->size() ); }
+ void FinishParam( sal_uInt16 nTokPos );
+ inline XclExpOperandListRef GetOperandList() const { return mxOperands; }
+
+ inline ScfUInt16Vec& GetAttrPosVec() { return maAttrPosVec; }
+ inline void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
+
+private:
+ ScfUInt16Vec maAttrPosVec; /// Token array positions of tAttr tokens.
+ const XclExpScToken& mrTokData; /// Data about processed function name token.
+ const XclFunctionInfo& mrFuncInfo; /// Constant data about processed function.
+ XclExpExtFuncData maExtFuncData; /// Data for external functions (macro, add-in).
+ XclExpOperandListRef mxOperands; /// Class conversion and position of all parameters.
+ const XclFuncParamInfo* mpParamInfo; /// Information for current parameter.
+};
+
+XclExpFuncData::XclExpFuncData( const XclExpScToken& rTokData,
+ const XclFunctionInfo& rFuncInfo, const XclExpExtFuncData& rExtFuncData ) :
+ mrTokData( rTokData ),
+ mrFuncInfo( rFuncInfo ),
+ maExtFuncData( rExtFuncData ),
+ mxOperands( new XclExpOperandList ),
+ mpParamInfo( rFuncInfo.mpParamInfos )
+{
+ DBG_ASSERT( mrTokData.mpScToken, "XclExpFuncData::XclExpFuncData - missing core token" );
+ // set name of an add-in function
+ if( (maExtFuncData.maFuncName.Len() == 0) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
+ maExtFuncData.Set( GetScToken().GetExternal(), true, false );
+}
+
+const XclFuncParamInfo& XclExpFuncData::GetParamInfo() const
+{
+ static const XclFuncParamInfo saInvalidInfo = { EXC_PARAM_NONE, EXC_PARAMCONV_ORG, false };
+ return mpParamInfo ? *mpParamInfo : saInvalidInfo;
+}
+
+bool XclExpFuncData::IsCalcOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_CALCONLY);
+}
+
+bool XclExpFuncData::IsExcelOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_EXCELONLY);
+}
+
+void XclExpFuncData::IncParamInfoIdx()
+{
+ if( mpParamInfo )
+ {
+ // move pointer to next entry, if something explicit follows
+ if( (static_cast<size_t>(mpParamInfo - mrFuncInfo.mpParamInfos + 1) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
+ ++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
+ }
+}
+
+void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
+{
+ // write token class conversion info for this parameter
+ const XclFuncParamInfo& rParamInfo = GetParamInfo();
+ mxOperands->AppendOperand( nTokPos, rParamInfo.meConv, rParamInfo.mbValType );
+ // move to next parameter info structure
+ IncParamInfoIdx();
+}
+
+// compiler configuration -----------------------------------------------------
+
+/** Type of token class handling. */
+enum XclExpFmlaClassType
+{
+ EXC_CLASSTYPE_CELL, /// Cell formula, shared formula.
+ EXC_CLASSTYPE_ARRAY, /// Array formula, conditional formatting, data validation.
+ EXC_CLASSTYPE_NAME /// Defined name, range list.
+};
+
+/** Configuration data of the formula compiler. */
+struct XclExpCompConfig
+{
+ XclFormulaType meType; /// Type of the formula to be created.
+ XclExpFmlaClassType meClassType; /// Token class handling type.
+ bool mbLocalLinkMgr; /// True = local (per-sheet) link manager, false = global.
+ bool mbFromCell; /// True = Any kind of cell formula (cell, array, shared).
+ bool mb3DRefOnly; /// True = Only 3D references allowed (e.g. names).
+ bool mbAllowArrays; /// True = Allow inline arrays.
+};
+
+/** The table containing configuration data for all formula types. */
+static const XclExpCompConfig spConfigTable[] =
+{
+ // formula type token class type lclLM inCell 3dOnly allowArray
+ { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, true, true, false, true },
+ { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, false, false, true, true },
+ { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, true, false, true, true },
+ { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, true, false, false, false },
+ { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, true, false, true, false },
+ { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, true, false, false, false }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
+struct XclExpCompData
+{
+ typedef boost::shared_ptr< ScTokenArray > ScTokenArrayRef;
+
+ const XclExpCompConfig& mrCfg; /// Configuration for current formula type.
+ ScTokenArrayRef mxOwnScTokArr; /// Own clone of a Calc token array.
+ XclTokenArrayIterator maTokArrIt; /// Iterator in Calc token array.
+ XclExpLinkManager* mpLinkMgr; /// Link manager for current context (local/global).
+ XclExpRefLog* mpRefLog; /// Log for external references.
+ const ScAddress* mpScBasePos; /// Current cell position of the formula.
+
+ ScfUInt8Vec maTokVec; /// Byte vector containing token data.
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
+ XclExpOperandListVector maOpListVec; /// Formula structure, maps operators to their operands.
+ ScfUInt16Vec maOpPosStack; /// Stack with positions of operand tokens waiting for an operator.
+ bool mbStopAtSep; /// True = Stop subexpression creation at an ocSep token.
+ bool mbVolatile; /// True = Formula contains volatile function.
+ bool mbOk; /// Current state of the compiler.
+
+ explicit XclExpCompData( const XclExpCompConfig* pCfg );
+};
+
+XclExpCompData::XclExpCompData( const XclExpCompConfig* pCfg ) :
+ mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
+ mpLinkMgr( 0 ),
+ mpRefLog( 0 ),
+ mpScBasePos( 0 ),
+ mbStopAtSep( false ),
+ mbVolatile( false ),
+ mbOk( pCfg != 0 )
+{
+ DBG_ASSERT( pCfg, "XclExpFmlaCompImpl::Init - unknown formula type" );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+/** Implementation class of the export formula compiler. */
+class XclExpFmlaCompImpl : protected XclExpRoot, protected XclTokenArrayHelper
+{
+public:
+ explicit XclExpFmlaCompImpl( const XclExpRoot& rRoot );
+
+ /** Creates an Excel token array from the passed Calc token array. */
+ XclTokenArrayRef CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos = 0, XclExpRefLog* pRefLog = 0 );
+ /** Creates a single error token containing the passed error code. */
+ XclTokenArrayRef CreateErrorFormula( sal_uInt8 nErrCode );
+ /** Creates a single token for a special cell reference. */
+ XclTokenArrayRef CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos );
+ /** Creates a single tNameXR token for a reference to an external name. */
+ XclTokenArrayRef CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
+
+ /** Returns true, if the passed formula type allows 3D references only. */
+ bool Is3DRefOnly( XclFormulaType eType ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ const XclExpCompConfig* GetConfigForType( XclFormulaType eType ) const;
+ inline sal_uInt16 GetSize() const { return static_cast< sal_uInt16 >( mxData->maTokVec.size() ); }
+
+ void Init( XclFormulaType eType );
+ void Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
+
+ void RecalcTokenClasses();
+ void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass );
+
+ void FinalizeFormula();
+ XclTokenArrayRef CreateTokenArray();
+
+ // compiler ---------------------------------------------------------------
+ // XclExpScToken: pass-by-value and return-by-value is intended
+
+ const FormulaToken* GetNextRawToken();
+ const FormulaToken* PeekNextRawToken( bool bSkipSpaces ) const;
+
+ bool GetNextToken( XclExpScToken& rTokData );
+ XclExpScToken GetNextToken();
+
+ XclExpScToken Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep );
+ XclExpScToken SkipExpression( XclExpScToken aTokData, bool bStopAtSep );
+
+ XclExpScToken OrTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AndTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken CompareTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ConcatTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AddSubTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken MulDivTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken PowTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ListTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken Factor( XclExpScToken aTokData );
+
+ // formula structure ------------------------------------------------------
+
+ void ProcessDouble( const XclExpScToken& rTokData );
+ void ProcessString( const XclExpScToken& rTokData );
+ void ProcessMissing( const XclExpScToken& rTokData );
+ void ProcessBad( const XclExpScToken& rTokData );
+ void ProcessParentheses( const XclExpScToken& rTokData );
+ void ProcessBoolean( const XclExpScToken& rTokData );
+ void ProcessDdeLink( const XclExpScToken& rTokData );
+ void ProcessExternal( const XclExpScToken& rTokData );
+ void ProcessMatrix( const XclExpScToken& rTokData );
+
+ void ProcessFunction( const XclExpScToken& rTokData );
+ void PrepareFunction( XclExpFuncData& rFuncData );
+ void FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces );
+ void FinishIfFunction( XclExpFuncData& rFuncData );
+ void FinishChooseFunction( XclExpFuncData& rFuncData );
+
+ XclExpScToken ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
+ void PrepareParam( XclExpFuncData& rFuncData );
+ void FinishParam( XclExpFuncData& rFuncData );
+ void AppendDefaultParam( XclExpFuncData& rFuncData );
+ void AppendTrailingParam( XclExpFuncData& rFuncData );
+
+ // reference handling -----------------------------------------------------
+
+ SCTAB GetScTab( const ScSingleRefData& rRefData ) const;
+ bool IsRef2D( const ScSingleRefData& rRefData ) const;
+ bool IsRef2D( const ScComplexRefData& rRefData ) const;
+
+ void ConvertRefData( ScSingleRefData& rRefData, XclAddress& rXclPos,
+ bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const;
+ void ConvertRefData( ScComplexRefData& rRefData, XclRange& rXclRange,
+ bool bNatLangRef ) const;
+
+ XclExpRefLogEntry* GetNewRefLogEntry();
+ void ProcessCellRef( const XclExpScToken& rTokData );
+ void ProcessRangeRef( const XclExpScToken& rTokData );
+ void ProcessExternalCellRef( const XclExpScToken& rTokData );
+ void ProcessExternalRangeRef( const XclExpScToken& rTokData );
+ void ProcessDefinedName( const XclExpScToken& rTokData );
+ void ProcessExternalName( const XclExpScToken& rTokData );
+
+ // token vector -----------------------------------------------------------
+
+ void PushOperandPos( sal_uInt16 nTokPos );
+ void PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands );
+ sal_uInt16 PopOperandPos();
+
+ void Append( sal_uInt8 nData );
+ void Append( sal_uInt8 nData, size_t nCount );
+ void Append( sal_uInt16 nData );
+ void Append( sal_uInt32 nData );
+ void Append( double fData );
+ void Append( const String& rString );
+
+ void AppendAddress( const XclAddress& rXclPos );
+ void AppendRange( const XclRange& rXclRange );
+
+ void AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount );
+
+ void AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
+ void AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
+ void AppendNumToken( double fValue, sal_uInt8 nSpaces = 0 );
+ void AppendBoolToken( bool bValue, sal_uInt8 nSpaces = 0 );
+ void AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces = 0 );
+ void AppendMissingToken( sal_uInt8 nSpaces = 0 );
+ void AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces = 0 );
+ void AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces = 0 );
+ void AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces = 0 );
+ void AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+
+ void AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces = 0 );
+ void AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
+ void AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces = 0 );
+ void AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount );
+ void AppendFuncToken( const XclExpFuncData& rFuncData );
+
+ void AppendParenToken( sal_uInt8 nOpenSpaces = 0, sal_uInt8 nCloseSpaces = 0 );
+ void AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType );
+
+ void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
+ void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
+
+ void UpdateAttrGoto( sal_uInt16 nAttrPos );
+
+ bool IsSpaceToken( sal_uInt16 nPos ) const;
+ void RemoveTrailingParen();
+
+ void AppendExt( sal_uInt8 nData );
+ void AppendExt( sal_uInt8 nData, size_t nCount );
+ void AppendExt( sal_uInt16 nData );
+ void AppendExt( double fData );
+ void AppendExt( const String& rString );
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap;
+ typedef boost::shared_ptr< XclExpCompData > XclExpCompDataRef;
+ typedef ::std::vector< XclExpCompDataRef > XclExpCompDataVector;
+
+ XclExpCompConfigMap maCfgMap; /// Compiler configuration map for all formula types.
+ XclFunctionProvider maFuncProv; /// Excel function data provider.
+ XclExpCompDataRef mxData; /// Working data for current formula.
+ XclExpCompDataVector maDataStack; /// Stack for working data, when compiler is called recursively.
+ const XclBiff meBiff; /// Cached BIFF version to save GetBiff() calls.
+ const SCsCOL mnMaxAbsCol; /// Maximum column index.
+ const SCsROW mnMaxAbsRow; /// Maximum row index.
+ const SCsCOL mnMaxScCol; /// Maximum column index in Calc itself.
+ const SCsROW mnMaxScRow; /// Maximum row index in Calc itself.
+ const sal_uInt16 mnMaxColMask; /// Mask to delete invalid bits in column fields.
+ const sal_uInt32 mnMaxRowMask; /// Mask to delete invalid bits in row fields.
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() ),
+ mnMaxAbsCol( static_cast< SCsCOL >( rRoot.GetXclMaxPos().Col() ) ),
+ mnMaxAbsRow( static_cast< SCsROW >( rRoot.GetXclMaxPos().Row() ) ),
+ mnMaxScCol( static_cast< SCsCOL >( rRoot.GetScMaxPos().Col() ) ),
+ mnMaxScRow( static_cast< SCsROW >( rRoot.GetScMaxPos().Row() ) ),
+ mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Col() ) ),
+ mnMaxRowMask( static_cast< sal_uInt32 >( rRoot.GetXclMaxPos().Row() ) )
+{
+ // build the configuration map
+ for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_TABLE_END( spConfigTable ); ++pEntry )
+ maCfgMap[ pEntry->meType ] = *pEntry;
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
+ const ScTokenArray& rScTokArr, const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ // initialize the compiler
+ Init( eType, rScTokArr, pScBasePos, pRefLog );
+
+ // start compilation, if initialization didn't fail
+ if( mxData->mbOk )
+ {
+ XclExpScToken aTokData( GetNextToken() );
+ sal_uInt16 nScError = rScTokArr.GetCodeError();
+ if( (nScError != 0) && (!aTokData.Is() || (aTokData.GetOpCode() == ocStop)) )
+ {
+ // #i50253# convert simple ocStop token to error code formula (e.g. =#VALUE!)
+ AppendErrorToken( XclTools::GetXclErrorCode( nScError ), aTokData.mnSpaces );
+ }
+ else if( aTokData.Is() )
+ {
+ aTokData = Expression( aTokData, false, false );
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpFmlaCompImpl::CreateFormula - empty token array" );
+ mxData->mbOk = false;
+ }
+
+ if( mxData->mbOk )
+ {
+ // #i44907# auto-generated SUBTOTAL formula cells have trailing ocStop token
+ mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
+ }
+ }
+
+ // finalize (add tAttrVolatile token, calculate all token classes)
+ RecalcTokenClasses();
+ FinalizeFormula();
+
+ // leave recursive call, create and return the final token array
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendErrorToken( nErrCode );
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendOperandTokenId( nTokenId );
+ Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
+ Append( rXclPos.mnCol ); // do not use AppendAddress(), we always need 16-bit column here
+ return CreateTokenArray();
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName )
+{
+ Init( EXC_FMLATYPE_NAME );
+ AppendNameXToken( nExtSheet, nExtName );
+ return CreateTokenArray();
+}
+
+bool XclExpFmlaCompImpl::Is3DRefOnly( XclFormulaType eType ) const
+{
+ const XclExpCompConfig* pCfg = GetConfigForType( eType );
+ return pCfg && pCfg->mb3DRefOnly;
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpCompConfig* XclExpFmlaCompImpl::GetConfigForType( XclFormulaType eType ) const
+{
+ XclExpCompConfigMap::const_iterator aIt = maCfgMap.find( eType );
+ DBG_ASSERT( aIt != maCfgMap.end(), "XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
+ return (aIt == maCfgMap.end()) ? 0 : &aIt->second;
+}
+
+void XclExpFmlaCompImpl::Init( XclFormulaType eType )
+{
+ // compiler invoked recursively? - store old working data
+ if( mxData.get() )
+ maDataStack.push_back( mxData );
+ // new compiler working data structure
+ mxData.reset( new XclExpCompData( GetConfigForType( eType ) ) );
+}
+
+void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ // common initialization
+ Init( eType );
+
+ // special initialization
+ if( mxData->mbOk ) switch( mxData->mrCfg.meType )
+ {
+ case EXC_FMLATYPE_CELL:
+ case EXC_FMLATYPE_MATRIX:
+ case EXC_FMLATYPE_CHART:
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ mxData->mpScBasePos = pScBasePos;
+ break;
+ case EXC_FMLATYPE_SHARED:
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ // clone the passed token array, convert references relative to current cell position
+ mxData->mxOwnScTokArr.reset( rScTokArr.Clone() );
+ ScCompiler::MoveRelWrap( *mxData->mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
+ // don't remember pScBasePos in mxData->mpScBasePos, shared formulas use real relative refs
+ break;
+ default:;
+ }
+
+ if( mxData->mbOk )
+ {
+ // link manager to be used
+ mxData->mpLinkMgr = mxData->mrCfg.mbLocalLinkMgr ? &GetLocalLinkManager() : &GetGlobalLinkManager();
+
+ // token array iterator (use cloned token array if present)
+ mxData->maTokArrIt.Init( mxData->mxOwnScTokArr ? *mxData->mxOwnScTokArr : rScTokArr, false );
+ mxData->mpRefLog = pRefLog;
+ }
+}
+
+void XclExpFmlaCompImpl::RecalcTokenClasses()
+{
+ if( mxData->mbOk )
+ {
+ mxData->mbOk = mxData->maOpPosStack.size() == 1;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
+ if( mxData->mbOk )
+ {
+ /* Cell and array formulas start with VAL conversion and VALTYPE
+ parameter type, defined names start with ARR conversion and
+ REFTYPE parameter type for the root token. */
+ XclExpOperandList aOperands;
+ bool bNameFmla = mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
+ XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL;
+ XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
+ XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla };
+ RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla );
+ }
+
+ // clear operand vectors (calls to the expensive InsertZeros() may follow)
+ mxData->maOpListVec.clear();
+ mxData->maOpPosStack.clear();
+ }
+}
+
+void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo,
+ XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass )
+{
+ DBG_ASSERT( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
+ sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ];
+ sal_uInt8 nTokClass = GetTokenClass( rnTokenId );
+
+ // REF tokens in VALTYPE parameters behave like VAL tokens
+ if( rConvInfo.mbValType && (nTokClass == EXC_TOKCLASS_REF) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
+
+ // replace RPO conversion of operator with parent conversion
+ XclFuncParamConv eConv = (rConvInfo.meConv == EXC_PARAMCONV_RPO) ? ePrevConv : rConvInfo.meConv;
+
+ // find the effective token class conversion to be performed for this token
+ XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
+ switch( eConv )
+ {
+ case EXC_PARAMCONV_ORG:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_VAL:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_VAL;
+ break;
+ case EXC_PARAMCONV_ARR:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ARR;
+ break;
+ case EXC_PARAMCONV_RPT:
+ switch( ePrevConv )
+ {
+ case EXC_PARAMCONV_ORG:
+ case EXC_PARAMCONV_VAL:
+ case EXC_PARAMCONV_ARR:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPT does not repeat the
+ previous explicit ORG or ARR conversion, but always
+ falls back to VAL conversion. */
+ eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPT:
+ // nested RPT repeats the previous effective conversion
+ eClassConv = ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPX repeats the previous
+ effective conversion (wich will be either ORG or ARR,
+ but never VAL), otherwise falls back to ORG conversion. */
+ eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur
+ break;
+ }
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If current token still has REF class, set previous effective
+ conversion as current conversion. This will not have an effect
+ on the REF token but is needed for RPT parameters of this
+ function that want to repeat this conversion type. If current
+ token is VAL or ARR class, the previous ARR conversion will be
+ repeated on the token, but VAL conversion will not. */
+ eClassConv = ((nTokClass == EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
+ ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur (see above)
+ break;
+ }
+
+ // do the token class conversion
+ switch( eClassConv )
+ {
+ case EXC_CLASSCONV_ORG:
+ /* Cell formulas: leave the current token class. Cell formulas
+ are the only type of formulas where all tokens can keep
+ their original token class.
+ Array and defined name formulas: convert VAL to ARR. */
+ if( (mxData->mrCfg.meClassType != EXC_CLASSTYPE_CELL) && (nTokClass == EXC_TOKCLASS_VAL) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ case EXC_CLASSCONV_VAL:
+ // convert ARR to VAL
+ if( nTokClass == EXC_TOKCLASS_ARR )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
+ break;
+ case EXC_CLASSCONV_ARR:
+ // convert VAL to ARR
+ if( nTokClass == EXC_TOKCLASS_VAL )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ }
+
+ // do conversion for nested operands, if token is an operator or function
+ if( rConvInfo.mnTokPos < mxData->maOpListVec.size() )
+ if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
+ for( XclExpOperandList::const_iterator aIt = pOperands->begin(), aEnd = pOperands->end(); aIt != aEnd; ++aIt )
+ RecalcTokenClass( *aIt, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF );
+}
+
+void XclExpFmlaCompImpl::FinalizeFormula()
+{
+ if( mxData->mbOk )
+ {
+ // Volatile? Add a tAttrVolatile token at the beginning of the token array.
+ if( mxData->mbVolatile )
+ {
+ // tAttrSpace token can be extended with volatile flag
+ if( !IsSpaceToken( 0 ) )
+ {
+ InsertZeros( 0, 4 );
+ mxData->maTokVec[ 0 ] = EXC_TOKID_ATTR;
+ }
+ mxData->maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
+ }
+
+ // Token array too long? -> error
+ mxData->mbOk = mxData->maTokVec.size() <= EXC_TOKARR_MAXLEN;
+ }
+
+ if( !mxData->mbOk )
+ {
+ // Any unrecoverable error? -> Create a =#NA formula.
+ mxData->maTokVec.clear();
+ mxData->maExtDataVec.clear();
+ mxData->mbVolatile = false;
+ AppendErrorToken( EXC_ERR_NA );
+ }
+}
+
+XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray()
+{
+ // create the Excel token array from working data before resetting mxData
+ DBG_ASSERT( mxData->mrCfg.mbAllowArrays || mxData->maExtDataVec.empty(), "XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
+ if( !mxData->mrCfg.mbAllowArrays )
+ mxData->maExtDataVec.clear();
+ XclTokenArrayRef xTokArr( new XclTokenArray( mxData->maTokVec, mxData->maExtDataVec, mxData->mbVolatile ) );
+ mxData.reset();
+
+ // compiler invoked recursively? - restore old working data
+ if( !maDataStack.empty() )
+ {
+ mxData = maDataStack.back();
+ maDataStack.pop_back();
+ }
+
+ return xTokArr;
+}
+
+// compiler -------------------------------------------------------------------
+
+const FormulaToken* XclExpFmlaCompImpl::GetNextRawToken()
+{
+ const FormulaToken* pScToken = mxData->maTokArrIt.Get();
+ ++mxData->maTokArrIt;
+ return pScToken;
+}
+
+const FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpaces ) const
+{
+ /* Returns pointer to next raw token in the token array. The token array
+ iterator already points to the next token (A call to GetNextToken()
+ always increases the iterator), so this function just returns the token
+ the iterator points to. To skip space tokens, a copy of the iterator is
+ created and set to the passed skip-spaces mode. If spaces have to be
+ skipped, and the iterator currently points to a space token, the
+ constructor will move it to the next non-space token. */
+ XclTokenArrayIterator aTempIt( mxData->maTokArrIt, bSkipSpaces );
+ return aTempIt.Get();
+}
+
+bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
+{
+ rTokData.mpScToken = GetNextRawToken();
+ rTokData.mnSpaces = (rTokData.GetOpCode() == ocSpaces) ? rTokData.mpScToken->GetByte() : 0;
+ while( rTokData.GetOpCode() == ocSpaces )
+ rTokData.mpScToken = GetNextRawToken();
+ return rTokData.Is();
+}
+
+XclExpScToken XclExpFmlaCompImpl::GetNextToken()
+{
+ XclExpScToken aTokData;
+ GetNextToken( aTokData );
+ return aTokData;
+}
+
+namespace {
+
+/** Returns the Excel token ID of a comparison operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetCompareTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocLess: return EXC_TOKID_LT;
+ case ocLessEqual: return EXC_TOKID_LE;
+ case ocEqual: return EXC_TOKID_EQ;
+ case ocGreaterEqual: return EXC_TOKID_GE;
+ case ocGreater: return EXC_TOKID_GT;
+ case ocNotEqual: return EXC_TOKID_NE;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a string concatenation operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetConcatTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocAmpersand) ? EXC_TOKID_CONCAT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of an addition/subtraction operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetAddSubTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocAdd: return EXC_TOKID_ADD;
+ case ocSub: return EXC_TOKID_SUB;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a multiplication/division operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetMulDivTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocMul: return EXC_TOKID_MUL;
+ case ocDiv: return EXC_TOKID_DIV;
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a power operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetPowTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocPow) ? EXC_TOKID_POWER : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a trailing unary operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetUnaryPostTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocPercentSign) ? EXC_TOKID_PERCENT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a leading unary operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetUnaryPreTokenId( OpCode eOpCode )
+{
+ switch( eOpCode )
+ {
+ case ocAdd: return EXC_TOKID_UPLUS; // +(1)
+ case ocNeg: return EXC_TOKID_UMINUS; // NEG(1)
+ case ocNegSub: return EXC_TOKID_UMINUS; // -(1)
+ default:;
+ }
+ return EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference list operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetListTokenId( OpCode eOpCode, bool bStopAtSep )
+{
+ return ((eOpCode == ocUnion) || (!bStopAtSep && (eOpCode == ocSep))) ? EXC_TOKID_LIST : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference intersection operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetIntersectTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocIntersect) ? EXC_TOKID_ISECT : EXC_TOKID_NONE;
+}
+
+/** Returns the Excel token ID of a reference range operator or EXC_TOKID_NONE. */
+inline sal_uInt8 lclGetRangeTokenId( OpCode eOpCode )
+{
+ return (eOpCode == ocRange) ? EXC_TOKID_RANGE : EXC_TOKID_NONE;
+}
+
+} // namespace
+
+XclExpScToken XclExpFmlaCompImpl::Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep )
+{
+ if( mxData->mbOk && aTokData.Is() )
+ {
+ // remember old stop-at-ocSep mode, restored below
+ bool bOldStopAtSep = mxData->mbStopAtSep;
+ mxData->mbStopAtSep = bStopAtSep;
+ // start compilation of the subexpression
+ aTokData = OrTerm( aTokData, bInParentheses );
+ // restore old stop-at-ocSep mode
+ mxData->mbStopAtSep = bOldStopAtSep;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::SkipExpression( XclExpScToken aTokData, bool bStopAtSep )
+{
+ while( mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
+ {
+ if( aTokData.GetOpCode() == ocOpen )
+ {
+ aTokData = SkipExpression( GetNextToken(), false );
+ if( mxData->mbOk ) mxData->mbOk = aTokData.GetOpCode() == ocClose;
+ }
+ aTokData = GetNextToken();
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::OrTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = AndTerm( aTokData, bInParentheses );
+ sal_uInt8 nParamCount = 1;
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocOr) )
+ {
+ RemoveTrailingParen();
+ aTokData = AndTerm( GetNextToken(), bInParentheses );
+ RemoveTrailingParen();
+ ++nParamCount;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ }
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_OR, nParamCount );
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::AndTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = CompareTerm( aTokData, bInParentheses );
+ sal_uInt8 nParamCount = 1;
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocAnd) )
+ {
+ RemoveTrailingParen();
+ aTokData = CompareTerm( GetNextToken(), bInParentheses );
+ RemoveTrailingParen();
+ ++nParamCount;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ }
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_AND, nParamCount );
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::CompareTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = ConcatTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = ConcatTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::ConcatTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = AddSubTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = AddSubTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::AddSubTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = MulDivTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = MulDivTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::MulDivTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = PowTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = PowTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::PowTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = UnaryPostTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = UnaryPostTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ aTokData = UnaryPreTerm( aTokData, bInParentheses );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ AppendUnaryOperatorToken( nOpTokenId, aTokData.mnSpaces );
+ GetNextToken( aTokData );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ sal_uInt8 nOpTokenId = mxData->mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
+ if( nOpTokenId != EXC_TOKID_NONE )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = UnaryPreTerm( GetNextToken(), bInParentheses );
+ AppendUnaryOperatorToken( nOpTokenId, nSpaces );
+ }
+ else
+ {
+ aTokData = ListTerm( aTokData, bInParentheses );
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::ListTerm( XclExpScToken aTokData, bool bInParentheses )
+{
+ sal_uInt16 nSubExprPos = GetSize();
+ bool bHasAnyRefOp = false;
+ bool bHasListOp = false;
+ aTokData = IntersectTerm( aTokData, bHasAnyRefOp );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mxData->mbStopAtSep )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = IntersectTerm( GetNextToken(), bHasAnyRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ bHasAnyRefOp = bHasListOp = true;
+ }
+ if( bHasAnyRefOp )
+ {
+ // add a tMemFunc token enclosing the entire reference subexpression
+ sal_uInt16 nSubExprSize = GetSize() - nSubExprPos;
+ InsertZeros( nSubExprPos, 3 );
+ mxData->maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
+ Overwrite( nSubExprPos + 1, nSubExprSize );
+ // update the operand/operator stack (set the list expression as operand of the tMemFunc)
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_VAL, false );
+ PushOperatorPos( nSubExprPos, xOperands );
+ }
+ // #i86439# enclose list operator into parentheses, e.g. Calc's =AREAS(A1~A2) to Excel's =AREAS((A1;A2))
+ if( bHasListOp && !bInParentheses )
+ AppendParenToken();
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp )
+{
+ aTokData = RangeTerm( aTokData, rbHasRefOp );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = RangeTerm( GetNextToken(), rbHasRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ rbHasRefOp = true;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp )
+{
+ aTokData = Factor( aTokData );
+ sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
+ while( mxData->mbOk && ((nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ {
+ sal_uInt8 nSpaces = aTokData.mnSpaces;
+ aTokData = Factor( GetNextToken() );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
+ rbHasRefOp = true;
+ }
+ return aTokData;
+}
+
+XclExpScToken XclExpFmlaCompImpl::Factor( XclExpScToken aTokData )
+{
+ if( !mxData->mbOk || !aTokData.Is() ) return XclExpScToken();
+
+ switch( aTokData.GetType() )
+ {
+ case svUnknown: mxData->mbOk = false; break;
+ case svDouble: ProcessDouble( aTokData ); break;
+ case svString: ProcessString( aTokData ); break;
+ case svSingleRef: ProcessCellRef( aTokData ); break;
+ case svDoubleRef: ProcessRangeRef( aTokData ); break;
+ case svExternalSingleRef: ProcessExternalCellRef( aTokData ); break;
+ case svExternalDoubleRef: ProcessExternalRangeRef( aTokData ); break;
+ case svExternalName: ProcessExternalName( aTokData ); break;
+ case svMatrix: ProcessMatrix( aTokData ); break;
+ case svExternal: ProcessExternal( aTokData ); break;
+
+ default: switch( aTokData.GetOpCode() )
+ {
+ case ocNone: /* do nothing */ break;
+ case ocMissing: ProcessMissing( aTokData ); break;
+ case ocBad: ProcessBad( aTokData ); break;
+ case ocOpen: ProcessParentheses( aTokData ); break;
+ case ocName: ProcessDefinedName( aTokData ); break;
+ case ocFalse:
+ case ocTrue: ProcessBoolean( aTokData ); break;
+ case ocDde: ProcessDdeLink( aTokData ); break;
+ default: ProcessFunction( aTokData );
+ }
+ }
+
+ return GetNextToken();
+}
+
+// formula structure ----------------------------------------------------------
+
+void XclExpFmlaCompImpl::ProcessDouble( const XclExpScToken& rTokData )
+{
+ double fValue = rTokData.mpScToken->GetDouble();
+ double fInt;
+ double fFrac = modf( fValue, &fInt );
+ if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
+ AppendIntToken( static_cast< sal_uInt16 >( fInt ), rTokData.mnSpaces );
+ else
+ AppendNumToken( fValue, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessString( const XclExpScToken& rTokData )
+{
+ AppendOperandTokenId( EXC_TOKID_STR, rTokData.mnSpaces );
+ Append( rTokData.mpScToken->GetString() );
+}
+
+void XclExpFmlaCompImpl::ProcessMissing( const XclExpScToken& rTokData )
+{
+ AppendMissingToken( rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessBad( const XclExpScToken& rTokData )
+{
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessParentheses( const XclExpScToken& rTokData )
+{
+ XclExpScToken aTokData = Expression( GetNextToken(), true, false );
+ mxData->mbOk = aTokData.GetOpCode() == ocClose;
+ AppendParenToken( rTokData.mnSpaces, aTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessBoolean( const XclExpScToken& rTokData )
+{
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk )
+ AppendBoolToken( rTokData.GetOpCode() == ocTrue, rTokData.mnSpaces );
+}
+
+namespace {
+
+inline bool lclGetTokenString( String& rString, const XclExpScToken& rTokData )
+{
+ bool bIsStr = (rTokData.GetType() == svString) && (rTokData.GetOpCode() == ocPush);
+ if( bIsStr )
+ rString = rTokData.mpScToken->GetString();
+ return bIsStr;
+}
+
+} // namespace
+
+void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpScToken& rTokData )
+{
+ String aApplic, aTopic, aItem;
+
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aApplic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aTopic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aItem, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk ) mxData->mbOk = aApplic.Len() && aTopic.Len() && aItem.Len();
+ if( mxData->mbOk )
+ {
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
+ else
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternal( const XclExpScToken& rTokData )
+{
+ /* #i47228# Excel import generates svExternal/ocMacro tokens for invalid
+ names and for external/invalid function calls. This function looks for
+ the next token in the token array. If it is an opening parenthesis, the
+ token is processed as external function call, otherwise as undefined name. */
+ const FormulaToken* pNextScToken = PeekNextRawToken( true );
+ if( !pNextScToken || (pNextScToken->GetOpCode() != ocOpen) )
+ AppendMissingNameToken( rTokData.mpScToken->GetExternal(), rTokData.mnSpaces );
+ else
+ ProcessFunction( rTokData );
+}
+
+void XclExpFmlaCompImpl::ProcessMatrix( const XclExpScToken& rTokData )
+{
+ const ScMatrix* pMatrix = static_cast< const ScToken* >( rTokData.mpScToken )->GetMatrix();
+ if( pMatrix && mxData->mrCfg.mbAllowArrays )
+ {
+ SCSIZE nScCols, nScRows;
+ pMatrix->GetDimensions( nScCols, nScRows );
+ DBG_ASSERT( (nScCols > 0) && (nScRows > 0), "XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
+ sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
+ sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
+
+ // create the tArray token
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ), rTokData.mnSpaces );
+ Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ Append( static_cast< sal_uInt32 >( 0 ) );
+
+ // create the extended data containing the array values
+ AppendExt( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ AppendExt( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ for( SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
+ {
+ for( SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
+ {
+ ScMatrixValue nMatVal = pMatrix->Get( nScCol, nScRow );
+ if( ScMatrix::IsValueType( nMatVal.nType ) ) // value, boolean, or error
+ {
+ if( ScMatrix::IsBooleanType( nMatVal.nType ) )
+ {
+ AppendExt( EXC_CACHEDVAL_BOOL );
+ AppendExt( static_cast< sal_uInt8 >( nMatVal.GetBoolean() ? 1 : 0 ) );
+ AppendExt( 0, 7 );
+ }
+ else if( sal_uInt16 nErr = nMatVal.GetError() )
+ {
+ AppendExt( EXC_CACHEDVAL_ERROR );
+ AppendExt( XclTools::GetXclErrorCode( nErr ) );
+ AppendExt( 0, 7 );
+ }
+ else
+ {
+ AppendExt( EXC_CACHEDVAL_DOUBLE );
+ AppendExt( nMatVal.fVal );
+ }
+ }
+ else // string or empty
+ {
+ const String& rStr = nMatVal.GetString();
+ if( rStr.Len() == 0 )
+ {
+ AppendExt( EXC_CACHEDVAL_EMPTY );
+ AppendExt( 0, 8 );
+ }
+ else
+ {
+ AppendExt( EXC_CACHEDVAL_STRING );
+ AppendExt( rStr );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // array in places that do not allow it (cond fmts, data validation)
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessFunction( const XclExpScToken& rTokData )
+{
+ OpCode eOpCode = rTokData.GetOpCode();
+ const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( eOpCode );
+
+ XclExpExtFuncData aExtFuncData;
+
+ // no exportable function found - try to create an external macro call
+ if( !pFuncInfo && (eOpCode >= SC_OPCODE_START_NO_PAR) )
+ {
+ const String& rFuncName = ScCompiler::GetNativeSymbol( eOpCode );
+ if( rFuncName.Len() )
+ {
+ aExtFuncData.Set( rFuncName, true, false );
+ pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( ocMacro );
+ }
+ }
+
+ mxData->mbOk = pFuncInfo != 0;
+ if( !mxData->mbOk ) return;
+
+ // functions simulated by a macro call in file format
+ if( pFuncInfo->IsMacroFunc() )
+ aExtFuncData.Set( pFuncInfo->GetMacroFuncName(), false, true );
+
+ XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData );
+ XclExpScToken aTokData;
+
+ // preparations for special functions, before function processing starts
+ PrepareFunction( aFuncData );
+
+ enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
+ eState = STATE_START;
+ while( eState != STATE_END ) switch( eState )
+ {
+ case STATE_START:
+ mxData->mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
+ eState = mxData->mbOk ? STATE_OPEN : STATE_END;
+ break;
+ case STATE_OPEN:
+ mxData->mbOk = GetNextToken( aTokData );
+ eState = mxData->mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
+ break;
+ case STATE_PARAM:
+ aTokData = ProcessParam( aTokData, aFuncData );
+ switch( aTokData.GetOpCode() )
+ {
+ case ocSep: eState = STATE_SEP; break;
+ case ocClose: eState = STATE_CLOSE; break;
+ default: mxData->mbOk = false;
+ }
+ if( !mxData->mbOk ) eState = STATE_END;
+ break;
+ case STATE_SEP:
+ mxData->mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
+ eState = mxData->mbOk ? STATE_PARAM : STATE_END;
+ break;
+ case STATE_CLOSE:
+ FinishFunction( aFuncData, aTokData.mnSpaces );
+ eState = STATE_END;
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::PrepareFunction( XclExpFuncData& rFuncData )
+{
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocCot: // simulate COT(x) by (1/TAN(x))
+ case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
+ AppendIntToken( 1 );
+ break;
+ case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
+ AppendNumToken( F_PI2 );
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces )
+{
+ // append missing parameters required in Excel, may modify param count
+ AppendTrailingParam( rFuncData );
+
+ // check if parameter count fits into the limits of the function
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
+ {
+ // first put the tAttrSpace tokens, they must not be included in tAttrGoto handling
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, rFuncData.GetSpaces() );
+
+ // add tAttrGoto tokens for IF or CHOOSE functions
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ case ocChose:
+ AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
+ break;
+ default:;
+ }
+
+ // put the tFunc or tFuncVar token (or another special token, e.g. tAttrSum)
+ AppendFuncToken( rFuncData );
+
+ // update volatile flag - is set if at least one used function is volatile
+ mxData->mbVolatile |= rFuncData.IsVolatile();
+
+ // update jump tokens for specific functions, add additional tokens
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ FinishIfFunction( rFuncData );
+ break;
+ case ocChose:
+ FinishChooseFunction( rFuncData );
+ break;
+
+ case ocCot: // simulate COT(x) by (1/TAN(x))
+ case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
+ AppendParenToken();
+ break;
+ case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
+ AppendBinaryOperatorToken( EXC_TOKID_SUB, true );
+ AppendParenToken();
+ break;
+
+ default:;
+ }
+ }
+ else
+ mxData->mbOk = false;
+}
+
+void XclExpFmlaCompImpl::FinishIfFunction( XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nParamCount = rFuncData.GetParamCount();
+ DBG_ASSERT( (nParamCount == 2) || (nParamCount == 3), "XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
+ const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
+ DBG_ASSERT( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
+ // update tAttrIf token following the condition parameter
+ Overwrite( rAttrPos[ 0 ] + 2, static_cast< sal_uInt16 >( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
+ // update the tAttrGoto tokens following true and false parameters
+ UpdateAttrGoto( rAttrPos[ 1 ] );
+ if( nParamCount == 3 )
+ UpdateAttrGoto( rAttrPos[ 2 ] );
+}
+
+void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nParamCount = rFuncData.GetParamCount();
+ ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
+ DBG_ASSERT( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
+ // number of choices is parameter count minus 1
+ sal_uInt16 nChoices = nParamCount - 1;
+ // tAttrChoose token contains number of choices
+ Overwrite( rAttrPos[ 0 ] + 2, nChoices );
+ // cache position of the jump table (follows number of choices in tAttrChoose token)
+ sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
+ // size of jump table: number of choices, plus 1 for error position
+ sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
+ // insert the jump table into the tAttrChoose token
+ InsertZeros( nJumpArrPos, nJumpArrSize );
+ // update positions of tAttrGoto tokens after jump table insertion
+ sal_uInt16 nIdx;
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
+ // update the tAttrGoto tokens (they contain a value one-less to real distance)
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ UpdateAttrGoto( rAttrPos[ nIdx ] );
+ // update the distances in the jump table
+ Overwrite( nJumpArrPos, nJumpArrSize );
+ for( nIdx = 1; nIdx < nParamCount; ++nIdx )
+ Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
+}
+
+XclExpScToken XclExpFmlaCompImpl::ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData )
+{
+ if( rFuncData.IsCalcOnlyParam() )
+ {
+ // skip Calc-only parameter, stop at next ocClose or ocSep
+ aTokData = SkipExpression( aTokData, true );
+ rFuncData.IncParamInfoIdx();
+ }
+ else
+ {
+ // insert Excel-only parameters, modifies param count and class in rFuncData
+ while( rFuncData.IsExcelOnlyParam() )
+ AppendDefaultParam( rFuncData );
+
+ // process the parameter, stop at next ocClose or ocSep
+ PrepareParam( rFuncData );
+ /* #i37355# insert tMissArg token for missing parameters --
+ Excel import filter adds ocMissing token (handled in Factor()),
+ but Calc itself does not do this if a new formula is entered. */
+ switch( aTokData.GetOpCode() )
+ {
+ case ocSep:
+ case ocClose: AppendMissingToken(); break; // empty parameter
+ default: aTokData = Expression( aTokData, false, true );
+ }
+ // finalize the parameter and add special tokens, e.g. for IF or CHOOSE parameters
+ if( mxData->mbOk ) FinishParam( rFuncData );
+ }
+ return aTokData;
+}
+
+void XclExpFmlaCompImpl::PrepareParam( XclExpFuncData& rFuncData )
+{
+ // index of this parameter is equal to number of already finished parameters
+ sal_uInt8 nParamIdx = rFuncData.GetParamCount();
+
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ switch( nParamIdx )
+ {
+ // add a tAttrIf token before true-parameter (second parameter)
+ case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_IF ); break;
+ // add a tAttrGoto token before false-parameter (third parameter)
+ case 2: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO ); break;
+ }
+ break;
+
+ case ocChose:
+ switch( nParamIdx )
+ {
+ // do nothing for first parameter
+ case 0: break;
+ // add a tAttrChoose token before first value parameter (second parameter)
+ case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_CHOOSE ); break;
+ // add a tAttrGoto token before other value parameters
+ default: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
+ }
+ break;
+
+ case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
+ if( nParamIdx == 0 )
+ AppendIntToken( 1 );
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::FinishParam( XclExpFuncData& rFuncData )
+{
+ // increase parameter count, update operand stack
+ rFuncData.FinishParam( PopOperandPos() );
+
+ // append more tokens for parameters of some special functions
+ sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
+ if( nParamIdx == 0 )
+ {
+ AppendParenToken();
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
+ }
+ break;
+ default:;
+ }
+}
+
+void XclExpFmlaCompImpl::AppendDefaultParam( XclExpFuncData& rFuncData )
+{
+ // prepare parameters of some special functions
+ PrepareParam( rFuncData );
+
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocExternal:
+ AppendAddInCallToken( rFuncData.GetExtFuncData() );
+ break;
+ case ocEuroConvert:
+ AppendEuroToolCallToken( rFuncData.GetExtFuncData() );
+ break;
+ case ocMacro:
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
+ break;
+ default:
+ {
+ DBG_ASSERT( rFuncData.IsMacroFunc(), "XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
+ if( rFuncData.IsMacroFunc() )
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
+ else
+ AppendMissingToken(); // to keep parameter count valid
+ }
+ }
+
+ // update parameter count, add special parameter tokens
+ FinishParam( rFuncData );
+}
+
+void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
+{
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ switch( rFuncData.GetOpCode() )
+ {
+ case ocIf:
+ if( nParamCount == 1 )
+ {
+ // Excel needs at least two parameters in IF function
+ PrepareParam( rFuncData );
+ AppendBoolToken( true );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocRound:
+ case ocRoundUp:
+ case ocRoundDown:
+ if( nParamCount == 1 )
+ {
+ // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 0 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocIndex:
+ if( nParamCount == 1 )
+ {
+ // INDEX function needs at least 2 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendMissingToken();
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocExternal:
+ case ocMacro:
+ // external or macro call without parameters needs the external name reference
+ if( nParamCount == 0 )
+ AppendDefaultParam( rFuncData );
+ break;
+
+ case ocGammaDist:
+ if( nParamCount == 3 )
+ {
+ // GAMMADIST function needs 4 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocPoissonDist:
+ if( nParamCount == 2 )
+ {
+ // POISSON function needs 3 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocNormDist:
+ if( nParamCount == 3 )
+ {
+ // NORMDIST function needs 4 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendBoolToken( true );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocLogNormDist:
+ switch( nParamCount )
+ {
+ // LOGNORMDIST function needs 3 parameters in Excel
+ case 1:
+ PrepareParam( rFuncData );
+ AppendIntToken( 0 );
+ FinishParam( rFuncData );
+ // do not break, add next default parameter
+ case 2:
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ break;
+ default:;
+ }
+
+ break;
+
+ default:
+ // #i108420# function without parameters stored as macro call needs the external name reference
+ if( (nParamCount == 0) && rFuncData.IsMacroFunc() )
+ AppendDefaultParam( rFuncData );
+
+ }
+}
+
+// reference handling ---------------------------------------------------------
+
+namespace {
+
+inline bool lclIsRefRel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColRel() || rRefData.IsRowRel();
+}
+
+inline bool lclIsRefDel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
+}
+
+inline bool lclIsRefRel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
+}
+
+inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
+}
+
+} // namespace
+
+SCTAB XclExpFmlaCompImpl::GetScTab( const ScSingleRefData& rRefData ) const
+{
+ bool bInvTab = rRefData.IsTabDeleted() || (!mxData->mpScBasePos && IsInGlobals() && rRefData.IsTabRel());
+ return bInvTab ? SCTAB_INVALID : static_cast< SCTAB >( rRefData.nTab );
+}
+
+bool XclExpFmlaCompImpl::IsRef2D( const ScSingleRefData& rRefData ) const
+{
+ /* rRefData.IsFlag3D() determines if sheet name is always visible, even on
+ the own sheet. If 3D references are allowed, the passed reference does
+ not count as 2D reference. */
+ return (!mxData->mpLinkMgr || !rRefData.IsFlag3D()) && !rRefData.IsTabDeleted() &&
+ (rRefData.IsTabRel() ? (rRefData.nRelTab == 0) : (static_cast< SCTAB >( rRefData.nTab ) == GetCurrScTab()));
+}
+
+bool XclExpFmlaCompImpl::IsRef2D( const ScComplexRefData& rRefData ) const
+{
+ return IsRef2D( rRefData.Ref1 ) && IsRef2D( rRefData.Ref2 );
+}
+
+void XclExpFmlaCompImpl::ConvertRefData(
+ ScSingleRefData& rRefData, XclAddress& rXclPos,
+ bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const
+{
+ if( mxData->mpScBasePos )
+ {
+ // *** reference position exists (cell, matrix) - convert to absolute ***
+ rRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+
+ // convert column index
+ SCsCOL& rnScCol = rRefData.nCol;
+ if( bTruncMaxCol && (rnScCol == mnMaxScCol) )
+ rnScCol = mnMaxAbsCol;
+ else if( (rnScCol < 0) || (rnScCol > mnMaxAbsCol) )
+ rRefData.SetColDeleted( sal_True );
+ rXclPos.mnCol = static_cast< sal_uInt16 >( rnScCol ) & mnMaxColMask;
+
+ // convert row index
+ SCsROW& rnScRow = rRefData.nRow;
+ if( bTruncMaxRow && (rnScRow == mnMaxScRow) )
+ rnScRow = mnMaxAbsRow;
+ else if( (rnScRow < 0) || (rnScRow > mnMaxAbsRow) )
+ rRefData.SetRowDeleted( sal_True );
+ rXclPos.mnRow = static_cast< sal_uInt32 >( rnScRow ) & mnMaxRowMask;
+ }
+ else
+ {
+ // *** no reference position (shared, names, condfmt) - use relative values ***
+
+ // convert column index (2-step-cast ScsCOL->sal_Int16->sal_uInt16 to get all bits correctly)
+ sal_Int16 nXclRelCol = static_cast< sal_Int16 >( rRefData.IsColRel() ? rRefData.nRelCol : rRefData.nCol );
+ rXclPos.mnCol = static_cast< sal_uInt16 >( nXclRelCol ) & mnMaxColMask;
+
+ // convert row index (2-step-cast ScsROW->sal_Int16->sal_uInt16 to get all bits correctly)
+ sal_Int16 nXclRelRow = static_cast< sal_Int32 >( rRefData.IsRowRel() ? rRefData.nRelRow : rRefData.nRow );
+ rXclPos.mnRow = static_cast< sal_uInt32 >( nXclRelRow ) & mnMaxRowMask;
+
+ // resolve relative tab index if possible
+ if( rRefData.IsTabRel() && !IsInGlobals() && (GetCurrScTab() < GetDoc().GetTableCount()) )
+ rRefData.nTab = static_cast< SCsTAB >( GetCurrScTab() + rRefData.nRelTab );
+ }
+
+ // flags for relative column and row
+ if( bNatLangRef )
+ {
+ DBG_ASSERT( meBiff == EXC_BIFF8, "XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
+ // Calc does not support absolute reference mode in natural language references
+ ::set_flag( rXclPos.mnCol, EXC_TOK_NLR_REL );
+ }
+ else
+ {
+ sal_uInt16 rnRelRow = rXclPos.mnRow;
+ sal_uInt16& rnRelField = (meBiff <= EXC_BIFF5) ? rnRelRow : rXclPos.mnCol;
+ ::set_flag( rnRelField, EXC_TOK_REF_COLREL, rRefData.IsColRel() );
+ ::set_flag( rnRelField, EXC_TOK_REF_ROWREL, rRefData.IsRowRel() );
+ }
+}
+
+void XclExpFmlaCompImpl::ConvertRefData(
+ ScComplexRefData& rRefData, XclRange& rXclRange, bool bNatLangRef ) const
+{
+ // convert start and end of the range
+ ConvertRefData( rRefData.Ref1, rXclRange.maFirst, bNatLangRef, false, false );
+ bool bTruncMaxCol = !rRefData.Ref1.IsColDeleted() && (rRefData.Ref1.nCol == 0);
+ bool bTruncMaxRow = !rRefData.Ref1.IsRowDeleted() && (rRefData.Ref1.nRow == 0);
+ ConvertRefData( rRefData.Ref2, rXclRange.maLast, bNatLangRef, bTruncMaxCol, bTruncMaxRow );
+}
+
+XclExpRefLogEntry* XclExpFmlaCompImpl::GetNewRefLogEntry()
+{
+ if( mxData->mpRefLog )
+ {
+ mxData->mpRefLog->resize( mxData->mpRefLog->size() + 1 );
+ return &mxData->mpRefLog->back();
+ }
+ return 0;
+}
+
+void XclExpFmlaCompImpl::ProcessCellRef( const XclExpScToken& rTokData )
+{
+ // get the Excel address components, adjust internal data in aRefData
+ bool bNatLangRef = (meBiff == EXC_BIFF8) && mxData->mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclPos, bNatLangRef, false, false );
+
+ if( bNatLangRef )
+ {
+ DBG_ASSERT( aRefData.IsColRel() != aRefData.IsRowRel(),
+ "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
+ // create tNlr token for natural language reference
+ sal_uInt8 nSubId = aRefData.IsColRel() ? EXC_TOK_NLR_COLV : EXC_TOK_NLR_ROWV;
+ AppendOperandTokenId( EXC_TOKID_NLR, rTokData.mnSpaces );
+ Append( nSubId );
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ // store external cell contents in CRN records
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( aRefData );
+
+ // create the tRef, tRefErr, tRefN, tRef3d, or tRefErr3d token
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ {
+ // 2D reference (not in defined names, but allowed in range lists)
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
+ (lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR : EXC_TOKID_REF);
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ AppendAddress( aXclPos );
+ }
+ else if( mxData->mpLinkMgr ) // 3D reference
+ {
+ // 1-based EXTERNSHEET index and 0-based Excel sheet index
+ sal_uInt16 nExtSheet, nXclTab;
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nXclTab );
+ Append( nXclTab );
+ }
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ // 3D ref in cond. format, or 2D ref in name
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpScToken& rTokData )
+{
+ // get the Excel address components, adjust internal data in aRefData
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclRange, false );
+
+ // store external cell contents in CRN records
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( aRefData );
+
+ // create the tArea, tAreaErr, tAreaN, tArea3d, or tAreaErr3d token
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ {
+ // 2D reference (not in name formulas, but allowed in range lists)
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
+ (lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR : EXC_TOKID_AREA);
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ AppendRange( aXclRange );
+ }
+ else if( mxData->mpLinkMgr ) // 3D reference
+ {
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
+ GetScTab( aRefData.Ref1 ), GetScTab( aRefData.Ref2 ), GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstXclTab );
+ Append( nLastXclTab );
+ }
+ AppendRange( aXclRange );
+ }
+ else
+ {
+ // 3D ref in cond. format, or 2D ref in name
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternalCellRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclPos, false, false, false );
+
+ // store external cell contents in CRN records
+ sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclRange, false );
+
+ // store external cell contents in CRN records
+ sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ sal_uInt16 nTabSpan = static_cast< sal_uInt16 >( aRefData.Ref2.nTab - aRefData.Ref1.nTab + 1 );
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendRange( aXclRange );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
+{
+ SCTAB nTab = SCTAB_GLOBAL;
+ bool bGlobal = static_cast<bool>(rTokData.mpScToken->GetByte());
+ if (!bGlobal && mxData->mpScBasePos)
+ nTab = mxData->mpScBasePos->Tab();
+
+ XclExpNameManager& rNameMgr = GetNameManager();
+ sal_uInt16 nNameIdx = rNameMgr.InsertName(nTab, rTokData.mpScToken->GetIndex());
+ if( nNameIdx != 0 )
+ {
+ // global names always with tName token, local names dependent on config
+ SCTAB nScTab = rNameMgr.GetScTab( nNameIdx );
+ if( (nScTab == SCTAB_GLOBAL) || (!mxData->mrCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
+ {
+ AppendNameToken( nNameIdx, rTokData.mnSpaces );
+ }
+ else if( mxData->mpLinkMgr )
+ {
+ // use the same special EXTERNNAME to refer to any local name
+ sal_uInt16 nExtSheet = mxData->mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
+ AppendNameXToken( nExtSheet, nNameIdx, rTokData.mnSpaces );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+ // volatile names (containing volatile functions)
+ mxData->mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+}
+
+void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ ScExternalRefManager& rExtRefMgr = *GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
+ const String& rName = rTokData.mpScToken->GetString();
+ ScExternalRefCache::TokenArrayRef xArray = rExtRefMgr.getRangeNameTokens( nFileId, rName );
+ if( xArray.get() )
+ {
+ // store external cell contents in CRN records
+ if( mxData->mpScBasePos )
+ {
+ for( FormulaToken* pScToken = xArray->First(); pScToken; pScToken = xArray->Next() )
+ {
+ if( pScToken->IsExternalRef() )
+ {
+ switch( pScToken->GetType() )
+ {
+ case svExternalSingleRef:
+ {
+ ScSingleRefData aRefData = static_cast< ScToken* >( pScToken )->GetSingleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCell( nFileId, pScToken->GetString(), aRefData );
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ ScComplexRefData aRefData = static_cast< ScToken* >( pScToken )->GetDoubleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCellRange( nFileId, pScToken->GetString(), aRefData );
+ }
+ default:
+ ; // nothing, avoid compiler warning
+ }
+ }
+ }
+ }
+
+ // insert the new external name and create the tNameX token
+ sal_uInt16 nExtSheet, nExtName;
+ const String* pFile = rExtRefMgr.getExternalFileName( nFileId );
+ if( pFile && mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, rName, xArray ) )
+ {
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
+ return;
+ }
+ }
+ }
+
+ // on any error: create a #NAME? error
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
+}
+
+// token vector ---------------------------------------------------------------
+
+void XclExpFmlaCompImpl::PushOperandPos( sal_uInt16 nTokPos )
+{
+ mxData->maOpPosStack.push_back( nTokPos );
+}
+
+void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands )
+{
+ PushOperandPos( nTokPos );
+ DBG_ASSERT( rxOperands.get(), "XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
+ if( mxData->maOpListVec.size() <= nTokPos )
+ mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
+ mxData->maOpListVec[ nTokPos ] = rxOperands;
+}
+
+sal_uInt16 XclExpFmlaCompImpl::PopOperandPos()
+{
+ DBG_ASSERT( !mxData->mbOk || !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
+ mxData->mbOk &= !mxData->maOpPosStack.empty();
+ if( mxData->mbOk )
+ {
+ sal_uInt16 nTokPos = mxData->maOpPosStack.back();
+ mxData->maOpPosStack.pop_back();
+ return nTokPos;
+ }
+ return 0;
+}
+
+namespace {
+
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt16 nData )
+{
+ orVector.resize( orVector.size() + 2 );
+ ShortToSVBT16( nData, &*(orVector.end() - 2) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt32 nData )
+{
+ orVector.resize( orVector.size() + 4 );
+ UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, double fData )
+{
+ orVector.resize( orVector.size() + 8 );
+ DoubleToSVBT64( fData, &*(orVector.end() - 8) );
+}
+
+inline void lclAppend( ScfUInt8Vec& orVector, const XclExpRoot& rRoot, const String& rString, XclStrFlags nStrFlags )
+{
+ XclExpStringRef xXclStr = XclExpStringHelper::CreateString( rRoot, rString, nStrFlags, EXC_TOK_STR_MAXLEN );
+ size_t nSize = orVector.size();
+ orVector.resize( nSize + xXclStr->GetSize() );
+ xXclStr->WriteToMem( &orVector[ nSize ] );
+}
+
+} // namespace
+
+void XclExpFmlaCompImpl::Append( sal_uInt8 nData )
+{
+ mxData->maTokVec.push_back( nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt8 nData, size_t nCount )
+{
+ mxData->maTokVec.resize( mxData->maTokVec.size() + nCount, nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt16 nData )
+{
+ lclAppend( mxData->maTokVec, nData );
+}
+
+void XclExpFmlaCompImpl::Append( sal_uInt32 nData )
+{
+ lclAppend( mxData->maTokVec, nData );
+}
+
+void XclExpFmlaCompImpl::Append( double fData )
+{
+ lclAppend( mxData->maTokVec, fData );
+}
+
+void XclExpFmlaCompImpl::Append( const String& rString )
+{
+ lclAppend( mxData->maTokVec, GetRoot(), rString, EXC_STR_8BITLENGTH );
+}
+
+void XclExpFmlaCompImpl::AppendAddress( const XclAddress& rXclPos )
+{
+ Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
+ if( meBiff <= EXC_BIFF5 )
+ Append( static_cast< sal_uInt8 >( rXclPos.mnCol ) );
+ else
+ Append( rXclPos.mnCol );
+}
+
+void XclExpFmlaCompImpl::AppendRange( const XclRange& rXclRange )
+{
+ Append( static_cast<sal_uInt16>(rXclRange.maFirst.mnRow) );
+ Append( static_cast<sal_uInt16>(rXclRange.maLast.mnRow) );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( static_cast< sal_uInt8 >( rXclRange.maFirst.mnCol ) );
+ Append( static_cast< sal_uInt8 >( rXclRange.maLast.mnCol ) );
+ }
+ else
+ {
+ Append( rXclRange.maFirst.mnCol );
+ Append( rXclRange.maLast.mnCol );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
+{
+ if( nCount > 0 )
+ {
+ Append( EXC_TOKID_ATTR );
+ Append( EXC_TOK_ATTR_SPACE );
+ Append( nType );
+ Append( nCount );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperandPos( GetSize() );
+ Append( nTokenId );
+}
+
+void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_INT, nSpaces );
+ Append( nValue );
+}
+
+void XclExpFmlaCompImpl::AppendNumToken( double fValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_NUM, nSpaces );
+ Append( fValue );
+}
+
+void XclExpFmlaCompImpl::AppendBoolToken( bool bValue, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_BOOL, nSpaces );
+ Append( bValue ? EXC_TOK_BOOL_TRUE : EXC_TOK_BOOL_FALSE );
+}
+
+void XclExpFmlaCompImpl::AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_ERR, nSpaces );
+ Append( nErrCode );
+}
+
+void XclExpFmlaCompImpl::AppendMissingToken( sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( EXC_TOKID_MISSARG, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces )
+{
+ if( nNameIdx > 0 )
+ {
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAME, EXC_TOKCLASS_REF ), nSpaces );
+ Append( nNameIdx );
+ Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
+ }
+ else
+ AppendErrorToken( EXC_ERR_NAME );
+}
+
+void XclExpFmlaCompImpl::AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nNameIdx = GetNameManager().InsertRawName( rName );
+ AppendNameToken( nNameIdx, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces )
+{
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), nSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ Append( 0, 8 );
+ Append( nExtName );
+ Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
+}
+
+void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rExtFuncData.maFuncName, rExtFuncData.mbVBasic, true, rExtFuncData.mbHidden );
+ AppendNameToken( nNameIdx, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ String aXclFuncName;
+ if( mxData->mpLinkMgr && ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
+ {
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
+ {
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
+ return;
+ }
+ }
+ AppendMacroCallToken( rExtFuncData, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
+{
+ sal_uInt16 nExtSheet, nExtName;
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
+ else
+ AppendMacroCallToken( rExtFuncData, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperatorPos( GetSize(), rxOperands );
+ Append( nTokenId );
+}
+
+void XclExpFmlaCompImpl::AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, true );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ for( sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPX, false );
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, EXC_TOKCLASS_VAL ), xOperands );
+ Append( nOpCount );
+ Append( nXclFuncIdx );
+}
+
+void XclExpFmlaCompImpl::AppendFuncToken( const XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ sal_uInt8 nRetClass = rFuncData.GetReturnClass();
+
+ if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
+ {
+ // SUM with only one parameter
+ AppendOperatorTokenId( EXC_TOKID_ATTR, rFuncData.GetOperandList() );
+ Append( EXC_TOK_ATTR_SUM );
+ Append( sal_uInt16( 0 ) );
+ }
+ else if( rFuncData.IsFixedParamCount() )
+ {
+ // fixed number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), rFuncData.GetOperandList() );
+ Append( nXclFuncIdx );
+ }
+ else
+ {
+ // variable number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), rFuncData.GetOperandList() );
+ Append( nParamCount );
+ Append( nXclFuncIdx );
+ }
+}
+
+void XclExpFmlaCompImpl::AppendParenToken( sal_uInt8 nOpenSpaces, sal_uInt8 nCloseSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_OPEN, nOpenSpaces );
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
+ Append( EXC_TOKID_PAREN );
+}
+
+void XclExpFmlaCompImpl::AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType )
+{
+ // store the start position of the token
+ rFuncData.AppendAttrPos( GetSize() );
+ // create the tAttr token
+ Append( EXC_TOKID_ATTR );
+ Append( nAttrType );
+ Append( sal_uInt16( 0 ) ); // placeholder that will be updated later
+}
+
+void XclExpFmlaCompImpl::InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
+{
+ // insert zeros into the token array
+ DBG_ASSERT( nInsertPos < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
+ mxData->maTokVec.insert( mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
+
+ // update positions of operands waiting for an operator
+ for( ScfUInt16Vec::iterator aIt = mxData->maOpPosStack.begin(), aEnd = mxData->maOpPosStack.end(); aIt != aEnd; ++aIt )
+ if( nInsertPos <= *aIt )
+ *aIt = *aIt + nInsertSize;
+
+ // update operand lists of all operator tokens
+ if( nInsertPos < mxData->maOpListVec.size() )
+ mxData->maOpListVec.insert( mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
+ for( XclExpOperandListVector::iterator aIt = mxData->maOpListVec.begin(), aEnd = mxData->maOpListVec.end(); aIt != aEnd; ++aIt )
+ if( aIt->get() )
+ for( XclExpOperandList::iterator aIt2 = (*aIt)->begin(), aEnd2 = (*aIt)->end(); aIt2 != aEnd2; ++aIt2 )
+ if( nInsertPos <= aIt2->mnTokPos )
+ aIt2->mnTokPos = aIt2->mnTokPos + nInsertSize;
+}
+
+void XclExpFmlaCompImpl::Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset )
+{
+ DBG_ASSERT( static_cast< size_t >( nWriteToPos + 1 ) < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
+ ShortToSVBT16( nOffset, &mxData->maTokVec[ nWriteToPos ] );
+}
+
+void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
+{
+ /* tAttrGoto contains distance from end of tAttr token to position behind
+ the function token (for IF or CHOOSE function), which is currently at
+ the end of the token array. Additionally this distance is decreased by
+ one, for whatever reason. So we have to subtract 4 and 1 from the
+ distance between the tAttr token start and the end of the token array. */
+ Overwrite( nAttrPos + 2, static_cast< sal_uInt16 >( GetSize() - nAttrPos - 5 ) );
+}
+
+bool XclExpFmlaCompImpl::IsSpaceToken( sal_uInt16 nPos ) const
+{
+ return
+ (static_cast< size_t >( nPos + 4 ) <= mxData->maTokVec.size()) &&
+ (mxData->maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
+ (mxData->maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
+}
+
+void XclExpFmlaCompImpl::RemoveTrailingParen()
+{
+ // remove trailing tParen token
+ if( !mxData->maTokVec.empty() && (mxData->maTokVec.back() == EXC_TOKID_PAREN) )
+ mxData->maTokVec.pop_back();
+ // remove remaining tAttrSpace tokens
+ while( (mxData->maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
+ mxData->maTokVec.erase( mxData->maTokVec.end() - 4, mxData->maTokVec.end() );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData )
+{
+ mxData->maExtDataVec.push_back( nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData, size_t nCount )
+{
+ mxData->maExtDataVec.resize( mxData->maExtDataVec.size() + nCount, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt16 nData )
+{
+ lclAppend( mxData->maExtDataVec, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( double fData )
+{
+ lclAppend( mxData->maExtDataVec, fData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( const String& rString )
+{
+ lclAppend( mxData->maExtDataVec, GetRoot(), rString, (meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH );
+}
+
+// ============================================================================
+
+namespace {
+
+void lclInitOwnTab( ScSingleRefData& rRef, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ if( b3DRefOnly )
+ {
+ // no reduction to 2D reference, if global link manager is used
+ rRef.SetFlag3D( sal_True );
+ }
+ else if( rScPos.Tab() == nCurrScTab )
+ {
+ rRef.SetTabRel( sal_True );
+ rRef.nRelTab = 0;
+ }
+}
+
+void lclPutCellToTokenArray( ScTokenArray& rScTokArr, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ ScSingleRefData aRef;
+ aRef.InitAddress( rScPos );
+ lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
+ rScTokArr.AddSingleReference( aRef );
+}
+
+void lclPutRangeToTokenArray( ScTokenArray& rScTokArr, const ScRange& rScRange, SCTAB nCurrScTab, bool b3DRefOnly )
+{
+ if( rScRange.aStart == rScRange.aEnd )
+ {
+ lclPutCellToTokenArray( rScTokArr, rScRange.aStart, nCurrScTab, b3DRefOnly );
+ }
+ else
+ {
+ ScComplexRefData aRef;
+ aRef.InitRange( rScRange );
+ lclInitOwnTab( aRef.Ref1, rScRange.aStart, nCurrScTab, b3DRefOnly );
+ lclInitOwnTab( aRef.Ref2, rScRange.aEnd, nCurrScTab, b3DRefOnly );
+ rScTokArr.AddDoubleReference( aRef );
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpFormulaCompiler::XclExpFormulaCompiler( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpFmlaCompImpl( rRoot ) )
+{
+}
+
+XclExpFormulaCompiler::~XclExpFormulaCompiler()
+{
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
+{
+ return mxImpl->CreateFormula( eType, rScTokArr, pScBasePos, pRefLog );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScAddress& rScPos )
+{
+ ScTokenArray aScTokArr;
+ lclPutCellToTokenArray( aScTokArr, rScPos, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRange& rScRange )
+{
+ ScTokenArray aScTokArr;
+ lclPutRangeToTokenArray( aScTokArr, rScRange, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateFormula( XclFormulaType eType, const ScRangeList& rScRanges )
+{
+ size_t nCount = rScRanges.size();
+ if( nCount == 0 )
+ return XclTokenArrayRef();
+
+ ScTokenArray aScTokArr;
+ SCTAB nCurrScTab = GetCurrScTab();
+ bool b3DRefOnly = mxImpl->Is3DRefOnly( eType );
+ for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ if( nIdx > 0 )
+ aScTokArr.AddOpCode( ocUnion );
+ lclPutRangeToTokenArray( aScTokArr, *rScRanges[ nIdx ], nCurrScTab, b3DRefOnly );
+ }
+ return mxImpl->CreateFormula( eType, aScTokArr );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateErrorFormula( sal_uInt8 nErrCode )
+{
+ return mxImpl->CreateErrorFormula( nErrCode );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateSpecialRefFormula(
+ sal_uInt8 nTokenId, const XclAddress& rXclPos )
+{
+ return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
+}
+
+XclTokenArrayRef XclExpFormulaCompiler::CreateNameXFormula(
+ sal_uInt16 nExtSheet, sal_uInt16 nExtName )
+{
+ return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xehelper.cxx b/sc/source/filter/excel/xehelper.cxx
new file mode 100644
index 000000000000..77b81686432f
--- /dev/null
+++ b/sc/source/filter/excel/xehelper.cxx
@@ -0,0 +1,1127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <sfx2/objsh.hxx>
+#include <vcl/font.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/itemset.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/outlobj.hxx>
+#include "scitems.hxx"
+#include <editeng/fhgtitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/svxfont.hxx>
+
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "cell.hxx"
+#include "editutil.hxx"
+#include "patattr.hxx"
+#include "xestyle.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xecontent.hxx"
+#include "xelink.hxx"
+#include "xehelper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::i18n::XBreakIterator;
+
+// Export progress bar ========================================================
+
+XclExpProgressBar::XclExpProgressBar( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxProgress( new ScfProgressBar( rRoot.GetDocShell(), STR_SAVE_DOC ) ),
+ mpSubProgress( 0 ),
+ mpSubRowCreate( 0 ),
+ mpSubRowFinal( 0 ),
+ mnSegRowFinal( SCF_INV_SEGMENT ),
+ mnRowCount( 0 )
+{
+}
+
+XclExpProgressBar::~XclExpProgressBar()
+{
+}
+
+void XclExpProgressBar::Initialize()
+{
+ const ScDocument& rDoc = GetDoc();
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ SCTAB nScTabCount = rTabInfo.GetScTabCount();
+
+ // *** segment: creation of ROW records *** -------------------------------
+
+ sal_Int32 nSegRowCreate = mxProgress->AddSegment( 2000 );
+ mpSubRowCreate = &mxProgress->GetSegmentProgressBar( nSegRowCreate );
+ maSubSegRowCreate.resize( nScTabCount, SCF_INV_SEGMENT );
+
+ for( SCTAB nScTab = 0; nScTab < nScTabCount; ++nScTab )
+ {
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ SCCOL nLastUsedScCol;
+ SCROW nLastUsedScRow;
+ rDoc.GetTableArea( nScTab, nLastUsedScCol, nLastUsedScRow );
+ sal_Size nSegSize = static_cast< sal_Size >( nLastUsedScRow + 1 );
+ maSubSegRowCreate[ nScTab ] = mpSubRowCreate->AddSegment( nSegSize );
+ }
+ }
+
+ // *** segment: writing all ROW records *** -------------------------------
+
+ mnSegRowFinal = mxProgress->AddSegment( 1000 );
+ // sub progress bar and segment are created later in ActivateFinalRowsSegment()
+}
+
+void XclExpProgressBar::IncRowRecordCount()
+{
+ ++mnRowCount;
+}
+
+void XclExpProgressBar::ActivateCreateRowsSegment()
+{
+ DBG_ASSERT( (0 <= GetCurrScTab()) && (GetCurrScTab() < GetTabInfo().GetScTabCount()),
+ "XclExpProgressBar::ActivateCreateRowsSegment - invalid sheet" );
+ sal_Int32 nSeg = maSubSegRowCreate[ GetCurrScTab() ];
+ DBG_ASSERT( nSeg != SCF_INV_SEGMENT, "XclExpProgressBar::ActivateCreateRowsSegment - invalid segment" );
+ if( nSeg != SCF_INV_SEGMENT )
+ {
+ mpSubProgress = mpSubRowCreate;
+ mpSubProgress->ActivateSegment( nSeg );
+ }
+ else
+ mpSubProgress = 0;
+}
+
+void XclExpProgressBar::ActivateFinalRowsSegment()
+{
+ if( !mpSubRowFinal && (mnRowCount > 0) )
+ {
+ mpSubRowFinal = &mxProgress->GetSegmentProgressBar( mnSegRowFinal );
+ mpSubRowFinal->AddSegment( mnRowCount );
+ }
+ mpSubProgress = mpSubRowFinal;
+ if( mpSubProgress )
+ mpSubProgress->Activate();
+}
+
+void XclExpProgressBar::Progress()
+{
+ if( mpSubProgress && !mpSubProgress->IsFull() )
+ mpSubProgress->Progress();
+}
+
+// Calc->Excel cell address/range conversion ==================================
+
+namespace {
+
+/** Fills the passed Excel address with the passed Calc cell coordinates without checking any limits. */
+inline void lclFillAddress( XclAddress& rXclPos, SCCOL nScCol, SCROW nScRow )
+{
+ rXclPos.mnCol = static_cast< sal_uInt16 >( nScCol );
+ rXclPos.mnRow = static_cast< sal_uInt32 >( nScRow );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpAddressConverter::XclExpAddressConverter( const XclExpRoot& rRoot ) :
+ XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetXclMaxPos() )
+{
+}
+
+// cell address ---------------------------------------------------------------
+
+bool XclExpAddressConverter::CheckAddress( const ScAddress& rScPos, bool bWarn )
+{
+ // ScAddress::operator<=() doesn't do what we want here
+ bool bValidCol = (0 <= rScPos.Col()) && (rScPos.Col() <= maMaxPos.Col());
+ bool bValidRow = (0 <= rScPos.Row()) && (rScPos.Row() <= maMaxPos.Row());
+ bool bValidTab = (0 <= rScPos.Tab()) && (rScPos.Tab() <= maMaxPos.Tab());
+
+ bool bValid = bValidCol && bValidRow && bValidTab;
+ if( !bValid && bWarn )
+ {
+ mbColTrunc |= !bValidCol;
+ mbRowTrunc |= !bValidRow;
+ mbTabTrunc |= (rScPos.Tab() > maMaxPos.Tab()); // do not warn for deleted refs
+ mrTracer.TraceInvalidAddress( rScPos, maMaxPos );
+ }
+ return bValid;
+}
+
+bool XclExpAddressConverter::ConvertAddress( XclAddress& rXclPos,
+ const ScAddress& rScPos, bool bWarn )
+{
+ bool bValid = CheckAddress( rScPos, bWarn );
+ if( bValid )
+ lclFillAddress( rXclPos, rScPos.Col(), rScPos.Row() );
+ return bValid;
+}
+
+XclAddress XclExpAddressConverter::CreateValidAddress( const ScAddress& rScPos, bool bWarn )
+{
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ if( !ConvertAddress( aXclPos, rScPos, bWarn ) )
+ lclFillAddress( aXclPos, ::std::min( rScPos.Col(), maMaxPos.Col() ), ::std::min( rScPos.Row(), maMaxPos.Row() ) );
+ return aXclPos;
+}
+
+// cell range -----------------------------------------------------------------
+
+bool XclExpAddressConverter::CheckRange( const ScRange& rScRange, bool bWarn )
+{
+ return CheckAddress( rScRange.aStart, bWarn ) && CheckAddress( rScRange.aEnd, bWarn );
+}
+
+bool XclExpAddressConverter::ValidateRange( ScRange& rScRange, bool bWarn )
+{
+ rScRange.Justify();
+
+ // check start position
+ bool bValidStart = CheckAddress( rScRange.aStart, bWarn );
+ if( bValidStart )
+ {
+ // check & correct end position
+ ScAddress& rScEnd = rScRange.aEnd;
+ if( !CheckAddress( rScEnd, bWarn ) )
+ {
+ rScEnd.SetCol( ::std::min( rScEnd.Col(), maMaxPos.Col() ) );
+ rScEnd.SetRow( ::std::min( rScEnd.Row(), maMaxPos.Row() ) );
+ rScEnd.SetTab( ::std::min( rScEnd.Tab(), maMaxPos.Tab() ) );
+ }
+ }
+
+ return bValidStart;
+}
+
+bool XclExpAddressConverter::ConvertRange( XclRange& rXclRange,
+ const ScRange& rScRange, bool bWarn )
+{
+ // check start position
+ bool bValidStart = CheckAddress( rScRange.aStart, bWarn );
+ if( bValidStart )
+ {
+ lclFillAddress( rXclRange.maFirst, rScRange.aStart.Col(), rScRange.aStart.Row() );
+
+ // check & correct end position
+ SCCOL nScCol2 = rScRange.aEnd.Col();
+ SCROW nScRow2 = rScRange.aEnd.Row();
+ if( !CheckAddress( rScRange.aEnd, bWarn ) )
+ {
+ nScCol2 = ::std::min( nScCol2, maMaxPos.Col() );
+ nScRow2 = ::std::min( nScRow2, maMaxPos.Row() );
+ }
+ lclFillAddress( rXclRange.maLast, nScCol2, nScRow2 );
+ }
+ return bValidStart;
+}
+
+// cell range list ------------------------------------------------------------
+
+void XclExpAddressConverter::ValidateRangeList( ScRangeList& rScRanges, bool bWarn )
+{
+ for ( size_t nRange = rScRanges.size(); nRange > 0; )
+ {
+ ScRange* pScRange = rScRanges[ --nRange ];
+ if( !CheckRange( *pScRange, bWarn ) )
+ delete rScRanges.Remove(nRange);
+ }
+}
+
+void XclExpAddressConverter::ConvertRangeList( XclRangeList& rXclRanges,
+ const ScRangeList& rScRanges, bool bWarn )
+{
+ rXclRanges.clear();
+ for( size_t nPos = 0, nCount = rScRanges.size(); nPos < nCount; ++nPos )
+ {
+ if( const ScRange* pScRange = rScRanges[ nPos ] )
+ {
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ if( ConvertRange( aXclRange, *pScRange, bWarn ) )
+ rXclRanges.push_back( aXclRange );
+ }
+ }
+}
+
+// EditEngine->String conversion ==============================================
+
+namespace {
+
+String lclGetUrlRepresentation( const SvxURLField& rUrlField )
+{
+ String aRepr( rUrlField.GetRepresentation() );
+ // no representation -> use URL
+ return aRepr.Len() ? aRepr : rUrlField.GetURL();
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpHyperlinkHelper::XclExpHyperlinkHelper( const XclExpRoot& rRoot, const ScAddress& rScPos ) :
+ XclExpRoot( rRoot ),
+ maScPos( rScPos ),
+ mbMultipleUrls( false )
+{
+}
+
+XclExpHyperlinkHelper::~XclExpHyperlinkHelper()
+{
+}
+
+String XclExpHyperlinkHelper::ProcessUrlField( const SvxURLField& rUrlField )
+{
+ String aUrlRepr;
+
+ if( GetBiff() == EXC_BIFF8 ) // no HLINK records in BIFF2-BIFF7
+ {
+ // there was/is already a HLINK record
+ mbMultipleUrls = mxLinkRec;
+
+ mxLinkRec.reset( new XclExpHyperlink( GetRoot(), rUrlField, maScPos ) );
+
+ if( const String* pRepr = mxLinkRec->GetRepr() )
+ aUrlRepr = *pRepr;
+
+ // add URL to note text
+ ScGlobal::AddToken( maUrlList, rUrlField.GetURL(), '\n' );
+ }
+
+ // no hyperlink representation from Excel HLINK record -> use it from text field
+ return aUrlRepr.Len() ? aUrlRepr : lclGetUrlRepresentation( rUrlField );
+}
+
+bool XclExpHyperlinkHelper::HasLinkRecord() const
+{
+ return !mbMultipleUrls && mxLinkRec;
+}
+
+XclExpHyperlinkHelper::XclExpHyperlinkRef XclExpHyperlinkHelper::GetLinkRecord()
+{
+ if( HasLinkRecord() )
+ return mxLinkRec;
+ return XclExpHyperlinkRef();
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Creates a new formatted string from the passed unformatted string.
+
+ Creates a Unicode string or a byte string, depending on the current BIFF
+ version contained in the passed XclExpRoot object. May create a formatted
+ string object, if the text contains different script types.
+
+ @param pCellAttr
+ Cell attributes used for font formatting.
+ @param nFlags
+ Modifiers for string export.
+ @param nMaxLen
+ The maximum number of characters to store in this string.
+ @return
+ The new string object.
+ */
+XclExpStringRef lclCreateFormattedString(
+ const XclExpRoot& rRoot, const String& rText, const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ /* Create an empty Excel string object with correctly initialized BIFF mode,
+ because this function only uses Append() functions that require this. */
+ XclExpStringRef xString = XclExpStringHelper::CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+
+ // script type handling
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( rRoot, rText );
+
+ // font buffer and cell item set
+ XclExpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ const SfxItemSet& rItemSet = pCellAttr ? pCellAttr->GetItemSet() : rRoot.GetDoc().GetDefPattern()->GetItemSet();
+
+ // process all script portions
+ OUString aOUText( rText );
+ sal_Int32 nPortionPos = 0;
+ sal_Int32 nTextLen = aOUText.getLength();
+ while( nPortionPos < nTextLen )
+ {
+ // get script type and end position of next script portion
+ sal_Int16 nScript = xBreakIt->getScriptType( aOUText, nPortionPos );
+ sal_Int32 nPortionEnd = xBreakIt->endOfScript( aOUText, nPortionPos, nScript );
+
+ // reuse previous script for following weak portions
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+
+ // construct font from current text portion
+ SvxFont aFont( XclExpFontHelper::GetFontFromItemSet( rRoot, rItemSet, nScript ) );
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = xString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *xString, rRoot, aOUText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
+ if( nXclPortionStart < xString->Len() )
+ {
+ // insert font into buffer
+ sal_uInt16 nFontIdx = rFontBuffer.Insert( aFont, EXC_COLOR_CELLTEXT );
+ // insert font index into format run vector
+ xString->AppendFormat( nXclPortionStart, nFontIdx );
+ }
+
+ // go to next script portion
+ nLastScript = nScript;
+ nPortionPos = nPortionEnd;
+ }
+
+ return xString;
+}
+
+/** Creates a new formatted string from an edit engine text object.
+
+ Creates a Unicode string or a byte string, depending on the current BIFF
+ version contained in the passed XclExpRoot object.
+
+ @param rEE
+ The edit engine in use. The text object must already be set.
+ @param nFlags
+ Modifiers for string export.
+ @param nMaxLen
+ The maximum number of characters to store in this string.
+ @return
+ The new string object.
+ */
+XclExpStringRef lclCreateFormattedString(
+ const XclExpRoot& rRoot, EditEngine& rEE, XclExpHyperlinkHelper* pLinkHelper,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ /* Create an empty Excel string object with correctly initialized BIFF mode,
+ because this function only uses Append() functions that require this. */
+ XclExpStringRef xString = XclExpStringHelper::CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+
+ // font buffer and helper item set for edit engine -> Calc item conversion
+ XclExpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ SfxItemSet aItemSet( *rRoot.GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+
+ // script type handling
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // #i63255# get script type for leading weak characters
+ sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( rRoot, rEE.GetText() );
+
+ // process all paragraphs
+ sal_uInt16 nParaCount = rEE.GetParagraphCount();
+ for( sal_uInt16 nPara = 0; nPara < nParaCount; ++nPara )
+ {
+ ESelection aSel( nPara, 0 );
+ String aParaText( rEE.GetText( nPara ) );
+
+ SvUShorts aPosList;
+ rEE.GetPortions( nPara, aPosList );
+
+ // process all portions in the paragraph
+ sal_uInt16 nPosCount = aPosList.Count();
+ for( sal_uInt16 nPos = 0; nPos < nPosCount; ++nPos )
+ {
+ aSel.nEndPos = static_cast< xub_StrLen >( aPosList.GetObject( nPos ) );
+ String aXclPortionText( aParaText, aSel.nStartPos, aSel.nEndPos - aSel.nStartPos );
+
+ aItemSet.ClearItem();
+ SfxItemSet aEditSet( rEE.GetAttribs( aSel ) );
+ ScPatternAttr::GetFromEditItemSet( aItemSet, aEditSet );
+
+ // get escapement value
+ short nEsc = GETITEM( aEditSet, SvxEscapementItem, EE_CHAR_ESCAPEMENT ).GetEsc();
+
+ // process text fields
+ bool bIsHyperlink = false;
+ if( aSel.nStartPos + 1 == aSel.nEndPos )
+ {
+ // test if the character is a text field
+ const SfxPoolItem* pItem;
+ if( aEditSet.GetItemState( EE_FEATURE_FIELD, false, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxFieldData* pField = static_cast< const SvxFieldItem* >( pItem )->GetField();
+ if( const SvxURLField* pUrlField = PTR_CAST( SvxURLField, pField ) )
+ {
+ // convert URL field to string representation
+ aXclPortionText = pLinkHelper ?
+ pLinkHelper->ProcessUrlField( *pUrlField ) :
+ lclGetUrlRepresentation( *pUrlField );
+ bIsHyperlink = true;
+ }
+ else
+ {
+ DBG_ERRORFILE( "lclCreateFormattedString - unknown text field" );
+ aXclPortionText.Erase();
+ }
+ }
+ }
+
+ // Excel start position of this portion
+ sal_uInt16 nXclPortionStart = xString->Len();
+ // add portion text to Excel string
+ XclExpStringHelper::AppendString( *xString, rRoot, aXclPortionText );
+ if( (nXclPortionStart < xString->Len()) || (aParaText.Len() == 0) )
+ {
+ /* Construct font from current edit engine text portion. Edit engine
+ creates different portions for different script types, no need to loop. */
+ sal_Int16 nScript = xBreakIt->getScriptType( aXclPortionText, 0 );
+ if( nScript == ApiScriptType::WEAK )
+ nScript = nLastScript;
+ SvxFont aFont( XclExpFontHelper::GetFontFromItemSet( rRoot, aItemSet, nScript ) );
+ nLastScript = nScript;
+
+ // add escapement
+ aFont.SetEscapement( nEsc );
+ // modify automatic font color for hyperlinks
+ if( bIsHyperlink && (GETITEM( aItemSet, SvxColorItem, ATTR_FONT_COLOR ).GetValue().GetColor() == COL_AUTO) )
+ aFont.SetColor( Color( COL_LIGHTBLUE ) );
+
+ // insert font into buffer
+ sal_uInt16 nFontIdx = rFontBuffer.Insert( aFont, EXC_COLOR_CELLTEXT );
+ // insert font index into format run vector
+ xString->AppendFormat( nXclPortionStart, nFontIdx );
+ }
+
+ aSel.nStartPos = aSel.nEndPos;
+ }
+
+ // add trailing newline (important for correct character index calculation)
+ if( nPara + 1 < nParaCount )
+ XclExpStringHelper::AppendChar( *xString, rRoot, '\n' );
+ }
+
+ return xString;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString( new XclExpString );
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ xString->Assign( rString, nFlags, nMaxLen );
+ else
+ xString->AssignByte( rString, rRoot.GetTextEncoding(), nFlags, nMaxLen );
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString = CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+ AppendChar( *xString, rRoot, cChar );
+ return xString;
+}
+
+void XclExpStringHelper::AppendString( XclExpString& rXclString, const XclExpRoot& rRoot, const String& rString )
+{
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ rXclString.Append( rString );
+ else
+ rXclString.AppendByte( rString, rRoot.GetTextEncoding() );
+}
+
+void XclExpStringHelper::AppendChar( XclExpString& rXclString, const XclExpRoot& rRoot, sal_Unicode cChar )
+{
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ rXclString.Append( cChar );
+ else
+ rXclString.AppendByte( cChar, rRoot.GetTextEncoding() );
+}
+
+XclExpStringRef XclExpStringHelper::CreateCellString(
+ const XclExpRoot& rRoot, const ScStringCell& rStringCell, const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ String aCellText;
+ rStringCell.GetString( aCellText );
+ return lclCreateFormattedString( rRoot, aCellText, pCellAttr, nFlags, nMaxLen );
+}
+
+XclExpStringRef XclExpStringHelper::CreateCellString(
+ const XclExpRoot& rRoot, const ScEditCell& rEditCell, const ScPatternAttr* pCellAttr,
+ XclExpHyperlinkHelper& rLinkHelper, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ if( const EditTextObject* pEditObj = rEditCell.GetData() )
+ {
+ // formatted cell
+ ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
+ sal_Bool bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( sal_True );
+ // default items
+ const SfxItemSet& rItemSet = pCellAttr ? pCellAttr->GetItemSet() : rRoot.GetDoc().GetDefPattern()->GetItemSet();
+ SfxItemSet* pEEItemSet = new SfxItemSet( rEE.GetEmptyItemSet() );
+ ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
+ rEE.SetDefaults( pEEItemSet ); // edit engine takes ownership
+ // create the string
+ rEE.SetText( *pEditObj );
+ xString = lclCreateFormattedString( rRoot, rEE, &rLinkHelper, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ }
+ else
+ {
+ // unformatted cell
+ String aCellText;
+ rEditCell.GetString( aCellText );
+ xString = lclCreateFormattedString( rRoot, aCellText, pCellAttr, nFlags, nMaxLen );
+ }
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const SdrTextObj& rTextObj,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ if( const OutlinerParaObject* pParaObj = rTextObj.GetOutlinerParaObject() )
+ {
+ EditEngine& rEE = rRoot.GetDrawEditEngine();
+ sal_Bool bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( sal_True );
+ // create the string
+ rEE.SetText( pParaObj->GetTextObject() );
+ xString = lclCreateFormattedString( rRoot, rEE, 0, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ // limit formats - TODO: BIFF dependent
+ if( !xString->IsEmpty() )
+ {
+ xString->LimitFormatCount( EXC_MAXRECSIZE_BIFF8 / 8 - 1 );
+ xString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpStringHelper::CreateString - textbox without para object" );
+ // create BIFF dependent empty Excel string
+ xString = CreateString( rRoot, EMPTY_STRING, nFlags, nMaxLen );
+ }
+ return xString;
+}
+
+XclExpStringRef XclExpStringHelper::CreateString(
+ const XclExpRoot& rRoot, const EditTextObject& rEditObj,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ XclExpStringRef xString;
+ EditEngine& rEE = rRoot.GetDrawEditEngine();
+ sal_Bool bOldUpdateMode = rEE.GetUpdateMode();
+ rEE.SetUpdateMode( sal_True );
+ rEE.SetText( rEditObj );
+ xString = lclCreateFormattedString( rRoot, rEE, 0, nFlags, nMaxLen );
+ rEE.SetUpdateMode( bOldUpdateMode );
+ // limit formats - TODO: BIFF dependent
+ if( !xString->IsEmpty() )
+ {
+ xString->LimitFormatCount( EXC_MAXRECSIZE_BIFF8 / 8 - 1 );
+ xString->AppendTrailingFormat( EXC_FONT_APP );
+ }
+ return xString;
+}
+
+sal_Int16 XclExpStringHelper::GetLeadingScriptType( const XclExpRoot& rRoot, const String& rString )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ Reference< XBreakIterator > xBreakIt = rRoot.GetDoc().GetBreakIterator();
+ OUString aOUString( rString );
+ sal_Int32 nStrPos = 0;
+ sal_Int32 nStrLen = aOUString.getLength();
+ sal_Int16 nScript = ApiScriptType::WEAK;
+ while( (nStrPos < nStrLen) && (nScript == ApiScriptType::WEAK) )
+ {
+ nScript = xBreakIt->getScriptType( aOUString, nStrPos );
+ nStrPos = xBreakIt->endOfScript( aOUString, nStrPos, nScript );
+ }
+ return (nScript == ApiScriptType::WEAK) ? rRoot.GetDefApiScript() : nScript;
+}
+
+// Header/footer conversion ===================================================
+
+XclExpHFConverter::XclExpHFConverter( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mrEE( rRoot.GetHFEditEngine() ),
+ mnTotalHeight( 0 )
+{
+}
+
+void XclExpHFConverter::GenerateString(
+ const EditTextObject* pLeftObj,
+ const EditTextObject* pCenterObj,
+ const EditTextObject* pRightObj )
+{
+ maHFString.Erase();
+ mnTotalHeight = 0;
+ AppendPortion( pLeftObj, 'L' );
+ AppendPortion( pCenterObj, 'C' );
+ AppendPortion( pRightObj, 'R' );
+}
+
+void XclExpHFConverter::AppendPortion( const EditTextObject* pTextObj, sal_Unicode cPortionCode )
+{
+ if( !pTextObj ) return;
+
+ String aText;
+ sal_Int32 nHeight = 0;
+ SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+
+ // edit engine
+ sal_Bool bOldUpdateMode = mrEE.GetUpdateMode();
+ mrEE.SetUpdateMode( sal_True );
+ mrEE.SetText( *pTextObj );
+
+ // font information
+ XclFontData aFontData, aNewData;
+ if( const XclExpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
+ {
+ aFontData = pFirstFont->GetFontData();
+ (aFontData.mnHeight += 10) /= 20; // using pt here, not twips
+ }
+ else
+ aFontData.mnHeight = 10;
+
+ const FontList* pFontList = 0;
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
+ pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
+ pFontList = pInfoItem->GetFontList();
+ }
+
+ sal_uInt16 nParaCount = mrEE.GetParagraphCount();
+ for( sal_uInt16 nPara = 0; nPara < nParaCount; ++nPara )
+ {
+ ESelection aSel( nPara, 0 );
+ String aParaText;
+ sal_Int32 nParaHeight = 0;
+ SvUShorts aPosList;
+ mrEE.GetPortions( nPara, aPosList );
+
+ sal_uInt16 nPosCount = aPosList.Count();
+ for( sal_uInt16 nPos = 0; nPos < nPosCount; ++nPos )
+ {
+ aSel.nEndPos = static_cast< xub_StrLen >( aPosList.GetObject( nPos ) );
+ if( aSel.nStartPos < aSel.nEndPos )
+ {
+
+// --- font attributes ---
+
+ Font aFont;
+ aItemSet.ClearItem();
+ SfxItemSet aEditSet( mrEE.GetAttribs( aSel ) );
+ ScPatternAttr::GetFromEditItemSet( aItemSet, aEditSet );
+ ScPatternAttr::GetFont( aFont, aItemSet, SC_AUTOCOL_RAW );
+
+ // font name and style
+ aNewData.maName = XclTools::GetXclFontName( aFont.GetName() );
+ aNewData.mnWeight = (aFont.GetWeight() > WEIGHT_NORMAL) ? EXC_FONTWGHT_BOLD : EXC_FONTWGHT_NORMAL;
+ aNewData.mbItalic = (aFont.GetItalic() != ITALIC_NONE);
+ bool bNewFont = !(aFontData.maName == aNewData.maName);
+ bool bNewStyle = (aFontData.mnWeight != aNewData.mnWeight) ||
+ (aFontData.mbItalic != aNewData.mbItalic);
+ if( bNewFont || (bNewStyle && pFontList) )
+ {
+ aParaText.AppendAscii( "&\"" ).Append( aNewData.maName );
+ if( pFontList )
+ {
+ FontInfo aFontInfo( pFontList->Get(
+ aNewData.maName,
+ (aNewData.mnWeight > EXC_FONTWGHT_NORMAL) ? WEIGHT_BOLD : WEIGHT_NORMAL,
+ aNewData.mbItalic ? ITALIC_NORMAL : ITALIC_NONE ) );
+ aNewData.maStyle = pFontList->GetStyleName( aFontInfo );
+ if( aNewData.maStyle.Len() )
+ aParaText.Append( ',' ).Append( aNewData.maStyle );
+ }
+ aParaText.Append( '"' );
+ }
+
+ // height
+ // is calculated wrong in ScPatternAttr::GetFromEditItemSet, because already in twips and not 100thmm
+ // -> get it directly from edit engine item set
+ aNewData.mnHeight = ulimit_cast< sal_uInt16 >( GETITEM( aEditSet, SvxFontHeightItem, EE_CHAR_FONTHEIGHT ).GetHeight() );
+ (aNewData.mnHeight += 10) /= 20;
+ bool bFontHtChanged = (aFontData.mnHeight != aNewData.mnHeight);
+ if( bFontHtChanged )
+ aParaText.Append( '&' ).Append( String::CreateFromInt32( aNewData.mnHeight ) );
+ // update maximum paragraph height, convert to twips
+ nParaHeight = ::std::max< sal_Int32 >( nParaHeight, aNewData.mnHeight * 20 );
+
+ // underline
+ aNewData.mnUnderline = EXC_FONTUNDERL_NONE;
+ switch( aFont.GetUnderline() )
+ {
+ case UNDERLINE_NONE: aNewData.mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case UNDERLINE_SINGLE: aNewData.mnUnderline = EXC_FONTUNDERL_SINGLE; break;
+ case UNDERLINE_DOUBLE: aNewData.mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: aNewData.mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+ if( aFontData.mnUnderline != aNewData.mnUnderline )
+ {
+ sal_uInt8 nTmpUnderl = (aNewData.mnUnderline == EXC_FONTUNDERL_NONE) ?
+ aFontData.mnUnderline : aNewData.mnUnderline;
+ aParaText.AppendAscii( (nTmpUnderl == EXC_FONTUNDERL_SINGLE) ? "&U" : "&E" );
+ }
+
+ // strikeout
+ aNewData.mbStrikeout = (aFont.GetStrikeout() != STRIKEOUT_NONE);
+ if( aFontData.mbStrikeout != aNewData.mbStrikeout )
+ aParaText.AppendAscii( "&S" );
+
+ // super/sub script
+ const SvxEscapementItem& rEscapeItem = GETITEM( aEditSet, SvxEscapementItem, EE_CHAR_ESCAPEMENT );
+ aNewData.SetScEscapement( rEscapeItem.GetEsc() );
+ if( aFontData.mnEscapem != aNewData.mnEscapem )
+ {
+ switch(aNewData.mnEscapem)
+ {
+ // close the previous super/sub script.
+ case EXC_FONTESC_NONE: aParaText.AppendAscii( (aFontData.mnEscapem == EXC_FONTESC_SUPER) ? "&X" : "&Y" ); break;
+ case EXC_FONTESC_SUPER: aParaText.AppendAscii( "&X" ); break;
+ case EXC_FONTESC_SUB: aParaText.AppendAscii( "&Y" ); break;
+ default: break;
+ }
+ }
+
+ aFontData = aNewData;
+
+// --- text content or text fields ---
+
+ const SfxPoolItem* pItem;
+ if( (aSel.nStartPos + 1 == aSel.nEndPos) && // fields are single characters
+ (aEditSet.GetItemState( EE_FEATURE_FIELD, false, &pItem ) == SFX_ITEM_SET) )
+ {
+ if( const SvxFieldData* pFieldData = static_cast< const SvxFieldItem* >( pItem )->GetField() )
+ {
+ if( pFieldData->ISA( SvxPageField ) )
+ aParaText.AppendAscii( "&P" );
+ else if( pFieldData->ISA( SvxPagesField ) )
+ aParaText.AppendAscii( "&N" );
+ else if( pFieldData->ISA( SvxDateField ) )
+ aParaText.AppendAscii( "&D" );
+ else if( pFieldData->ISA( SvxTimeField ) || pFieldData->ISA( SvxExtTimeField ) )
+ aParaText.AppendAscii( "&T" );
+ else if( pFieldData->ISA( SvxTableField ) )
+ aParaText.AppendAscii( "&A" );
+ else if( pFieldData->ISA( SvxFileField ) ) // title -> file name
+ aParaText.AppendAscii( "&F" );
+ else if( const SvxExtFileField* pFileField = PTR_CAST( SvxExtFileField, pFieldData ) )
+ {
+ switch( pFileField->GetFormat() )
+ {
+ case SVXFILEFORMAT_NAME_EXT:
+ case SVXFILEFORMAT_NAME:
+ aParaText.AppendAscii( "&F" );
+ break;
+ case SVXFILEFORMAT_PATH:
+ aParaText.AppendAscii( "&Z" );
+ break;
+ case SVXFILEFORMAT_FULLPATH:
+ aParaText.AppendAscii( "&Z&F" );
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpHFConverter::AppendPortion - unknown file field" );
+ }
+ }
+ }
+ }
+ else
+ {
+ String aPortionText( mrEE.GetText( aSel ) );
+ aPortionText.SearchAndReplaceAll( String( '&' ), String( RTL_CONSTASCII_USTRINGPARAM( "&&" ) ) );
+ // #i17440# space between font height and numbers in text
+ if( bFontHtChanged && aParaText.Len() && aPortionText.Len() )
+ {
+ sal_Unicode cLast = aParaText.GetChar( aParaText.Len() - 1 );
+ sal_Unicode cFirst = aPortionText.GetChar( 0 );
+ if( ('0' <= cLast) && (cLast <= '9') && ('0' <= cFirst) && (cFirst <= '9') )
+ aParaText.Append( ' ' );
+ }
+ aParaText.Append( aPortionText );
+ }
+ }
+
+ aSel.nStartPos = aSel.nEndPos;
+ }
+
+ ScGlobal::AddToken( aText, aParaText, '\n' );
+ if( nParaHeight == 0 )
+ nParaHeight = aFontData.mnHeight * 20; // points -> twips
+ nHeight += nParaHeight;
+ }
+
+ mrEE.SetUpdateMode( bOldUpdateMode );
+
+ if( aText.Len() )
+ {
+ maHFString.Append( '&' ).Append( cPortionCode ).Append( aText );
+ mnTotalHeight = ::std::max( mnTotalHeight, nHeight );
+ }
+}
+
+// URL conversion =============================================================
+
+namespace {
+
+/** Converts the file URL passed in rUrl to a URL in DOS notation (local or UNC).
+ @param rUrl (in/out-param) In: URL to convert; Out: Converted URL in DOS notation.
+ @param rBasePath Base path for relative URLs.
+ @param bSaveRelUrl Converts to a relative URL, using rBasePath.
+ @return True = Conversion successful, rUrl contains converted file URL. */
+bool lclConvertToDos( String& rUrl, const String& rBasePath, bool bSaveRelUrl )
+{
+ String aDosUrl( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ bool bRet = (aDosUrl.Len() > 0);
+ if( bRet && bSaveRelUrl )
+ {
+ // try to convert to relative path
+ String aDosBase( INetURLObject( rBasePath ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( aDosBase.Len() )
+ {
+ xub_StrLen nPos;
+
+ // --- 1st step: delete equal subdirectories ---
+
+ // special handling for UNC
+ xub_StrLen nStartSearch = aDosBase.EqualsAscii( "\\\\", 0, 2 ) ? 2 : 0;
+ bool bEqualBase = false;
+ bool bLoop = true;
+ while( bLoop && ((nPos = aDosBase.Search( '\\', nStartSearch )) != STRING_NOTFOUND) )
+ {
+ bLoop = (sal_True == aDosBase.Equals( aDosUrl, 0, nPos + 1 ));
+ if( bLoop )
+ {
+ aDosBase.Erase( 0, nPos + 1 );
+ aDosUrl.Erase( 0, nPos + 1 );
+ nStartSearch = 0;
+ bEqualBase = true;
+ }
+ }
+
+ // --- 2nd step: add parent directory levels ---
+
+ if( bEqualBase )
+ {
+ while( (nPos = aDosBase.Search( '\\' )) != STRING_NOTFOUND )
+ {
+ aDosBase.Erase( 0, nPos + 1 );
+ aDosUrl.InsertAscii( "..\\", 0 );
+ }
+ }
+ }
+ rUrl = aDosUrl;
+ }
+ return bRet;
+}
+
+/** Encodes special parts of the URL, i.e. directory separators and volume names.
+ @param pTableName Pointer to a table name to be encoded in this URL, or 0. */
+void lclEncodeDosUrl( XclBiff eBiff, String& rUrl, const String* pTableName = 0 )
+{
+ if( rUrl.Len() )
+ {
+ String aOldUrl( rUrl );
+ rUrl = EXC_URLSTART_ENCODED;
+
+ if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( "\\\\", 0, 2 ) )
+ {
+ // UNC
+ rUrl.Append( EXC_URL_DOSDRIVE ).Append( '@' );
+ aOldUrl.Erase( 0, 2 );
+ }
+ else if( (aOldUrl.Len() > 2) && aOldUrl.EqualsAscii( ":\\", 1, 2 ) )
+ {
+ // drive letter
+ rUrl.Append( EXC_URL_DOSDRIVE ).Append( aOldUrl.GetChar( 0 ) );
+ aOldUrl.Erase( 0, 3 );
+ }
+
+ // directories
+ xub_StrLen nPos;
+ while( (nPos = aOldUrl.Search( '\\' )) != STRING_NOTFOUND )
+ {
+ if( aOldUrl.EqualsAscii( "..", 0, 2 ) )
+ rUrl.Append( EXC_URL_PARENTDIR ); // parent dir
+ else
+ rUrl.Append( aOldUrl.GetBuffer(), nPos ).Append( EXC_URL_SUBDIR );
+ aOldUrl.Erase( 0, nPos + 1 );
+ }
+
+ // file name
+ if( pTableName ) // enclose file name in brackets if table name follows
+ rUrl.Append( '[' ).Append( aOldUrl ).Append( ']' );
+ else
+ rUrl.Append( aOldUrl );
+ }
+ else // empty URL -> self reference
+ {
+ switch( eBiff )
+ {
+ case EXC_BIFF5:
+ rUrl = pTableName ? EXC_URLSTART_SELFENCODED : EXC_URLSTART_SELF;
+ break;
+ case EXC_BIFF8:
+ DBG_ASSERT( pTableName, "lclEncodeDosUrl - sheet name required for BIFF8" );
+ rUrl = EXC_URLSTART_SELF;
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+
+ // table name
+ if( pTableName )
+ rUrl.Append( *pTableName );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+String XclExpUrlHelper::EncodeUrl( const XclExpRoot& rRoot, const String& rAbsUrl, const String* pTableName )
+{
+ String aDosUrl( rAbsUrl );
+ if( !aDosUrl.Len() || lclConvertToDos( aDosUrl, rRoot.GetBasePath(), rRoot.IsRelUrl() ) )
+ lclEncodeDosUrl( rRoot.GetBiff(), aDosUrl, pTableName );
+ return aDosUrl;
+}
+
+String XclExpUrlHelper::EncodeDde( const String& rApplic, const String rTopic )
+{
+ String aDde( rApplic );
+ aDde.Append( EXC_DDE_DELIM ).Append( rTopic );
+ return aDde;
+}
+
+// Cached Value Lists =========================================================
+
+XclExpCachedMatrix::XclExpCachedMatrix( const ScMatrix& rMatrix )
+ : mrMatrix( rMatrix )
+{
+ mrMatrix.IncRef();
+}
+XclExpCachedMatrix::~XclExpCachedMatrix()
+{
+ mrMatrix.DecRef();
+}
+
+void XclExpCachedMatrix::GetDimensions( SCSIZE & nCols, SCSIZE & nRows ) const
+{
+ mrMatrix.GetDimensions( nCols, nRows );
+
+ DBG_ASSERT( nCols && nRows, "XclExpCachedMatrix::GetDimensions - empty matrix" );
+ DBG_ASSERT( nCols <= 256, "XclExpCachedMatrix::GetDimensions - too many columns" );
+}
+
+sal_Size XclExpCachedMatrix::GetSize() const
+{
+ SCSIZE nCols, nRows;
+
+ GetDimensions( nCols, nRows );
+
+ /* The returned size may be wrong if the matrix contains strings. The only
+ effect is that the export stream has to update a wrong record size which is
+ faster than to iterate through all cached values and calculate their sizes. */
+ return 3 + 9 * (nCols * nRows);
+}
+
+void XclExpCachedMatrix::Save( XclExpStream& rStrm ) const
+{
+ SCSIZE nCols, nRows;
+
+ GetDimensions( nCols, nRows );
+
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ // in BIFF2-BIFF7: 256 columns represented by 0 columns
+ rStrm << static_cast< sal_uInt8 >( nCols ) << static_cast< sal_uInt16 >( nRows );
+ else
+ // in BIFF8: columns and rows decreaed by 1
+ rStrm << static_cast< sal_uInt8 >( nCols - 1 ) << static_cast< sal_uInt16 >( nRows - 1 );
+
+ for( SCSIZE nRow = 0; nRow < nRows; ++nRow )
+ {
+ for( SCSIZE nCol = 0; nCol < nCols; ++nCol )
+ {
+ ScMatrixValue nMatVal = mrMatrix.Get( nCol, nRow );
+
+ if( SC_MATVAL_EMPTY == nMatVal.nType )
+ {
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_EMPTY;
+ rStrm.WriteZeroBytes( 8 );
+ }
+ else if( ScMatrix::IsNonValueType( nMatVal.nType ) )
+ {
+ XclExpString aStr( nMatVal.GetString(), EXC_STR_DEFAULT );
+ rStrm.SetSliceSize( 6 );
+ rStrm << EXC_CACHEDVAL_STRING << aStr;
+ }
+ else if( SC_MATVAL_BOOLEAN == nMatVal.nType )
+ {
+ sal_Int8 nBool = nMatVal.GetBoolean();
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_BOOL << nBool;
+ rStrm.WriteZeroBytes( 7 );
+ }
+ else if( sal_uInt16 nScError = nMatVal.GetError() )
+ {
+ sal_Int8 nError ( XclTools::GetXclErrorCode( nScError ) );
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_ERROR << nError;
+ rStrm.WriteZeroBytes( 7 );
+ }
+ else
+ {
+ rStrm.SetSliceSize( 9 );
+ rStrm << EXC_CACHEDVAL_DOUBLE << nMatVal.fVal;
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xelink.cxx b/sc/source/filter/excel/xelink.cxx
new file mode 100644
index 000000000000..43f8342bf815
--- /dev/null
+++ b/sc/source/filter/excel/xelink.cxx
@@ -0,0 +1,2367 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xelink.hxx"
+
+#include <algorithm>
+#include <unotools/collatorwrapper.hxx>
+#include <svl/zforlist.hxx>
+#include "document.hxx"
+#include "cell.hxx"
+#include "scextopt.hxx"
+#include "externalrefmgr.hxx"
+
+#include <vector>
+#include <memory>
+
+using ::std::auto_ptr;
+using ::std::find_if;
+using ::std::vector;
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+// External names =============================================================
+
+/** This is a base class for any external name (i.e. add-in names or DDE links).
+ @descr Derived classes implement creation and export of the external names. */
+class XclExpExtNameBase : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** @param nFlags The flags to export. */
+ explicit XclExpExtNameBase( const XclExpRoot& rRoot,
+ const String& rName, sal_uInt16 nFlags = 0 );
+ virtual ~XclExpExtNameBase();
+
+ /** Returns the name string of the external name. */
+ inline const String& GetName() const { return maName; }
+
+private:
+ /** Writes the start of the record that is equal in all EXTERNNAME records and calls WriteAddData(). */
+ virtual void WriteBody( XclExpStream& rStrm );
+ /** Called to write additional data following the common record contents.
+ @descr Derived classes should overwrite this function to write their data. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ String maName; /// Calc name (title) of the external name.
+ XclExpStringRef mxName; /// Excel name (title) of the external name.
+ sal_uInt16 mnFlags; /// Flags for record export.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an EXTERNNAME record for an add-in function name. */
+class XclExpExtNameAddIn : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an EXTERNNAME record for a DDE link. */
+class XclExpExtNameDde : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtNameDde( const XclExpRoot& rRoot, const String& rName,
+ sal_uInt16 nFlags, const ScMatrix* pResults = 0 );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpCachedMatrix > XclExpCachedMatRef;
+ XclExpCachedMatRef mxMatrix; /// Cached results of the DDE link.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpSupbook;
+
+class XclExpExtName : public XclExpExtNameBase
+{
+public:
+ explicit XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const String& rName,
+ const ScExternalRefCache::TokenArrayRef pArray );
+
+private:
+ /** Writes additional record contents. */
+ virtual void WriteAddData( XclExpStream& rStrm );
+
+private:
+ const XclExpSupbook& mrSupbook;
+ auto_ptr<ScTokenArray> mpArray;
+};
+
+// List of external names =====================================================
+
+/** List of all external names of a sheet. */
+class XclExpExtNameBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpExtNameBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts an add-in function name
+ @return The 1-based (Excel-like) list index of the name. */
+ sal_uInt16 InsertAddIn( const String& rName );
+ /** InsertEuroTool */
+ sal_uInt16 InsertEuroTool( const String& rName );
+ /** Inserts a DDE link.
+ @return The 1-based (Excel-like) list index of the DDE link. */
+ sal_uInt16 InsertDde( const String& rApplic, const String& rTopic, const String& rItem );
+
+ sal_uInt16 InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the EXTERNNAME record list. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpExtNameBase > XclExpExtNameList;
+ typedef XclExpExtNameList::RecordRefType XclExpExtNameRef;
+
+private:
+ /** Returns the 1-based (Excel-like) list index of the external name or 0, if not found. */
+ sal_uInt16 GetIndex( const String& rName ) const;
+ /** Appends the passed newly crested external name.
+ @return The 1-based (Excel-like) list index of the appended name. */
+ sal_uInt16 AppendNew( XclExpExtNameBase* pExtName );
+
+private:
+ XclExpExtNameList maNameList; /// The list with all EXTERNNAME records.
+};
+
+// Cached external cells ======================================================
+
+/** Stores the contents of a consecutive row of external cells (record CRN). */
+class XclExpCrn : public XclExpRecord
+{
+public:
+ explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+
+ /** Returns true, if the passed value could be appended to this record. */
+ bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+ void WriteBool( XclExpStream& rStrm, bool bValue );
+ void WriteDouble( XclExpStream& rStrm, double fValue );
+ void WriteString( XclExpStream& rStrm, const OUString& rValue );
+ void WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode );
+ void WriteEmpty( XclExpStream& rStrm );
+
+private:
+ typedef ::std::vector< Any > CachedValues;
+
+ CachedValues maValues; /// All cached values.
+ SCCOL mnScCol; /// Column index of the first external cell.
+ SCROW mnScRow; /// Row index of the external cells.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the record XCT which is the header record of a CRN record list.
+ */
+class XclExpXct : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXct( const XclExpRoot& rRoot,
+ const String& rTabName, sal_uInt16 nSBTab,
+ ScExternalRefCache::TableTypeRef xCacheTable );
+
+ /** Returns the external sheet name. */
+ inline const XclExpString& GetTabName() const { return maTabName; }
+
+ /** Stores all cells in the given range in the CRN list. */
+ void StoreCellRange( const ScRange& rRange );
+
+ void StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken );
+ void StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken );
+
+ /** Writes the XCT and all CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ ScExternalRefCache::TableTypeRef mxCacheTable;
+ ScMarkData maUsedCells; /// Contains addresses of all stored cells.
+ ScRange maBoundRange; /// Bounding box of maUsedCells.
+ XclExpString maTabName; /// Sheet name of the external sheet.
+ sal_uInt16 mnSBTab; /// Referred sheet index in SUPBOOK record.
+};
+
+// External documents (EXTERNSHEET/SUPBOOK), base class =======================
+
+/** Base class for records representing external sheets/documents.
+
+ In BIFF5/BIFF7, this record is the EXTERNSHEET record containing one sheet
+ of the own or an external document. In BIFF8, this record is the SUPBOOK
+ record representing the entire own or external document with all referenced
+ sheets.
+ */
+class XclExpExternSheetBase : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpExternSheetBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_uInt32 nRecSize = 0 );
+
+protected:
+ /** Creates and returns the list of EXTERNNAME records. */
+ XclExpExtNameBuffer& GetExtNameBuffer();
+ /** Creates and returns the list of EXTERNNAME records. */
+ void WriteExtNameBuffer( XclExpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpExtNameBuffer > XclExpExtNameBfrRef;
+ XclExpExtNameBfrRef mxExtNameBfr; /// List of EXTERNNAME records.
+};
+
+// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
+
+/** Represents an EXTERNSHEET record containing the URL and sheet name of a sheet.
+ @descr This class is used up to BIFF7 only, writing a BIFF8 EXTERNSHEET
+ record is implemented directly in the link manager. */
+class XclExpExternSheet : public XclExpExternSheetBase
+{
+public:
+ /** Creates an EXTERNSHEET record containing a special code (i.e. own document or sheet). */
+ explicit XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode );
+ /** Creates an EXTERNSHEET record referring to an internal sheet. */
+ explicit XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName );
+
+ /** Finds or inserts an EXTERNNAME record for add-ins.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertAddIn( const String& rName );
+
+ /** Writes the EXTERNSHEET and all EXTERNNAME, XCT and CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Initializes the record data with the passed encoded URL. */
+ void Init( const String& rEncUrl );
+ /** Writes the contents of the EXTERNSHEET record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maTabName; /// The name of the sheet.
+};
+
+// External documents (SUPBOOK, BIFF8) ========================================
+
+/** The SUPBOOK record contains data for an external document (URL, sheet names, external values). */
+class XclExpSupbook : public XclExpExternSheetBase
+{
+public:
+ /** Creates a SUPBOOK record for internal references. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount );
+ /** Creates a SUPBOOK record for add-in functions. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot );
+ /** EUROTOOL SUPBOOK */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType );
+ /** Creates a SUPBOOK record for an external document. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl );
+ /** Creates a SUPBOOK record for a DDE link. */
+ explicit XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic );
+
+ /** Returns true, if this SUPBOOK contains the passed URL of an external document. */
+ bool IsUrlLink( const String& rUrl ) const;
+ /** Returns true, if this SUPBOOK contains the passed DDE link. */
+ bool IsDdeLink( const String& rApplic, const String& rTopic ) const;
+ /** Fills the passed reference log entry with the URL and sheet names. */
+ void FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
+ sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const;
+
+ /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
+ void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
+
+ void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ::formula::FormulaToken& rToken );
+ void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ::formula::FormulaToken& rToken );
+
+ sal_uInt16 GetTabIndex( const String& rTabName ) const;
+ sal_uInt16 GetTabCount() const;
+
+ /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
+ sal_uInt16 InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable );
+ /** Finds or inserts an EXTERNNAME record for add-ins.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertAddIn( const String& rName );
+ /** InsertEuroTool */
+ sal_uInt16 InsertEuroTool( const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
+ sal_uInt16 InsertDde( const String& rItem );
+
+ sal_uInt16 InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Returns the sheet name inside of this SUPBOOK. */
+ const XclExpString* GetTabName( sal_uInt16 nSBTab ) const;
+
+ /** Writes the SUPBOOK record contents. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpXct > XclExpXctList;
+ typedef XclExpXctList::RecordRefType XclExpXctRef;
+
+ XclExpXctList maXctList; /// List of XCT records (which contain CRN records).
+ String maUrl; /// URL of the external document or application name for DDE.
+ String maDdeTopic; /// Topic of an DDE link.
+ XclExpString maUrlEncoded; /// Document name encoded for Excel.
+ XclSupbookType meType; /// Type of this SUPBOOK record.
+ sal_uInt16 mnXclTabCount; /// Number of internal sheets.
+};
+
+// All SUPBOOKS in a document =================================================
+
+/** This struct contains a sheet index range for 3D references.
+ @descr This reference consists of an index to a SUPBOOK record and indexes
+ to SUPBOOK sheet names. */
+struct XclExpXti
+{
+ sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
+ sal_uInt16 mnFirstSBTab; /// Index to the first sheet of the range in the SUPBOOK.
+ sal_uInt16 mnLastSBTab; /// Index to the last sheet of the range in the SUPBOOK.
+
+ inline explicit XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
+ inline explicit XclExpXti( sal_uInt16 nSupbook, sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) :
+ mnSupbook( nSupbook ), mnFirstSBTab( nFirstSBTab ), mnLastSBTab( nLastSBTab ) {}
+
+ /** Writes this XTI structure (inside of the EXTERNSHEET record). */
+ inline void Save( XclExpStream& rStrm ) const
+ { rStrm << mnSupbook << mnFirstSBTab << mnLastSBTab; }
+};
+
+inline bool operator==( const XclExpXti& rLeft, const XclExpXti& rRight )
+{
+ return
+ (rLeft.mnSupbook == rRight.mnSupbook) &&
+ (rLeft.mnFirstSBTab == rRight.mnFirstSBTab) &&
+ (rLeft.mnLastSBTab == rRight.mnLastSBTab);
+}
+
+// ----------------------------------------------------------------------------
+
+/** Contains a list of all SUPBOOK records and index arrays of external sheets. */
+class XclExpSupbookBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpSupbookBuffer( const XclExpRoot& rRoot );
+
+ /** Finds SUPBOOK index and SUPBOOK sheet range from given Excel sheet range.
+ @return An XTI structure containing SUPBOOK and sheet indexes. */
+ XclExpXti GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 ) const;
+
+ /** Stores all cells in the given range in a CRN record list. */
+ void StoreCellRange( const ScRange& rRange );
+
+ void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell );
+ void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange );
+
+ /** Finds or inserts an EXTERNNAME record for an add-in function name.
+ @param rnSupbook Returns the index of the SUPBOOK record which contains the add-in function name.
+ @param rnExtName Returns the 1-based EXTERNNAME record index. */
+ bool InsertAddIn(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ bool InsertEuroTool(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @param rnSupbook Returns the index of the SUPBOOK record which contains the DDE link.
+ @param rnExtName Returns the 1-based EXTERNNAME record index. */
+ bool InsertDde(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ bool InsertExtName(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ XclExpXti GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
+ /** Writes all SUPBOOK records with their sub records. */
+ virtual void Save( XclExpStream& rStrm );
+
+ struct XclExpSBIndex
+ {
+ sal_uInt16 mnSupbook; /// SUPBOOK index for an Excel sheet.
+ sal_uInt16 mnSBTab; /// Sheet name index in SUPBOOK for an Excel sheet.
+ inline void Set( sal_uInt16 nSupbook, sal_uInt16 nSBTab )
+ { mnSupbook = nSupbook; mnSBTab = nSBTab; }
+ };
+ typedef ::std::vector< XclExpSBIndex > XclExpSBIndexVec;
+
+private:
+ typedef XclExpRecordList< XclExpSupbook > XclExpSupbookList;
+ typedef XclExpSupbookList::RecordRefType XclExpSupbookRef;
+
+private:
+ /** Searches for the SUPBOOK record containing the passed document URL.
+ @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
+ @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
+ @return True, if the SUPBOOK record exists (out-parameters are valid). */
+ bool GetSupbookUrl( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
+ const String& rUrl ) const;
+ /** Searches for the SUPBOOK record containing the passed DDE link.
+ @param rxSupbook (out-param) Returns a reference to the SUPBOOK record, or 0.
+ @param rnIndex (out-param) Returns the list index, if the SUPBOOK exists.
+ @return True, if the SUPBOOK record exists (out-parameters are valid). */
+ bool GetSupbookDde( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
+ const String& rApplic, const String& rTopic ) const;
+
+ /** Appends a new SUPBOOK to the list.
+ @return The list index of the SUPBOOK record. */
+ sal_uInt16 Append( XclExpSupbookRef xSupbook );
+
+private:
+ XclExpSupbookList maSupbookList; /// List of all SUPBOOK records.
+ XclExpSBIndexVec maSBIndexVec; /// SUPBOOK and sheet name index for each Excel sheet.
+ sal_uInt16 mnOwnDocSB; /// Index to SUPBOOK for own document.
+ sal_uInt16 mnAddInSB; /// Index to add-in SUPBOOK.
+};
+
+// Export link manager ========================================================
+
+/** Abstract base class for implementation classes of the link manager. */
+class XclExpLinkManagerImpl : protected XclExpRoot
+{
+public:
+ /** Derived classes search for an EXTSHEET structure for the given Calc sheet range. */
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry ) = 0;
+ /** Derived classes search for a special EXTERNSHEET index for the own document. */
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) = 0;
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry ) = 0;
+
+ /** Derived classes store all cells in the given range in a CRN record list. */
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ) = 0;
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 ) = 0;
+
+ /** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName ) = 0;
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName ) = 0;
+
+ /** Derived classes find or insert an EXTERNNAME record for DDE links. */
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem ) = 0;
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) = 0;
+
+ /** Derived classes write the entire link table to the passed stream. */
+ virtual void Save( XclExpStream& rStrm ) = 0;
+
+protected:
+ explicit XclExpLinkManagerImpl( const XclExpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager for BIFF5/BIFF7. */
+class XclExpLinkManagerImpl5 : public XclExpLinkManagerImpl
+{
+public:
+ explicit XclExpLinkManagerImpl5( const XclExpRoot& rRoot );
+
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry );
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpExternSheet > XclExpExtSheetList;
+ typedef XclExpExtSheetList::RecordRefType XclExpExtSheetRef;
+ typedef ::std::map< SCTAB, sal_uInt16 > XclExpIntTabMap;
+ typedef ::std::map< sal_Unicode, sal_uInt16 > XclExpCodeMap;
+
+private:
+ /** Returns the number of EXTERNSHEET records. */
+ sal_uInt16 GetExtSheetCount() const;
+
+ /** Appends an internal EXTERNSHEET record and returns the one-based index. */
+ sal_uInt16 AppendInternal( XclExpExtSheetRef xExtSheet );
+ /** Creates all EXTERNSHEET records for internal sheets on first call. */
+ void CreateInternal();
+
+ /** Returns the specified internal EXTERNSHEET record. */
+ XclExpExtSheetRef GetInternal( sal_uInt16 nExtSheet );
+ /** Returns the EXTERNSHEET index of an internal Calc sheet, or a deleted reference. */
+ XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab );
+ /** Finds or creates the EXTERNSHEET index of an internal special EXTERNSHEET. */
+ XclExpExtSheetRef FindInternal( sal_uInt16& rnExtSheet, sal_Unicode cCode );
+
+private:
+ XclExpExtSheetList maExtSheetList; /// List with EXTERNSHEET records.
+ XclExpIntTabMap maIntTabMap; /// Maps internal Calc sheets to EXTERNSHEET records.
+ XclExpCodeMap maCodeMap; /// Maps special external codes to EXTERNSHEET records.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager for BIFF8. */
+class XclExpLinkManagerImpl8 : public XclExpLinkManagerImpl
+{
+public:
+ explicit XclExpLinkManagerImpl8( const XclExpRoot& rRoot );
+
+ virtual void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry );
+ virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
+ virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ virtual void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 );
+
+ virtual bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ virtual bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+
+ virtual bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ virtual bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Searches for or inserts a new XTI structure.
+ @return The 0-based list index of the XTI structure. */
+ sal_uInt16 InsertXti( const XclExpXti& rXti );
+
+private:
+ typedef ::std::vector< XclExpXti > XclExpXtiVec;
+
+ XclExpSupbookBuffer maSBBuffer; /// List of all SUPBOOK records.
+ XclExpXtiVec maXtiVec; /// List of XTI structures for the EXTERNSHEET record.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+// Excel sheet indexes ========================================================
+
+const sal_uInt8 EXC_TABBUF_IGNORE = 0x01; /// Sheet will be ignored completely.
+const sal_uInt8 EXC_TABBUF_EXTERN = 0x02; /// Sheet is linked externally.
+const sal_uInt8 EXC_TABBUF_SKIPMASK = 0x0F; /// Sheet will be skipped, if any flag is set.
+const sal_uInt8 EXC_TABBUF_VISIBLE = 0x10; /// Sheet is visible.
+const sal_uInt8 EXC_TABBUF_SELECTED = 0x20; /// Sheet is selected.
+const sal_uInt8 EXC_TABBUF_MIRRORED = 0x40; /// Sheet is mirrored (right-to-left).
+
+// ----------------------------------------------------------------------------
+
+XclExpTabInfo::XclExpTabInfo( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnScCnt( 0 ),
+ mnXclCnt( 0 ),
+ mnXclExtCnt( 0 ),
+ mnXclSelCnt( 0 ),
+ mnDisplXclTab( 0 ),
+ mnFirstVisXclTab( 0 )
+{
+ ScDocument& rDoc = GetDoc();
+ ScExtDocOptions& rDocOpt = GetExtDocOptions();
+
+ mnScCnt = rDoc.GetTableCount();
+
+ SCTAB nScTab;
+ SCTAB nFirstVisScTab = SCTAB_INVALID; // first visible sheet
+ SCTAB nFirstExpScTab = SCTAB_INVALID; // first exported sheet
+
+ // --- initialize the flags in the index buffer ---
+
+ maTabInfoVec.resize( mnScCnt );
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ // ignored sheets (skipped by export, with invalid Excel sheet index)
+ if( rDoc.IsScenario( nScTab ) )
+ {
+ SetFlag( nScTab, EXC_TABBUF_IGNORE );
+ }
+
+ // external sheets (skipped, but with valid Excel sheet index for ref's)
+ else if( rDoc.GetLinkMode( nScTab ) == SC_LINK_VALUE )
+ {
+ SetFlag( nScTab, EXC_TABBUF_EXTERN );
+ }
+
+ // exported sheets
+ else
+ {
+ // sheet name
+ rDoc.GetName( nScTab, maTabInfoVec[ nScTab ].maScName );
+
+ // remember first exported sheet
+ if( nFirstExpScTab == SCTAB_INVALID )
+ nFirstExpScTab = nScTab;
+ // remember first visible exported sheet
+ if( (nFirstVisScTab == SCTAB_INVALID) && rDoc.IsVisible( nScTab ) )
+ nFirstVisScTab = nScTab;
+
+ // sheet visible (only exported sheets)
+ SetFlag( nScTab, EXC_TABBUF_VISIBLE, rDoc.IsVisible( nScTab ) );
+
+ // sheet selected (only exported sheets)
+ if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nScTab ) )
+ SetFlag( nScTab, EXC_TABBUF_SELECTED, pTabSett->mbSelected );
+
+ // sheet mirrored (only exported sheets)
+ SetFlag( nScTab, EXC_TABBUF_MIRRORED, rDoc.IsLayoutRTL( nScTab ) );
+ }
+ }
+
+ // --- visible/selected sheets ---
+
+ SCTAB nDisplScTab = rDocOpt.GetDocSettings().mnDisplTab;
+
+ // find first visible exported sheet
+ if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
+ {
+ // no exportable visible sheet -> use first exportable sheet
+ nFirstVisScTab = nFirstExpScTab;
+ if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
+ {
+ // no exportable sheet at all -> use active sheet and export it
+ nFirstVisScTab = nDisplScTab;
+ SetFlag( nFirstVisScTab, EXC_TABBUF_SKIPMASK, false ); // clear skip flags
+ }
+ SetFlag( nFirstVisScTab, EXC_TABBUF_VISIBLE ); // must be visible, even if originally hidden
+ }
+
+ // find currently displayed sheet
+ if( !IsExportTab( nDisplScTab ) ) // selected sheet not exported (i.e. scenario) -> use first visible
+ nDisplScTab = nFirstVisScTab;
+ SetFlag( nDisplScTab, EXC_TABBUF_VISIBLE | EXC_TABBUF_SELECTED );
+
+ // number of selected sheets
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ if( IsSelectedTab( nScTab ) )
+ ++mnXclSelCnt;
+
+ // --- calculate resulting Excel sheet indexes ---
+
+ CalcXclIndexes();
+ mnFirstVisXclTab = GetXclTab( nFirstVisScTab );
+ mnDisplXclTab = GetXclTab( nDisplScTab );
+
+ // --- sorted vectors for index lookup ---
+
+ CalcSortedIndexes();
+}
+
+bool XclExpTabInfo::IsExportTab( SCTAB nScTab ) const
+{
+ /* Check sheet index before to avoid assertion in GetFlag(). */
+ return (nScTab < mnScCnt) && !GetFlag( nScTab, EXC_TABBUF_SKIPMASK );
+}
+
+bool XclExpTabInfo::IsExternalTab( SCTAB nScTab ) const
+{
+ /* Check sheet index before to avoid assertion (called from formula
+ compiler also for deleted references). */
+ return (nScTab < mnScCnt) && GetFlag( nScTab, EXC_TABBUF_EXTERN );
+}
+
+bool XclExpTabInfo::IsVisibleTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_VISIBLE );
+}
+
+bool XclExpTabInfo::IsSelectedTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_SELECTED );
+}
+
+bool XclExpTabInfo::IsDisplayedTab( SCTAB nScTab ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
+ return GetXclTab( nScTab ) == mnDisplXclTab;
+}
+
+bool XclExpTabInfo::IsMirroredTab( SCTAB nScTab ) const
+{
+ return GetFlag( nScTab, EXC_TABBUF_MIRRORED );
+}
+
+const String& XclExpTabInfo::GetScTabName( SCTAB nScTab ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
+ return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].maScName : EMPTY_STRING;
+}
+
+sal_uInt16 XclExpTabInfo::GetXclTab( SCTAB nScTab ) const
+{
+ return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].mnXclTab : EXC_TAB_DELETED;
+}
+
+SCTAB XclExpTabInfo::GetRealScTab( SCTAB nSortedScTab ) const
+{
+ DBG_ASSERT( nSortedScTab < mnScCnt, "XclExpTabInfo::GetRealScTab - sheet out of range" );
+ return (nSortedScTab < mnScCnt) ? maFromSortedVec[ nSortedScTab ] : SCTAB_INVALID;
+}
+
+bool XclExpTabInfo::GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::GetFlag - sheet out of range" );
+ return (nScTab < mnScCnt) && ::get_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags );
+}
+
+void XclExpTabInfo::SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet )
+{
+ DBG_ASSERT( nScTab < mnScCnt, "XclExpTabInfo::SetFlag - sheet out of range" );
+ if( nScTab < mnScCnt )
+ ::set_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags, bSet );
+}
+
+void XclExpTabInfo::CalcXclIndexes()
+{
+ sal_uInt16 nXclTab = 0;
+ SCTAB nScTab = 0;
+
+ // --- pass 1: process regular sheets ---
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ if( IsExportTab( nScTab ) )
+ {
+ maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
+ ++nXclTab;
+ }
+ else
+ maTabInfoVec[ nScTab ].mnXclTab = EXC_TAB_DELETED;
+ }
+ mnXclCnt = nXclTab;
+
+ // --- pass 2: process external sheets (nXclTab continues) ---
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ if( IsExternalTab( nScTab ) )
+ {
+ maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
+ ++nXclTab;
+ ++mnXclExtCnt;
+ }
+ }
+
+ // result: first occur all exported sheets, followed by all external sheets
+}
+
+typedef ::std::pair< String, SCTAB > XclExpTabName;
+typedef ::std::vector< XclExpTabName > XclExpTabNameVec;
+
+inline bool operator<( const XclExpTabName& rArg1, const XclExpTabName& rArg2 )
+{
+ // compare the sheet names only
+ return ScGlobal::GetCollator()->compareString( rArg1.first, rArg2.first ) == COMPARE_LESS;
+}
+
+void XclExpTabInfo::CalcSortedIndexes()
+{
+ ScDocument& rDoc = GetDoc();
+ XclExpTabNameVec aVec( mnScCnt );
+ SCTAB nScTab;
+
+ // fill with sheet names
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ rDoc.GetName( nScTab, aVec[ nScTab ].first );
+ aVec[ nScTab ].second = nScTab;
+ }
+ ::std::sort( aVec.begin(), aVec.end() );
+
+ // fill index vectors from sorted sheet name vector
+ maFromSortedVec.resize( mnScCnt );
+ maToSortedVec.resize( mnScCnt );
+ for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
+ {
+ maFromSortedVec[ nScTab ] = aVec[ nScTab ].second;
+ maToSortedVec[ aVec[ nScTab ].second ] = nScTab;
+ }
+}
+
+// External names =============================================================
+
+XclExpExtNameBase::XclExpExtNameBase(
+ const XclExpRoot& rRoot, const String& rName, sal_uInt16 nFlags ) :
+ XclExpRecord( EXC_ID_EXTERNNAME ),
+ XclExpRoot( rRoot ),
+ maName( rName ),
+ mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
+ mnFlags( nFlags )
+{
+ DBG_ASSERT( maName.Len() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
+ SetRecSize( 6 + mxName->GetSize() );
+}
+
+XclExpExtNameBase::~XclExpExtNameBase()
+{
+}
+
+void XclExpExtNameBase::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnFlags
+ << sal_uInt32( 0 )
+ << *mxName;
+ WriteAddData( rStrm );
+}
+
+void XclExpExtNameBase::WriteAddData( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot& rRoot, const String& rName ) :
+ XclExpExtNameBase( rRoot, rName )
+{
+ AddRecSize( 4 );
+}
+
+void XclExpExtNameAddIn::WriteAddData( XclExpStream& rStrm )
+{
+ // write a #REF! error formula
+ rStrm << sal_uInt16( 2 ) << EXC_TOKID_ERR << EXC_ERR_REF;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot& rRoot,
+ const String& rName, sal_uInt16 nFlags, const ScMatrix* pResults ) :
+ XclExpExtNameBase( rRoot, rName, nFlags )
+{
+ if( pResults )
+ {
+ mxMatrix.reset( new XclExpCachedMatrix( *pResults ) );
+ AddRecSize( mxMatrix->GetSize() );
+ }
+}
+
+void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
+{
+ if( mxMatrix )
+ mxMatrix->Save( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) :
+ XclExpExtNameBase( rRoot, rName ),
+ mrSupbook(rSupbook),
+ mpArray(pArray->Clone())
+{
+}
+
+void XclExpExtName::WriteAddData( XclExpStream& rStrm )
+{
+ // Write only if it only has a single token that is either a cell or cell
+ // range address. Excel just writes '02 00 1C 17' for all the other types
+ // of external names.
+
+ using namespace ::formula;
+ do
+ {
+ if (mpArray->GetLen() != 1)
+ break;
+
+ const ScToken* p = static_cast<const ScToken*>(mpArray->First());
+ if (!p->IsExternalRef())
+ break;
+
+ switch (p->GetType())
+ {
+ case svExternalSingleRef:
+ {
+ const ScSingleRefData& rRef = p->GetSingleRef();
+ if (rRef.IsTabRel())
+ break;
+
+ bool bColRel = rRef.IsColRel();
+ bool bRowRel = rRef.IsRowRel();
+ sal_uInt16 nCol = static_cast< sal_uInt16 >( bColRel ? rRef.nRelCol : rRef.nCol );
+ sal_uInt16 nRow = static_cast< sal_uInt16 >( bRowRel ? rRef.nRelRow : rRef.nRow );
+ if (bColRel) nCol |= 0x4000;
+ if (bRowRel) nCol |= 0x8000;
+
+ const String& rTabName = p->GetString();
+ sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
+
+ // size is always 9
+ rStrm << static_cast<sal_uInt16>(9);
+ // operator token (3A for cell reference)
+ rStrm << static_cast<sal_uInt8>(0x3A);
+ // cell address (Excel's address has 2 sheet IDs.)
+ rStrm << nSBTab << nSBTab << nRow << nCol;
+ return;
+ }
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rRef = p->GetDoubleRef();
+ const ScSingleRefData& r1 = rRef.Ref1;
+ const ScSingleRefData& r2 = rRef.Ref2;
+ if (r1.IsTabRel() || r2.IsTabRel())
+ break;
+
+ sal_uInt16 nTab1 = r1.nTab;
+ sal_uInt16 nTab2 = r2.nTab;
+ bool bCol1Rel = r1.IsColRel();
+ bool bRow1Rel = r1.IsRowRel();
+ bool bCol2Rel = r2.IsColRel();
+ bool bRow2Rel = r2.IsRowRel();
+
+ sal_uInt16 nCol1 = static_cast< sal_uInt16 >( bCol1Rel ? r1.nRelCol : r1.nCol );
+ sal_uInt16 nCol2 = static_cast< sal_uInt16 >( bCol2Rel ? r2.nRelCol : r2.nCol );
+ sal_uInt16 nRow1 = static_cast< sal_uInt16 >( bRow1Rel ? r1.nRelRow : r1.nRow );
+ sal_uInt16 nRow2 = static_cast< sal_uInt16 >( bRow2Rel ? r2.nRelRow : r2.nRow );
+ if (bCol1Rel) nCol1 |= 0x4000;
+ if (bRow1Rel) nCol1 |= 0x8000;
+ if (bCol2Rel) nCol2 |= 0x4000;
+ if (bRow2Rel) nCol2 |= 0x8000;
+
+ const String& rTabName = p->GetString();
+ sal_uInt16 nSBTab = mrSupbook.GetTabIndex(rTabName);
+
+ // size is always 13 (0x0D)
+ rStrm << static_cast<sal_uInt16>(13);
+ // operator token (3B for area reference)
+ rStrm << static_cast<sal_uInt8>(0x3B);
+ // range (area) address
+ sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
+ rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
+ return;
+ }
+ default:
+ ; // nothing
+ }
+ }
+ while (false);
+
+ // special value for #REF! (02 00 1C 17)
+ rStrm << static_cast<sal_uInt16>(2) << EXC_TOKID_ERR << EXC_ERR_REF;
+}
+
+// List of external names =====================================================
+
+XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertAddIn( const String& rName )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtNameAddIn( GetRoot(), rName ) );
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertEuroTool( const String& rName )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtNameBase( GetRoot(), rName ) );
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertDde(
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ sal_uInt16 nIndex = GetIndex( rItem );
+ if( nIndex == 0 )
+ {
+ sal_uInt16 nPos;
+ if( GetDoc().FindDdeLink( rApplic, rTopic, rItem, SC_DDE_IGNOREMODE, nPos ) )
+ {
+ // create the leading 'StdDocumentName' EXTERNNAME record
+ if( maNameList.IsEmpty() )
+ AppendNew( new XclExpExtNameDde(
+ GetRoot(), CREATE_STRING( "StdDocumentName" ), EXC_EXTN_EXPDDE_STDDOC ) );
+
+ // try to find DDE result array, but create EXTERNNAME record without them too
+ const ScMatrix* pScMatrix = GetDoc().GetDdeLinkResultMatrix( nPos );
+ nIndex = AppendNew( new XclExpExtNameDde( GetRoot(), rItem, EXC_EXTN_EXPDDE, pScMatrix ) );
+ }
+ }
+ return nIndex;
+}
+
+sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ sal_uInt16 nIndex = GetIndex( rName );
+ return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, pArray ) );
+}
+
+void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
+{
+ maNameList.Save( rStrm );
+}
+
+sal_uInt16 XclExpExtNameBuffer::GetIndex( const String& rName ) const
+{
+ for( size_t nPos = 0, nSize = maNameList.GetSize(); nPos < nSize; ++nPos )
+ if( maNameList.GetRecord( nPos )->GetName() == rName )
+ return static_cast< sal_uInt16 >( nPos + 1 );
+ return 0;
+}
+
+sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName )
+{
+ XclExpExtNameRef xExtName( pExtName );
+ size_t nSize = maNameList.GetSize();
+ if( nSize < 0x7FFF )
+ {
+ maNameList.AppendRecord( xExtName );
+ return static_cast< sal_uInt16 >( nSize + 1 );
+ }
+ return 0;
+}
+
+// Cached external cells ======================================================
+
+XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) :
+ XclExpRecord( EXC_ID_CRN, 4 ),
+ mnScCol( nScCol ),
+ mnScRow( nScRow )
+{
+ maValues.push_back( rValue );
+}
+
+bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
+{
+ if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) )
+ return false;
+ maValues.push_back( rValue );
+ return true;
+}
+
+void XclExpCrn::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 )
+ << static_cast< sal_uInt8 >( mnScCol )
+ << static_cast< sal_uInt16 >( mnScRow );
+ for( CachedValues::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->has< bool >() )
+ WriteBool( rStrm, aIt->get< bool >() );
+ else if( aIt->has< double >() )
+ WriteDouble( rStrm, aIt->get< double >() );
+ else if( aIt->has< OUString >() )
+ WriteString( rStrm, aIt->get< OUString >() );
+ else
+ WriteEmpty( rStrm );
+ }
+}
+
+void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue )
+{
+ rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0);
+ rStrm.WriteZeroBytes( 7 );
+}
+
+void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue )
+{
+ if( ::rtl::math::isNan( fValue ) )
+ {
+ sal_uInt16 nScError = static_cast< sal_uInt16 >( reinterpret_cast< const sal_math_Double* >( &fValue )->nan_parts.fraction_lo );
+ WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) );
+ }
+ else
+ {
+ rStrm << EXC_CACHEDVAL_DOUBLE << fValue;
+ }
+}
+
+void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue )
+{
+ rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue );
+}
+
+void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode )
+{
+ rStrm << EXC_CACHEDVAL_ERROR << nErrCode;
+ rStrm.WriteZeroBytes( 7 );
+}
+
+void XclExpCrn::WriteEmpty( XclExpStream& rStrm )
+{
+ rStrm << EXC_CACHEDVAL_EMPTY;
+ rStrm.WriteZeroBytes( 8 );
+}
+
+// Cached cells of a sheet ====================================================
+
+XclExpXct::XclExpXct( const XclExpRoot& rRoot, const String& rTabName,
+ sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) :
+ XclExpRoot( rRoot ),
+ mxCacheTable( xCacheTable ),
+ maBoundRange( ScAddress::INITIALIZE_INVALID ),
+ maTabName( rTabName ),
+ mnSBTab( nSBTab )
+{
+}
+
+void XclExpXct::StoreCellRange( const ScRange& rRange )
+{
+ // #i70418# restrict size of external range to prevent memory overflow
+ if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 )
+ return;
+
+ maUsedCells.SetMultiMarkArea( rRange );
+ maBoundRange.ExtendTo( rRange );
+}
+
+void XclExpXct::StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken )
+{
+ maUsedCells.SetMultiMarkArea( ScRange( rCell ) );
+ maBoundRange.ExtendTo( ScRange( rCell ) );
+ (void)rToken;
+}
+
+void XclExpXct::StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken )
+{
+ maUsedCells.SetMultiMarkArea( rRange );
+ maBoundRange.ExtendTo( rRange );
+ (void)rToken;
+}
+
+namespace {
+
+class XclExpCrnList : public XclExpRecordList< XclExpCrn >
+{
+public:
+ /** Inserts the passed value into an existing or new CRN record.
+ @return True = value inserted successfully, false = CRN list is full. */
+ bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
+};
+
+bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
+{
+ RecordRefType xLastRec = GetLastRecord();
+ if( xLastRec && xLastRec->InsertValue( nScCol, nScRow, rValue ) )
+ return true;
+ if( GetSize() == SAL_MAX_UINT16 )
+ return false;
+ AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) );
+ return true;
+}
+
+} // namespace
+
+void XclExpXct::Save( XclExpStream& rStrm )
+{
+ if( !mxCacheTable )
+ return;
+
+ /* Get the range of used rows in the cache table. This may help to
+ optimize building the CRN record list if the cache table does not
+ contain all referred cells, e.g. if big empty ranges are used in the
+ formulas. */
+ ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange();
+ if( aRowRange.first >= aRowRange.second )
+ return;
+
+ /* Crop the bounding range of used cells in this table to Excel limits.
+ Return if there is no external cell inside these limits. */
+ if( !GetAddressConverter().ValidateRange( maBoundRange, false ) )
+ return;
+
+ /* Find the resulting row range that needs to be processed. */
+ SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() );
+ SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() );
+ if( nScRow1 > nScRow2 )
+ return;
+
+ /* Build and collect all CRN records before writing the XCT record. This
+ is needed to determine the total number of CRN records which must be
+ known when writing the XCT record (possibly encrypted, so seeking the
+ output strem back after writing the CRN records is not an option). */
+ XclExpCrnList aCrnRecs;
+ SvNumberFormatter& rFormatter = GetFormatter();
+ bool bValid = true;
+ for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow )
+ {
+ ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow );
+ for( SCCOL nScCol = aColRange.first; bValid && (nScCol < aColRange.second); ++nScCol )
+ {
+ if( maUsedCells.IsCellMarked( nScCol, nScRow, sal_True ) )
+ {
+ sal_uInt32 nScNumFmt = 0;
+ ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt );
+ using namespace ::formula;
+ if( xToken.get() ) switch( xToken->GetType() )
+ {
+ case svDouble:
+ bValid = (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) ?
+ aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) :
+ aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) );
+ break;
+ case svString:
+ // do not save empty strings (empty cells) to cache
+ if( xToken->GetString().Len() > 0 )
+ bValid = aCrnRecs.InsertValue( nScCol, nScRow, Any( OUString( xToken->GetString() ) ) );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ // write the XCT record and the list of CRN records
+ rStrm.StartRecord( EXC_ID_XCT, 4 );
+ rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab;
+ rStrm.EndRecord();
+ aCrnRecs.Save( rStrm );
+}
+
+// External documents (EXTERNSHEET/SUPBOOK), base class =======================
+
+XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot& rRoot, sal_uInt16 nRecId, sal_uInt32 nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpExtNameBuffer& XclExpExternSheetBase::GetExtNameBuffer()
+{
+ if( !mxExtNameBfr )
+ mxExtNameBfr.reset( new XclExpExtNameBuffer( GetRoot() ) );
+ return *mxExtNameBfr;
+}
+
+void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream& rStrm )
+{
+ if( mxExtNameBfr )
+ mxExtNameBfr->Save( rStrm );
+}
+
+// External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
+
+XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
+{
+ Init( String( cCode ) );
+}
+
+XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, const String& rTabName ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
+{
+ // reference to own sheet: \03<sheetname>
+ Init( String( EXC_EXTSH_TABNAME ).Append( rTabName ) );
+}
+
+void XclExpExternSheet::Save( XclExpStream& rStrm )
+{
+ // EXTERNSHEET record
+ XclExpRecord::Save( rStrm );
+ // EXTERNNAME records
+ WriteExtNameBuffer( rStrm );
+}
+
+void XclExpExternSheet::Init( const String& rEncUrl )
+{
+ DBG_ASSERT_BIFF( GetBiff() <= EXC_BIFF5 );
+ maTabName.AssignByte( rEncUrl, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ SetRecSize( maTabName.GetSize() );
+}
+
+sal_uInt16 XclExpExternSheet::InsertAddIn( const String& rName )
+{
+ return GetExtNameBuffer().InsertAddIn( rName );
+}
+
+void XclExpExternSheet::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt8 nNameSize = static_cast< sal_uInt8 >( maTabName.Len() );
+ // special case: reference to own sheet (starting with '\03') needs wrong string length
+ if( maTabName.GetChar( 0 ) == EXC_EXTSH_TABNAME )
+ --nNameSize;
+ rStrm << nNameSize;
+ maTabName.WriteBuffer( rStrm );
+}
+
+// External document (SUPBOOK, BIFF8) =========================================
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ meType( EXC_SBTYPE_SELF ),
+ mnXclTabCount( nXclTabCount )
+{
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ meType( EXC_SBTYPE_ADDIN ),
+ mnXclTabCount( 1 )
+{
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl, XclSupbookType ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
+ maUrl( rUrl ),
+ maUrlEncoded( rUrl ),
+ meType( EXC_SBTYPE_EUROTOOL ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+}
+
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
+ maUrl( rUrl ),
+ maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot, rUrl ) ),
+ meType( EXC_SBTYPE_EXTERN ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+
+ // We need to create all tables up front to ensure the correct table order.
+ ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl );
+ ScfStringVec aTabNames;
+ pRefMgr->getAllCachedTableNames( nFileId, aTabNames );
+ for( ScfStringVec::const_iterator aBeg = aTabNames.begin(), aIt = aBeg, aEnd = aTabNames.end(); aIt != aEnd; ++aIt )
+ InsertTabName( *aIt, pRefMgr->getCacheTable( nFileId, aIt - aBeg ) );
+}
+
+XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) :
+ XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
+ maUrl( rApplic ),
+ maDdeTopic( rTopic ),
+ maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic, rTopic ) ),
+ meType( EXC_SBTYPE_SPECIAL ),
+ mnXclTabCount( 0 )
+{
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
+}
+
+bool XclExpSupbook::IsUrlLink( const String& rUrl ) const
+{
+ return (meType == EXC_SBTYPE_EXTERN || meType == EXC_SBTYPE_EUROTOOL) && (maUrl == rUrl);
+}
+
+bool XclExpSupbook::IsDdeLink( const String& rApplic, const String& rTopic ) const
+{
+ return (meType == EXC_SBTYPE_SPECIAL) && (maUrl == rApplic) && (maDdeTopic == rTopic);
+}
+
+void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
+ sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const
+{
+ rRefLogEntry.mpUrl = maUrlEncoded.IsEmpty() ? 0 : &maUrlEncoded;
+ rRefLogEntry.mpFirstTab = GetTabName( nFirstSBTab );
+ rRefLogEntry.mpLastTab = GetTabName( nLastSBTab );
+}
+
+void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
+{
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCellRange( rRange );
+}
+
+void XclExpSupbook::StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken )
+{
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCell( rCell, rToken );
+}
+
+void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken )
+{
+ // multi-table range is not allowed!
+ if( rRange.aStart.Tab() == rRange.aEnd.Tab() )
+ if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
+ pXct->StoreCellRange( rRange, rToken );
+}
+
+sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName ) const
+{
+ XclExpString aXclName(rTabName);
+ size_t nSize = maXctList.GetSize();
+ for (size_t i = 0; i < nSize; ++i)
+ {
+ XclExpXctRef aRec = maXctList.GetRecord(i);
+ if (aXclName == aRec->GetTabName())
+ return ulimit_cast<sal_uInt16>(i);
+ }
+ return EXC_NOTAB;
+}
+
+sal_uInt16 XclExpSupbook::GetTabCount() const
+{
+ return ulimit_cast<sal_uInt16>(maXctList.GetSize());
+}
+
+sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable )
+{
+ DBG_ASSERT( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
+ sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
+ XclExpXctRef xXct( new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable ) );
+ AddRecSize( xXct->GetTabName().GetSize() );
+ maXctList.AppendRecord( xXct );
+ return nSBTab;
+}
+
+sal_uInt16 XclExpSupbook::InsertAddIn( const String& rName )
+{
+ return GetExtNameBuffer().InsertAddIn( rName );
+}
+
+sal_uInt16 XclExpSupbook::InsertEuroTool( const String& rName )
+{
+ return GetExtNameBuffer().InsertEuroTool( rName );
+}
+
+sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
+{
+ return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
+}
+
+sal_uInt16 XclExpSupbook::InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ return GetExtNameBuffer().InsertExtName(*this, rName, pArray);
+}
+
+void XclExpSupbook::Save( XclExpStream& rStrm )
+{
+ // SUPBOOK record
+ XclExpRecord::Save( rStrm );
+ // XCT record, CRN records
+ maXctList.Save( rStrm );
+ // EXTERNNAME records
+ WriteExtNameBuffer( rStrm );
+}
+
+const XclExpString* XclExpSupbook::GetTabName( sal_uInt16 nSBTab ) const
+{
+ XclExpXctRef xXct = maXctList.GetRecord( nSBTab );
+ return xXct ? &xXct->GetTabName() : 0;
+}
+
+void XclExpSupbook::WriteBody( XclExpStream& rStrm )
+{
+ switch( meType )
+ {
+ case EXC_SBTYPE_SELF:
+ rStrm << mnXclTabCount << EXC_SUPB_SELF;
+ break;
+ case EXC_SBTYPE_EXTERN:
+ case EXC_SBTYPE_SPECIAL:
+ case EXC_SBTYPE_EUROTOOL:
+ {
+ sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
+ rStrm << nCount << maUrlEncoded;
+
+ for( size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos )
+ rStrm << maXctList.GetRecord( nPos )->GetTabName();
+ }
+ break;
+ case EXC_SBTYPE_ADDIN:
+ rStrm << mnXclTabCount << EXC_SUPB_ADDIN;
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpSupbook::WriteBody - unknown SUPBOOK type" );
+ }
+}
+
+// All SUPBOOKS in a document =================================================
+
+XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnOwnDocSB( SAL_MAX_UINT16 ),
+ mnAddInSB( SAL_MAX_UINT16 )
+{
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ sal_uInt16 nXclCnt = rTabInfo.GetXclTabCount();
+ sal_uInt16 nCodeCnt = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
+ size_t nCount = nXclCnt + rTabInfo.GetXclExtTabCount();
+
+ DBG_ASSERT( nCount > 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
+ if( nCount )
+ {
+ maSBIndexVec.resize( nCount );
+
+ // self-ref SUPBOOK first of list
+ XclExpSupbookRef xSupbook( new XclExpSupbook( GetRoot(), ::std::max( nXclCnt, nCodeCnt ) ) );
+ mnOwnDocSB = Append( xSupbook );
+ for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
+ maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
+ }
+}
+
+XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
+ XclExpRefLogEntry* pRefLogEntry ) const
+{
+ XclExpXti aXti;
+ size_t nSize = maSBIndexVec.size();
+ if( (nFirstXclTab < nSize) && (nLastXclTab < nSize) )
+ {
+ // index of the SUPBOOK record
+ aXti.mnSupbook = maSBIndexVec[ nFirstXclTab ].mnSupbook;
+
+ // all sheets in the same supbook?
+ bool bSameSB = true;
+ for( sal_uInt16 nXclTab = nFirstXclTab + 1; bSameSB && (nXclTab <= nLastXclTab); ++nXclTab )
+ {
+ bSameSB = maSBIndexVec[ nXclTab ].mnSupbook == aXti.mnSupbook;
+ if( !bSameSB )
+ nLastXclTab = nXclTab - 1;
+ }
+ aXti.mnFirstSBTab = maSBIndexVec[ nFirstXclTab ].mnSBTab;
+ aXti.mnLastSBTab = maSBIndexVec[ nLastXclTab ].mnSBTab;
+
+ // fill external reference log entry (for change tracking)
+ if( pRefLogEntry )
+ {
+ pRefLogEntry->mnFirstXclTab = nFirstXclTab;
+ pRefLogEntry->mnLastXclTab = nLastXclTab;
+ XclExpSupbookRef xSupbook = maSupbookList.GetRecord( aXti.mnSupbook );
+ if( xSupbook )
+ xSupbook->FillRefLogEntry( *pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab );
+ }
+ }
+ else
+ {
+ // special range, i.e. for deleted sheets or add-ins
+ aXti.mnSupbook = mnOwnDocSB;
+ aXti.mnFirstSBTab = nFirstXclTab;
+ aXti.mnLastSBTab = nLastXclTab;
+ }
+
+ return aXti;
+}
+
+void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
+{
+ sal_uInt16 nXclTab = GetTabInfo().GetXclTab( rRange.aStart.Tab() );
+ if( nXclTab < maSBIndexVec.size() )
+ {
+ const XclExpSBIndex& rSBIndex = maSBIndexVec[ nXclTab ];
+ XclExpSupbookRef xSupbook = maSupbookList.GetRecord( rSBIndex.mnSupbook );
+ DBG_ASSERT( xSupbook , "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
+ if( xSupbook )
+ xSupbook->StoreCellRange( rRange, rSBIndex.mnSBTab );
+ }
+}
+
+namespace {
+
+class FindSBIndexEntry
+{
+public:
+ explicit FindSBIndexEntry(sal_uInt16 nSupbookId, sal_uInt16 nTabId) :
+ mnSupbookId(nSupbookId), mnTabId(nTabId) {}
+
+ bool operator()(const XclExpSupbookBuffer::XclExpSBIndex& r) const
+ {
+ return mnSupbookId == r.mnSupbook && mnTabId == r.mnSBTab;
+ }
+
+private:
+ sal_uInt16 mnSupbookId;
+ sal_uInt16 mnTabId;
+};
+
+}
+
+void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell )
+{
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+
+ ScExternalRefCache::TokenRef pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
+ if (!pToken.get())
+ return;
+
+ sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
+ if (nSheetId == EXC_NOTAB)
+ // specified table name not found in this SUPBOOK.
+ return;
+
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+
+ xSupbook->StoreCell(nSheetId, rCell, *pToken);
+}
+
+void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange )
+{
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+
+ SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
+
+ // If this is a multi-table range, get token for each table.
+ using namespace ::formula;
+ vector<FormulaToken*> aMatrixList;
+ aMatrixList.reserve(nTabCount);
+
+ // This is a new'ed instance, so we must manage its life cycle here.
+ ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
+ if (!pArray.get())
+ return;
+
+ for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
+ {
+ if (p->GetType() == svMatrix)
+ aMatrixList.push_back(p);
+ else if (p->GetOpCode() != ocSep)
+ {
+ // This is supposed to be ocSep!!!
+ return;
+ }
+ }
+
+ if (aMatrixList.size() != static_cast<size_t>(nTabCount))
+ {
+ // matrix size mis-match !
+ return;
+ }
+
+ sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
+
+ ScRange aRange(rRange);
+ aRange.aStart.SetTab(0);
+ aRange.aEnd.SetTab(0);
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ {
+ sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+
+ xSupbook->StoreCellRange(nSheetId, aRange, *aMatrixList[nTab]);
+ }
+}
+
+bool XclExpSupbookBuffer::InsertAddIn(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpSupbookRef xSupbook;
+ if( mnAddInSB == SAL_MAX_UINT16 )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot() ) );
+ mnAddInSB = Append( xSupbook );
+ }
+ else
+ xSupbook = maSupbookList.GetRecord( mnAddInSB );
+ DBG_ASSERT( xSupbook, "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
+ rnSupbook = mnAddInSB;
+ rnExtName = xSupbook->InsertAddIn( rName );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertEuroTool(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpSupbookRef xSupbook;
+ String aUrl( RTL_CONSTASCII_USTRINGPARAM("\001\010EUROTOOL.XLA"));
+ if( !GetSupbookUrl( xSupbook, rnSupbook, aUrl ) )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot(), aUrl, EXC_SBTYPE_EUROTOOL ) );
+ rnSupbook = Append( xSupbook );
+ }
+ rnExtName = xSupbook->InsertEuroTool( rName );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertDde(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ XclExpSupbookRef xSupbook;
+ if( !GetSupbookDde( xSupbook, rnSupbook, rApplic, rTopic ) )
+ {
+ xSupbook.reset( new XclExpSupbook( GetRoot(), rApplic, rTopic ) );
+ rnSupbook = Append( xSupbook );
+ }
+ rnExtName = xSupbook->InsertDde( rItem );
+ return rnExtName > 0;
+}
+
+bool XclExpSupbookBuffer::InsertExtName(
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ XclExpSupbookRef xSupbook;
+ if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
+ {
+ xSupbook.reset( new XclExpSupbook(GetRoot(), rUrl) );
+ rnSupbook = Append(xSupbook);
+ }
+ rnExtName = xSupbook->InsertExtName(rName, pArray);
+ return rnExtName > 0;
+}
+
+XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ return aXti;
+
+ XclExpSupbookRef xSupbook;
+ sal_uInt16 nSupbookId;
+ if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
+ {
+ xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
+ nSupbookId = Append(xSupbook);
+ }
+ aXti.mnSupbook = nSupbookId;
+
+ sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
+ if (nFirstSheetId == EXC_NOTAB)
+ {
+ // first sheet not found in SUPBOOK.
+ return aXti;
+ }
+ sal_uInt16 nSheetCount = xSupbook->GetTabCount();
+ for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
+ {
+ sal_uInt16 nSheetId = nFirstSheetId + i;
+ if (nSheetId >= nSheetCount)
+ return aXti;
+
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
+ if (itr == itrEnd)
+ {
+ maSBIndexVec.push_back(XclExpSBIndex());
+ XclExpSBIndex& r = maSBIndexVec.back();
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
+ if (i == 0)
+ aXti.mnFirstSBTab = nSheetId;
+ if (i == nXclTabSpan - 1)
+ aXti.mnLastSBTab = nSheetId;
+ }
+
+ if (pRefLogEntry)
+ {
+ pRefLogEntry->mnFirstXclTab = 0;
+ pRefLogEntry->mnLastXclTab = 0;
+ if (xSupbook)
+ xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
+ }
+
+ return aXti;
+}
+
+void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
+{
+ maSupbookList.Save( rStrm );
+}
+
+bool XclExpSupbookBuffer::GetSupbookUrl(
+ XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex, const String& rUrl ) const
+{
+ for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
+ {
+ rxSupbook = maSupbookList.GetRecord( nPos );
+ if( rxSupbook->IsUrlLink( rUrl ) )
+ {
+ rnIndex = ulimit_cast< sal_uInt16 >( nPos );
+ return true;
+ }
+ }
+ return false;
+}
+
+bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef& rxSupbook,
+ sal_uInt16& rnIndex, const String& rApplic, const String& rTopic ) const
+{
+ for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
+ {
+ rxSupbook = maSupbookList.GetRecord( nPos );
+ if( rxSupbook->IsDdeLink( rApplic, rTopic ) )
+ {
+ rnIndex = ulimit_cast< sal_uInt16 >( nPos );
+ return true;
+ }
+ }
+ return false;
+}
+
+sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
+{
+ maSupbookList.AppendRecord( xSupbook );
+ return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
+}
+
+// Export link manager ========================================================
+
+XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot& rRoot ) :
+ XclExpLinkManagerImpl( rRoot )
+{
+}
+
+void XclExpLinkManagerImpl5::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ FindInternal( rnExtSheet, rnFirstXclTab, nFirstScTab );
+ if( (rnFirstXclTab == EXC_TAB_DELETED) || (nFirstScTab == nLastScTab) )
+ {
+ rnLastXclTab = rnFirstXclTab;
+ }
+ else
+ {
+ sal_uInt16 nDummyExtSheet;
+ FindInternal( nDummyExtSheet, rnLastXclTab, nLastScTab );
+ }
+
+ (void)pRefLogEntry; // avoid compiler warning
+ DBG_ASSERT( !pRefLogEntry, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
+{
+ sal_uInt16 nExtSheet;
+ FindInternal( nExtSheet, cCode );
+ return nExtSheet;
+}
+
+void XclExpLinkManagerImpl5::FindExtSheet(
+ sal_uInt16 /*nFileId*/, const String& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
+ XclExpRefLogEntry* /*pRefLogEntry*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCell( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef*/ )
+{
+ // not implemented
+}
+
+void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16 /*nFileId*/, const String& /*rTabName*/, const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/ )
+{
+ // not implemented
+}
+
+bool XclExpLinkManagerImpl5::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ XclExpExtSheetRef xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_ADDIN );
+ if( xExtSheet )
+ {
+ rnExtName = xExtSheet->InsertAddIn( rName );
+ return rnExtName > 0;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl5::InsertEuroTool(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rName*/ )
+{
+ return false;
+}
+
+
+bool XclExpLinkManagerImpl5::InsertDde(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/,
+ const String& /*rApplic*/, const String& /*rTopic*/, const String& /*rItem*/ )
+{
+ // not implemented
+ return false;
+}
+
+bool XclExpLinkManagerImpl5::InsertExtName(
+ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rUrl*/,
+ const String& /*rName*/, const ScExternalRefCache::TokenArrayRef /*pArray*/ )
+{
+ // not implemented
+ return false;
+}
+
+void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
+{
+ if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
+ {
+ // EXTERNCOUNT record
+ XclExpUInt16Record( EXC_ID_EXTERNCOUNT, nExtSheetCount ).Save( rStrm );
+ // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
+ maExtSheetList.Save( rStrm );
+ }
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::GetExtSheetCount() const
+{
+ return static_cast< sal_uInt16 >( maExtSheetList.GetSize() );
+}
+
+sal_uInt16 XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef xExtSheet )
+{
+ if( GetExtSheetCount() < 0x7FFF )
+ {
+ maExtSheetList.AppendRecord( xExtSheet );
+ // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
+ return static_cast< sal_uInt16 >( -GetExtSheetCount() );
+ }
+ return 0;
+}
+
+void XclExpLinkManagerImpl5::CreateInternal()
+{
+ if( maIntTabMap.empty() )
+ {
+ // create EXTERNSHEET records for all internal exported sheets
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
+ {
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ XclExpExtSheetRef xRec;
+ if( nScTab == GetCurrScTab() )
+ xRec.reset( new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB ) );
+ else
+ xRec.reset( new XclExpExternSheet( GetRoot(), rTabInfo.GetScTabName( nScTab ) ) );
+ maIntTabMap[ nScTab ] = AppendInternal( xRec );
+ }
+ }
+ }
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet )
+{
+ return maExtSheetList.GetRecord( static_cast< sal_uInt16 >( -nExtSheet - 1 ) );
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab )
+{
+ // create internal EXTERNSHEET records on demand
+ CreateInternal();
+
+ // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
+ XclExpExtSheetRef xExtSheet;
+ XclExpIntTabMap::const_iterator aIt = maIntTabMap.find( nScTab );
+ if( aIt == maIntTabMap.end() )
+ {
+ xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_OWNDOC );
+ rnXclTab = EXC_TAB_DELETED;
+ }
+ else
+ {
+ rnExtSheet = aIt->second;
+ xExtSheet = GetInternal( rnExtSheet );
+ rnXclTab = GetTabInfo().GetXclTab( nScTab );
+ }
+ return xExtSheet;
+}
+
+XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
+ sal_uInt16& rnExtSheet, sal_Unicode cCode )
+{
+ XclExpExtSheetRef xExtSheet;
+ XclExpCodeMap::const_iterator aIt = maCodeMap.find( cCode );
+ if( aIt == maCodeMap.end() )
+ {
+ xExtSheet.reset( new XclExpExternSheet( GetRoot(), cCode ) );
+ rnExtSheet = maCodeMap[ cCode ] = AppendInternal( xExtSheet );
+ }
+ else
+ {
+ rnExtSheet = aIt->second;
+ xExtSheet = GetInternal( rnExtSheet );
+ }
+ return xExtSheet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot& rRoot ) :
+ XclExpLinkManagerImpl( rRoot ),
+ maSBBuffer( rRoot )
+{
+}
+
+void XclExpLinkManagerImpl8::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+ rnFirstXclTab = rTabInfo.GetXclTab( nFirstScTab );
+ rnLastXclTab = rTabInfo.GetXclTab( nLastScTab );
+ rnExtSheet = InsertXti( maSBBuffer.GetXti( rnFirstXclTab, rnLastXclTab, pRefLogEntry ) );
+}
+
+sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
+{
+ (void)cCode; // avoid compiler warning
+ DBG_ASSERT( (cCode == EXC_EXTSH_OWNDOC) || (cCode == EXC_EXTSH_ADDIN),
+ "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
+ return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+}
+
+void XclExpLinkManagerImpl8::FindExtSheet(
+ sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
+ rnExtSheet = InsertXti(aXti);
+ rnFirstSBTab = aXti.mnFirstSBTab;
+ rnLastSBTab = aXti.mnLastSBTab;
+}
+
+void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
+{
+ if( !rRef1.IsDeleted() && !rRef2.IsDeleted() && (rRef1.nTab >= 0) && (rRef2.nTab >= 0) )
+ {
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ SCTAB nFirstScTab = static_cast< SCTAB >( rRef1.nTab );
+ SCTAB nLastScTab = static_cast< SCTAB >( rRef2.nTab );
+ ScRange aRange(
+ static_cast< SCCOL >( rRef1.nCol ), static_cast< SCROW >( rRef1.nRow ), 0,
+ static_cast< SCCOL >( rRef2.nCol ), static_cast< SCROW >( rRef2.nRow ), 0 );
+ for( SCTAB nScTab = nFirstScTab; nScTab <= nLastScTab; ++nScTab )
+ {
+ if( rTabInfo.IsExternalTab( nScTab ) )
+ {
+ aRange.aStart.SetTab( nScTab );
+ aRange.aEnd.SetTab( nScTab );
+ maSBBuffer.StoreCellRange( aRange );
+ }
+ }
+ }
+}
+
+void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ ScAddress aAddr(rRef.nCol, rRef.nRow, rRef.nTab);
+ maSBBuffer.StoreCell(nFileId, rTabName, aAddr);
+}
+
+void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef1, const ScSingleRefData& rRef2 )
+{
+ ScRange aRange(static_cast<SCCOL>(rRef1.nCol), static_cast<SCROW>(rRef1.nRow), static_cast<SCTAB>(rRef1.nTab),
+ static_cast<SCCOL>(rRef2.nCol), static_cast<SCROW>(rRef2.nRow), static_cast<SCTAB>(rRef2.nTab));
+ maSBBuffer.StoreCellRange(nFileId, rTabName, aRange);
+}
+
+bool XclExpLinkManagerImpl8::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertAddIn( nSupbook, rnExtName, rName ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl8::InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertEuroTool( nSupbook, rnExtName, rName ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+
+bool XclExpLinkManagerImpl8::InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertDde( nSupbook, rnExtName, rApplic, rTopic, rItem ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName, const String& rUrl, const ScExternalRefCache::TokenArrayRef pArray )
+{
+ sal_uInt16 nSupbook;
+ if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, pArray ) )
+ {
+ rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
+ return true;
+ }
+ return false;
+}
+
+void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
+{
+ if( !maXtiVec.empty() )
+ {
+ // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
+ maSBBuffer.Save( rStrm );
+
+ // EXTERNSHEET
+ sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXtiVec.size() );
+ rStrm.StartRecord( EXC_ID_EXTERNSHEET, 2 + 6 * nCount );
+ rStrm << nCount;
+ rStrm.SetSliceSize( 6 );
+ for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
+ aIt->Save( rStrm );
+ rStrm.EndRecord();
+ }
+}
+
+sal_uInt16 XclExpLinkManagerImpl8::InsertXti( const XclExpXti& rXti )
+{
+ for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
+ if( *aIt == rXti )
+ return ulimit_cast< sal_uInt16 >( aIt - maXtiVec.begin() );
+ maXtiVec.push_back( rXti );
+ return ulimit_cast< sal_uInt16 >( maXtiVec.size() - 1 );
+}
+
+// ============================================================================
+
+XclExpLinkManager::XclExpLinkManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ mxImpl.reset( new XclExpLinkManagerImpl5( rRoot ) );
+ break;
+ case EXC_BIFF8:
+ mxImpl.reset( new XclExpLinkManagerImpl8( rRoot ) );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+XclExpLinkManager::~XclExpLinkManager()
+{
+}
+
+void XclExpLinkManager::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab,
+ SCTAB nScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( rnExtSheet, rnXclTab, rnXclTab, nScTab, nScTab, pRefLogEntry );
+}
+
+void XclExpLinkManager::FindExtSheet(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( rnExtSheet, rnFirstXclTab, rnLastXclTab, nFirstScTab, nLastScTab, pRefLogEntry );
+}
+
+sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
+{
+ return mxImpl->FindExtSheet( cCode );
+}
+
+void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry )
+{
+ mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
+}
+
+void XclExpLinkManager::StoreCell( const ScSingleRefData& rRef )
+{
+ mxImpl->StoreCellRange( rRef, rRef );
+}
+
+void XclExpLinkManager::StoreCellRange( const ScComplexRefData& rRef )
+{
+ mxImpl->StoreCellRange( rRef.Ref1, rRef.Ref2 );
+}
+
+void XclExpLinkManager::StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
+{
+ mxImpl->StoreCell( nFileId, rTabName, rRef );
+}
+
+void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
+{
+ mxImpl->StoreCellRange( nFileId, rTabName, rRef.Ref1, rRef.Ref2 );
+}
+
+bool XclExpLinkManager::InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ return mxImpl->InsertAddIn( rnExtSheet, rnExtName, rName );
+}
+
+bool XclExpLinkManager::InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
+{
+ return mxImpl->InsertEuroTool( rnExtSheet, rnExtName, rName );
+}
+
+bool XclExpLinkManager::InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem )
+{
+ return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
+}
+
+bool XclExpLinkManager::InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName, const String& rUrl,
+ const ScExternalRefCache::TokenArrayRef pArray )
+{
+ return mxImpl->InsertExtName( rnExtSheet, rnExtName, rUrl, rName, pArray );
+}
+
+void XclExpLinkManager::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xename.cxx b/sc/source/filter/excel/xename.cxx
new file mode 100644
index 000000000000..69377c5d06f4
--- /dev/null
+++ b/sc/source/filter/excel/xename.cxx
@@ -0,0 +1,767 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xename.hxx"
+
+#include <map>
+
+#include "globstr.hrc"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "xehelper.hxx"
+#include "xelink.hxx"
+#include "globalnames.hxx"
+
+// for filter manager
+#include "excrecds.hxx"
+
+#include <formula/grammar.hxx>
+
+using namespace ::oox;
+
+using ::rtl::OString;
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+/** Represents an internal defined name, supports writing it to a NAME record. */
+class XclExpName : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Creates a standard defined name. */
+ explicit XclExpName( const XclExpRoot& rRoot, const String& rName );
+ /** Creates a built-in defined name. */
+ explicit XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn );
+
+ /** Sets a token array containing the definition of this name. */
+ void SetTokenArray( XclTokenArrayRef xTokArr );
+ /** Changes this defined name to be local on the specified Calc sheet. */
+ void SetLocalTab( SCTAB nScTab );
+ /** Hides or unhides the defined name. */
+ void SetHidden( bool bHidden = true );
+ /** Changes this name to be the call to a VB macro function or procedure.
+ @param bVBasic true = Visual Basic macro, false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ void SetMacroCall( bool bVBasic, bool bFunc );
+
+
+ /** Sets the name's symbol value
+ @param sValue the name's symbolic value */
+ void SetSymbol( String sValue );
+ /** Returns the name's symbol value */
+ inline const String& GetSymbol() const { return msSymbol; }
+
+ /** Returns the original name (title) of this defined name. */
+ inline const String& GetOrigName() const { return maOrigName; }
+ /** Returns the Excel built-in name index of this defined name.
+ @return The built-in name index or EXC_BUILTIN_UNKNOWN for user-defined names. */
+ inline sal_Unicode GetBuiltInName() const { return mcBuiltIn; }
+
+ /** Returns the token array for this defined name. */
+ inline XclTokenArrayRef GetTokenArray() const { return mxTokArr; }
+
+ /** Returns true, if this is a document-global defined name. */
+ inline bool IsGlobal() const { return mnXclTab == EXC_NAME_GLOBAL; }
+ /** Returns the Calc sheet of a local defined name. */
+ inline SCTAB GetScTab() const { return mnScTab; }
+
+ /** Returns true, if this defined name is volatile. */
+ bool IsVolatile() const;
+ /** Returns true, if this defined name is hidden. */
+ bool IsHidden() const;
+ /** Returns true, if this defined name describes a macro call.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ bool IsMacroCall( bool bVBasic, bool bFunc ) const;
+
+ /** Writes the entire NAME record to the passed stream. */
+ virtual void Save( XclExpStream& rStrm );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the NAME record to the passed stream. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maOrigName; /// The original user-defined name.
+ String msSymbol; /// The value of the symbol
+ XclExpStringRef mxName; /// The name as Excel string object.
+ XclTokenArrayRef mxTokArr; /// The definition of the defined name.
+ sal_Unicode mcBuiltIn; /// The built-in index for built-in names.
+ SCTAB mnScTab; /// The Calc sheet index for local names.
+ sal_uInt16 mnFlags; /// Additional flags for this defined name.
+ sal_uInt16 mnExtSheet; /// The 1-based index to a global EXTERNSHEET record.
+ sal_uInt16 mnXclTab; /// The 1-based Excel sheet index for local names.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScRangeData;
+class ScDBData;
+
+/** Implementation class of the name manager. */
+class XclExpNameManagerImpl : protected XclExpRoot
+{
+public:
+ explicit XclExpNameManagerImpl( const XclExpRoot& rRoot );
+
+ /** Creates NAME records for built-in and user defined names. */
+ void Initialize();
+
+ /** Inserts the Calc name with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertName( SCTAB nTab, sal_uInt16 nScNameIdx );
+
+ /** Inserts a new built-in defined name. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, const ScRange& aRange );
+ /** Inserts a new defined name. Sets another unused name, if rName already exists. */
+ sal_uInt16 InsertUniqueName( const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Returns index of an existing name, or creates a name without definition. */
+ sal_uInt16 InsertRawName( const String& rName );
+ /** Searches or inserts a defined name describing a macro name.
+ @param bVBasic true = Visual Basic macro; false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ sal_uInt16 InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden );
+
+ /** Returns the NAME record at the specified position or 0 on error. */
+ const XclExpName* GetName( sal_uInt16 nNameIdx ) const;
+
+ /** Writes the entire list of NAME records.
+ @descr In BIFF7 and lower, writes the entire global link table, which
+ consists of an EXTERNCOUNT record, several EXTERNSHEET records, and
+ the list of NAME records. */
+ void Save( XclExpStream& rStrm );
+
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpName > XclExpNameList;
+ typedef XclExpNameList::RecordRefType XclExpNameRef;
+ typedef ::std::map< sal_uInt16, sal_uInt16 > XclExpIndexMap;
+
+ typedef ::std::map< ::std::pair<SCTAB, sal_uInt16>, sal_uInt16> NamedExpIndexMap;
+
+private:
+ /**
+ * @param nTab 0-based table index, or SCTAB_GLOBAL for global names.
+ * @param nScIdx calc's name index.
+ *
+ * @return excel's name index.
+ */
+ sal_uInt16 FindNamedExpIndex( SCTAB nTab, sal_uInt16 nScIdx );
+
+ /** Returns the index of an existing built-in NAME record with the passed definition, otherwise 0. */
+ sal_uInt16 FindBuiltInNameIdx( const String& rName,
+ const XclTokenArray& rTokArr, bool bDBRange ) const;
+ /** Returns an unused name for the passed name. */
+ String GetUnusedName( const String& rName ) const;
+
+ /** Appends a new NAME record to the record list.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 Append( XclExpNameRef xName );
+ /** Creates a new NAME record for the passed user-defined name.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 CreateName( SCTAB nTab, const ScRangeData& rRangeData );
+ /** Creates a new NAME record for the passed database range.
+ @return The 1-based NAME record index used elsewhere in the Excel file. */
+ sal_uInt16 CreateName( const ScDBData& rDBData );
+
+ /** Creates NAME records for all built-in names in the document. */
+ void CreateBuiltInNames();
+ /** Creates NAME records for all user-defined names in the document. */
+ void CreateUserNames();
+
+private:
+ /**
+ * Maps Calc's named range to Excel's NAME records. Global names use
+ * -1 as their table index, whereas sheet-local names have 0-based table
+ * index.
+ */
+ NamedExpIndexMap maNamedExpMap;
+ XclExpNameList maNameList; /// List of NAME records.
+ size_t mnFirstUserIdx; /// List index of first user-defined NAME record.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+XclExpName::XclExpName( const XclExpRoot& rRoot, const String& rName ) :
+ XclExpRecord( EXC_ID_NAME ),
+ XclExpRoot( rRoot ),
+ maOrigName( rName ),
+ mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
+ mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
+ mnScTab( SCTAB_GLOBAL ),
+ mnFlags( EXC_NAME_DEFAULT ),
+ mnExtSheet( EXC_NAME_GLOBAL ),
+ mnXclTab( EXC_NAME_GLOBAL )
+{
+}
+
+XclExpName::XclExpName( const XclExpRoot& rRoot, sal_Unicode cBuiltIn ) :
+ XclExpRecord( EXC_ID_NAME ),
+ XclExpRoot( rRoot ),
+ mcBuiltIn( cBuiltIn ),
+ mnScTab( SCTAB_GLOBAL ),
+ mnFlags( EXC_NAME_DEFAULT ),
+ mnExtSheet( EXC_NAME_GLOBAL ),
+ mnXclTab( EXC_NAME_GLOBAL )
+{
+ // filter source range is hidden in Excel
+ if( cBuiltIn == EXC_BUILTIN_FILTERDATABASE )
+ SetHidden();
+
+ // special case for BIFF5/7 filter source range - name appears as plain text without built-in flag
+ if( (GetBiff() <= EXC_BIFF5) && (cBuiltIn == EXC_BUILTIN_FILTERDATABASE) )
+ {
+ String aName( XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE ) );
+ mxName = XclExpStringHelper::CreateString( rRoot, aName, EXC_STR_8BITLENGTH );
+ maOrigName = XclTools::GetXclBuiltInDefName( cBuiltIn );
+ }
+ else
+ {
+ maOrigName = XclTools::GetBuiltInDefNameXml( cBuiltIn ) ;
+ mxName = XclExpStringHelper::CreateString( rRoot, cBuiltIn, EXC_STR_8BITLENGTH );
+ ::set_flag( mnFlags, EXC_NAME_BUILTIN );
+ }
+}
+
+void XclExpName::SetTokenArray( XclTokenArrayRef xTokArr )
+{
+ mxTokArr = xTokArr;
+}
+
+void XclExpName::SetLocalTab( SCTAB nScTab )
+{
+ DBG_ASSERT( GetTabInfo().IsExportTab( nScTab ), "XclExpName::SetLocalTab - invalid sheet index" );
+ if( GetTabInfo().IsExportTab( nScTab ) )
+ {
+ mnScTab = nScTab;
+ GetGlobalLinkManager().FindExtSheet( mnExtSheet, mnXclTab, nScTab );
+
+ // special handling for NAME record
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: // EXTERNSHEET index is positive in NAME record
+ mnExtSheet = ~mnExtSheet + 1;
+ break;
+ case EXC_BIFF8: // EXTERNSHEET index not used, but must be created in link table
+ mnExtSheet = 0;
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ // Excel sheet index is 1-based
+ ++mnXclTab;
+ }
+}
+
+void XclExpName::SetHidden( bool bHidden )
+{
+ ::set_flag( mnFlags, EXC_NAME_HIDDEN, bHidden );
+}
+
+void XclExpName::SetMacroCall( bool bVBasic, bool bFunc )
+{
+ ::set_flag( mnFlags, EXC_NAME_PROC );
+ ::set_flag( mnFlags, EXC_NAME_VB, bVBasic );
+ ::set_flag( mnFlags, EXC_NAME_FUNC, bFunc );
+}
+
+void XclExpName::SetSymbol( String sSymbol )
+{
+ msSymbol = sSymbol;
+}
+
+bool XclExpName::IsVolatile() const
+{
+ return mxTokArr && mxTokArr->IsVolatile();
+}
+
+bool XclExpName::IsHidden() const
+{
+ return ::get_flag( mnFlags, EXC_NAME_HIDDEN );
+}
+
+bool XclExpName::IsMacroCall( bool bVBasic, bool bFunc ) const
+{
+ return
+ (::get_flag( mnFlags, EXC_NAME_VB ) == bVBasic) &&
+ (::get_flag( mnFlags, EXC_NAME_FUNC ) == bFunc);
+}
+
+void XclExpName::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mxName && (mxName->Len() > 0), "XclExpName::Save - missing name" );
+ DBG_ASSERT( !(IsGlobal() && ::get_flag( mnFlags, EXC_NAME_BUILTIN )), "XclExpName::Save - global built-in name" );
+ SetRecSize( 11 + mxName->GetSize() + (mxTokArr ? mxTokArr->GetSize() : 2) );
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpName::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_definedName,
+ // OOXTODO: XML_comment, "",
+ // OOXTODO: XML_customMenu, "",
+ // OOXTODO: XML_description, "",
+ XML_function, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
+ // OOXTODO: XML_functionGroupId, "",
+ // OOXTODO: XML_help, "",
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_HIDDEN ) ),
+ XML_localSheetId, mnScTab == SCTAB_GLOBAL ? NULL : OString::valueOf( (sal_Int32)mnScTab ).getStr(),
+ XML_name, XclXmlUtils::ToOString( maOrigName ).getStr(),
+ // OOXTODO: XML_publishToServer, "",
+ // OOXTODO: XML_shortcutKey, "",
+ // OOXTODO: XML_statusBar, "",
+ XML_vbProcedure, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_NAME_VB ) ),
+ // OOXTODO: XML_workbookParameter, "",
+ // OOXTODO: XML_xlm, "",
+ FSEND );
+ rWorkbook->writeEscaped( XclXmlUtils::ToOUString( msSymbol ) );
+ rWorkbook->endElement( XML_definedName );
+}
+
+void XclExpName::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nFmlaSize = mxTokArr ? mxTokArr->GetSize() : 0;
+
+ rStrm << mnFlags // flags
+ << sal_uInt8( 0 ); // keyboard shortcut
+ mxName->WriteLenField( rStrm ); // length of name
+ rStrm << nFmlaSize // size of token array
+ << mnExtSheet // BIFF5/7: EXTSHEET index, BIFF8: not used
+ << mnXclTab // 1-based sheet index for local names
+ << sal_uInt32( 0 ); // length of menu/descr/help/status text
+ mxName->WriteFlagField( rStrm ); // BIFF8 flag field (no-op in <=BIFF7)
+ mxName->WriteBuffer( rStrm ); // character array of the name
+ if( mxTokArr )
+ mxTokArr->WriteArray( rStrm ); // token array without size
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpNameManagerImpl::XclExpNameManagerImpl( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnFirstUserIdx( 0 )
+{
+}
+
+void XclExpNameManagerImpl::Initialize()
+{
+ CreateBuiltInNames();
+ mnFirstUserIdx = maNameList.GetSize();
+ CreateUserNames();
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertName( SCTAB nTab, sal_uInt16 nScNameIdx )
+{
+ sal_uInt16 nNameIdx = FindNamedExpIndex( nTab, nScNameIdx );
+ if (nNameIdx)
+ return nNameIdx;
+
+ const ScRangeData* pData = NULL;
+ ScRangeName* pRN = (nTab == SCTAB_GLOBAL) ? GetDoc().GetRangeName() : GetDoc().GetRangeName(nTab);
+ if (pRN)
+ pData = pRN->findByIndex(nScNameIdx);
+
+ if (pData)
+ nNameIdx = CreateName(nTab, *pData);
+
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, const ScRange& aRange )
+{
+ XclExpNameRef xName( new XclExpName( GetRoot(), cBuiltIn ) );
+ xName->SetTokenArray( xTokArr );
+ xName->SetLocalTab( aRange.aStart.Tab() );
+ String sSymbol;
+ aRange.Format( sSymbol, SCR_ABS_3D, GetDocPtr(), ScAddress::Details( ::formula::FormulaGrammar::CONV_XL_A1 ) );
+ xName->SetSymbol( sSymbol );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertBuiltInName( sal_Unicode cBuiltIn, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ XclExpNameRef xName( new XclExpName( GetRoot(), cBuiltIn ) );
+ xName->SetTokenArray( xTokArr );
+ xName->SetLocalTab( nScTab );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertUniqueName(
+ const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ DBG_ASSERT( rName.Len(), "XclExpNameManagerImpl::InsertUniqueName - empty name" );
+ XclExpNameRef xName( new XclExpName( GetRoot(), GetUnusedName( rName ) ) );
+ xName->SetTokenArray( xTokArr );
+ xName->SetLocalTab( nScTab );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertRawName( const String& rName )
+{
+ // empty name? may occur in broken external Calc tokens
+ if( !rName.Len() )
+ return 0;
+
+ // try to find an existing NAME record, regardless of its type
+ for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nListIdx );
+ if( xName->IsGlobal() && (xName->GetOrigName() == rName) )
+ return static_cast< sal_uInt16 >( nListIdx + 1 );
+ }
+
+ // create a new NAME record
+ XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
+ return Append( xName );
+}
+
+sal_uInt16 XclExpNameManagerImpl::InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
+{
+ // empty name? may occur in broken external Calc tokens
+ if( !rMacroName.Len() )
+ return 0;
+
+ // try to find an existing NAME record
+ for( size_t nListIdx = mnFirstUserIdx, nListSize = maNameList.GetSize(); nListIdx < nListSize; ++nListIdx )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nListIdx );
+ if( xName->IsMacroCall( bVBasic, bFunc ) && (xName->GetOrigName() == rMacroName) )
+ return static_cast< sal_uInt16 >( nListIdx + 1 );
+ }
+
+ // create a new NAME record
+ XclExpNameRef xName( new XclExpName( GetRoot(), rMacroName ) );
+ xName->SetMacroCall( bVBasic, bFunc );
+ xName->SetHidden( bHidden );
+
+ // for sheet macros, add a #NAME! error
+ if( !bVBasic )
+ xName->SetTokenArray( GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NAME ) );
+
+ return Append( xName );
+}
+
+const XclExpName* XclExpNameManagerImpl::GetName( sal_uInt16 nNameIdx ) const
+{
+ DBG_ASSERT( maNameList.HasRecord( nNameIdx - 1 ), "XclExpNameManagerImpl::GetName - wrong record index" );
+ return maNameList.GetRecord( nNameIdx - 1 ).get();
+}
+
+void XclExpNameManagerImpl::Save( XclExpStream& rStrm )
+{
+ maNameList.Save( rStrm );
+}
+
+void XclExpNameManagerImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maNameList.IsEmpty() )
+ return;
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_definedNames, FSEND );
+ maNameList.SaveXml( rStrm );
+ rWorkbook->endElement( XML_definedNames );
+}
+
+// private --------------------------------------------------------------------
+
+sal_uInt16 XclExpNameManagerImpl::FindNamedExpIndex( SCTAB nTab, sal_uInt16 nScIdx )
+{
+ NamedExpIndexMap::key_type key = NamedExpIndexMap::key_type(nTab, nScIdx);
+ NamedExpIndexMap::const_iterator itr = maNamedExpMap.find(key);
+ return (itr == maNamedExpMap.end()) ? 0 : itr->second;
+}
+
+sal_uInt16 XclExpNameManagerImpl::FindBuiltInNameIdx(
+ const String& rName, const XclTokenArray& rTokArr, bool bDBRange ) const
+{
+ /* Get built-in index from the name. Special case: the database range
+ 'unnamed' will be mapped to Excel's built-in '_FilterDatabase' name. */
+ sal_Unicode cBuiltIn = (bDBRange && (rName == String(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)))) ?
+ EXC_BUILTIN_FILTERDATABASE : XclTools::GetBuiltInDefNameIndex( rName );
+
+ if( cBuiltIn < EXC_BUILTIN_UNKNOWN )
+ {
+ // try to find the record in existing built-in NAME record list
+ for( size_t nPos = 0; nPos < mnFirstUserIdx; ++nPos )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nPos );
+ if( xName->GetBuiltInName() == cBuiltIn )
+ {
+ XclTokenArrayRef xTokArr = xName->GetTokenArray();
+ if( xTokArr && (*xTokArr == rTokArr) )
+ return static_cast< sal_uInt16 >( nPos + 1 );
+ }
+ }
+ }
+ return 0;
+}
+
+String XclExpNameManagerImpl::GetUnusedName( const String& rName ) const
+{
+ String aNewName( rName );
+ sal_Int32 nAppIdx = 0;
+ bool bExist = true;
+ while( bExist )
+ {
+ // search the list of user-defined names
+ bExist = false;
+ for( size_t nPos = mnFirstUserIdx, nSize = maNameList.GetSize(); !bExist && (nPos < nSize); ++nPos )
+ {
+ XclExpNameRef xName = maNameList.GetRecord( nPos );
+ bExist = xName->GetOrigName() == aNewName;
+ // name exists -> create a new name "<originalname>_<counter>"
+ if( bExist )
+ aNewName.Assign( rName ).Append( '_' ).Append( String::CreateFromInt32( ++nAppIdx ) );
+ }
+ }
+ return aNewName;
+}
+
+sal_uInt16 XclExpNameManagerImpl::Append( XclExpNameRef xName )
+{
+ if( maNameList.GetSize() == 0xFFFF )
+ return 0;
+ maNameList.AppendRecord( xName );
+ return static_cast< sal_uInt16 >( maNameList.GetSize() ); // 1-based
+}
+
+sal_uInt16 XclExpNameManagerImpl::CreateName( SCTAB nTab, const ScRangeData& rRangeData )
+{
+ const String& rName = rRangeData.GetName();
+
+ /* #i38821# recursive names: first insert the (empty) name object,
+ otherwise a recursive call of this function from the formula compiler
+ with the same defined name will not find it and will create it again. */
+ size_t nOldListSize = maNameList.GetSize();
+ XclExpNameRef xName( new XclExpName( GetRoot(), rName ) );
+ if (nTab != SCTAB_GLOBAL)
+ xName->SetLocalTab(nTab);
+ sal_uInt16 nNameIdx = Append( xName );
+ // store the index of the NAME record in the lookup map
+ NamedExpIndexMap::key_type key = NamedExpIndexMap::key_type(nTab, rRangeData.GetIndex());
+ maNamedExpMap[key] = nNameIdx;
+
+ /* Create the definition formula.
+ This may cause recursive creation of other defined names. */
+ if( const ScTokenArray* pScTokArr = const_cast< ScRangeData& >( rRangeData ).GetCode() )
+ {
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, *pScTokArr );
+ xName->SetTokenArray( xTokArr );
+
+ String sSymbol;
+ rRangeData.GetSymbol( sSymbol, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1 );
+ xName->SetSymbol( sSymbol );
+
+ /* Try to replace by existing built-in name - complete token array is
+ needed for comparison, and due to the recursion problem above this
+ cannot be done earlier. If a built-in name is found, the created NAME
+ record for this name and all following records in the list must be
+ deleted, otherwise they may contain wrong name list indexes. */
+ sal_uInt16 nBuiltInIdx = FindBuiltInNameIdx( rName, *xTokArr, false );
+ if( nBuiltInIdx != 0 )
+ {
+ // delete the new NAME records
+ while( maNameList.GetSize() > nOldListSize )
+ maNameList.RemoveRecord( maNameList.GetSize() - 1 );
+ // use index of the found built-in NAME record
+ key = NamedExpIndexMap::key_type(nTab, rRangeData.GetIndex());
+ maNamedExpMap[key] = nNameIdx = nBuiltInIdx;
+ }
+ }
+
+ return nNameIdx;
+}
+
+void XclExpNameManagerImpl::CreateBuiltInNames()
+{
+ ScDocument& rDoc = GetDoc();
+ XclExpTabInfo& rTabInfo = GetTabInfo();
+
+ /* #i2394# built-in defined names must be sorted by the name of the
+ containing sheet. Example: SheetA!Print_Range must be stored *before*
+ SheetB!Print_Range, regardless of the position of SheetA in the document! */
+ for( SCTAB nScTabIdx = 0, nScTabCount = rTabInfo.GetScTabCount(); nScTabIdx < nScTabCount; ++nScTabIdx )
+ {
+ // find real sheet index from the nScTabIdx counter
+ SCTAB nScTab = rTabInfo.GetRealScTab( nScTabIdx );
+ // create NAME records for all built-in names of this sheet
+ if( rTabInfo.IsExportTab( nScTab ) )
+ {
+ // *** 1) print ranges *** ----------------------------------------
+
+ if( rDoc.HasPrintRange() )
+ {
+ ScRangeList aRangeList;
+ for( sal_uInt16 nIdx = 0, nCount = rDoc.GetPrintRangeCount( nScTab ); nIdx < nCount; ++nIdx )
+ {
+ ScRange aRange( *rDoc.GetPrintRange( nScTab, nIdx ) );
+ // Calc document does not care about sheet index in print ranges
+ aRange.aStart.SetTab( nScTab );
+ aRange.aEnd.SetTab( nScTab );
+ aRange.Justify();
+ aRangeList.Append( aRange );
+ }
+ // create the NAME record (do not warn if ranges are shrunken)
+ GetAddressConverter().ValidateRangeList( aRangeList, false );
+ if( !aRangeList.empty() )
+ GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTAREA, aRangeList );
+ }
+
+ // *** 2) print titles *** ----------------------------------------
+
+ ScRangeList aTitleList;
+ // repeated columns
+ if( const ScRange* pColRange = rDoc.GetRepeatColRange( nScTab ) )
+ aTitleList.Append( ScRange(
+ pColRange->aStart.Col(), 0, nScTab,
+ pColRange->aEnd.Col(), GetXclMaxPos().Row(), nScTab ) );
+ // repeated rows
+ if( const ScRange* pRowRange = rDoc.GetRepeatRowRange( nScTab ) )
+ aTitleList.Append( ScRange(
+ 0, pRowRange->aStart.Row(), nScTab,
+ GetXclMaxPos().Col(), pRowRange->aEnd.Row(), nScTab ) );
+ // create the NAME record
+ GetAddressConverter().ValidateRangeList( aTitleList, false );
+ if( !aTitleList.empty() )
+ GetNameManager().InsertBuiltInName( EXC_BUILTIN_PRINTTITLES, aTitleList );
+
+ // *** 3) filter ranges *** ---------------------------------------
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetFilterManager().InitTabFilter( nScTab );
+ }
+ }
+}
+
+void XclExpNameManagerImpl::CreateUserNames()
+{
+ const ScRangeName& rNamedRanges = GetNamedRanges();
+ ScRangeName::const_iterator itr = rNamedRanges.begin(), itrEnd = rNamedRanges.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ // skip definitions of shared formulas
+ if (!itr->HasType(RT_SHARED) && !FindNamedExpIndex(SCTAB_GLOBAL, itr->GetIndex()))
+ CreateName(SCTAB_GLOBAL, *itr);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpNameManager::XclExpNameManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mxImpl( new XclExpNameManagerImpl( rRoot ) )
+{
+}
+
+XclExpNameManager::~XclExpNameManager()
+{
+}
+
+void XclExpNameManager::Initialize()
+{
+ mxImpl->Initialize();
+}
+
+sal_uInt16 XclExpNameManager::InsertName( SCTAB nTab, sal_uInt16 nScNameIdx )
+{
+ return mxImpl->InsertName( nTab, nScNameIdx );
+}
+
+sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRange& rRange )
+{
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRange );
+ return mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRange );
+}
+
+sal_uInt16 XclExpNameManager::InsertBuiltInName( sal_Unicode cBuiltIn, const ScRangeList& rRangeList )
+{
+ sal_uInt16 nNameIdx = 0;
+ if( !rRangeList.empty() )
+ {
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_NAME, rRangeList );
+ nNameIdx = mxImpl->InsertBuiltInName( cBuiltIn, xTokArr, rRangeList.front()->aStart.Tab() );
+ }
+ return nNameIdx;
+}
+
+sal_uInt16 XclExpNameManager::InsertUniqueName(
+ const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab )
+{
+ return mxImpl->InsertUniqueName( rName, xTokArr, nScTab );
+}
+
+sal_uInt16 XclExpNameManager::InsertRawName( const String& rName )
+{
+ return mxImpl->InsertRawName( rName );
+}
+
+sal_uInt16 XclExpNameManager::InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden )
+{
+ return mxImpl->InsertMacroCall( rMacroName, bVBasic, bFunc, bHidden );
+}
+
+const String& XclExpNameManager::GetOrigName( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName ? pName->GetOrigName() : EMPTY_STRING;
+}
+
+SCTAB XclExpNameManager::GetScTab( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName ? pName->GetScTab() : SCTAB_GLOBAL;
+}
+
+bool XclExpNameManager::IsVolatile( sal_uInt16 nNameIdx ) const
+{
+ const XclExpName* pName = mxImpl->GetName( nNameIdx );
+ return pName && pName->IsVolatile();
+}
+
+void XclExpNameManager::Save( XclExpStream& rStrm )
+{
+ mxImpl->Save( rStrm );
+}
+
+void XclExpNameManager::SaveXml( XclExpXmlStream& rStrm )
+{
+ mxImpl->SaveXml( rStrm );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xepage.cxx b/sc/source/filter/excel/xepage.cxx
new file mode 100644
index 000000000000..3831bc7822ac
--- /dev/null
+++ b/sc/source/filter/excel/xepage.cxx
@@ -0,0 +1,436 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xepage.hxx"
+#include <svl/itemset.hxx>
+#include "scitems.hxx"
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "attrib.hxx"
+#include "xehelper.hxx"
+#include "xeescher.hxx"
+
+#include <set>
+#include <limits>
+
+using namespace ::oox;
+
+using ::rtl::OString;
+using ::std::set;
+using ::std::numeric_limits;
+
+// Page settings records ======================================================
+
+// Header/footer --------------------------------------------------------------
+
+XclExpHeaderFooter::XclExpHeaderFooter( sal_uInt16 nRecId, const String& rHdrString ) :
+ XclExpRecord( nRecId ),
+ maHdrString( rHdrString )
+{
+}
+
+void XclExpHeaderFooter::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ sal_Int32 nElement = GetRecId() == EXC_ID_HEADER ? XML_oddHeader : XML_oddFooter;
+ rWorksheet->startElement( nElement, FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( maHdrString ) );
+ rWorksheet->endElement( nElement );
+}
+
+void XclExpHeaderFooter::WriteBody( XclExpStream& rStrm )
+{
+ if( maHdrString.Len() )
+ {
+ XclExpString aExString;
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ aExString.AssignByte( maHdrString, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aExString.Assign( maHdrString, EXC_STR_DEFAULT, 255 ); // 16-bit length, but max 255 chars
+ rStrm << aExString;
+ }
+}
+
+// General page settings ------------------------------------------------------
+
+XclExpSetup::XclExpSetup( const XclPageData& rPageData ) :
+ XclExpRecord( EXC_ID_SETUP, 34 ),
+ mrData( rPageData )
+{
+}
+
+void XclExpSetup::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FastAttributeList* pAttrList=rStrm.GetCurrentStream()->createAttrList();
+ if( rStrm.getVersion() != oox::core::ISOIEC_29500_2008 ||
+ mrData.mnStrictPaperSize != EXC_PAPERSIZE_USER )
+ {
+ pAttrList->add( XML_paperSize, OString::valueOf( (sal_Int32) mrData.mnPaperSize ).getStr() );
+ }
+ else
+ {
+ pAttrList->add( XML_paperWidth, OString::valueOf( (sal_Int32) mrData.mnPaperWidth ).concat(OString("mm")).getStr() );
+ pAttrList->add( XML_paperHeight, OString::valueOf( (sal_Int32) mrData.mnPaperHeight ).concat(OString("mm")).getStr() );
+ // pAttrList->add( XML_paperUnits, "mm" );
+ }
+ pAttrList->add( XML_scale, OString::valueOf( (sal_Int32) mrData.mnScaling ).getStr() );
+ pAttrList->add( XML_firstPageNumber, OString::valueOf( (sal_Int32) mrData.mnStartPage ).getStr() );
+ pAttrList->add( XML_fitToWidth, OString::valueOf( (sal_Int32) mrData.mnFitToWidth ).getStr() );
+ pAttrList->add( XML_fitToHeight, OString::valueOf( (sal_Int32) mrData.mnFitToHeight ).getStr() );
+ pAttrList->add( XML_pageOrder, mrData.mbPrintInRows ? "overThenDown" : "downThenOver" );
+ pAttrList->add( XML_orientation, mrData.mbPortrait ? "portrait" : "landscape" ); // OOXTODO: "default"?
+ pAttrList->add( XML_usePrinterDefaults, XclXmlUtils::ToPsz( !mrData.mbValid ) );
+ pAttrList->add( XML_blackAndWhite, XclXmlUtils::ToPsz( mrData.mbBlackWhite ) );
+ pAttrList->add( XML_draft, XclXmlUtils::ToPsz( mrData.mbDraftQuality ) );
+ pAttrList->add( XML_cellComments, mrData.mbPrintNotes ? "atEnd" : "none" ); // OOXTODO: "asDisplayed"?
+ pAttrList->add( XML_useFirstPageNumber, XclXmlUtils::ToPsz( mrData.mbManualStart ) );
+ // OOXTODO: XML_errors, // == displayed|blank|dash|NA
+ pAttrList->add( XML_horizontalDpi, OString::valueOf( (sal_Int32) mrData.mnHorPrintRes ).getStr() );
+ pAttrList->add( XML_verticalDpi, OString::valueOf( (sal_Int32) mrData.mnVerPrintRes ).getStr() );
+ pAttrList->add( XML_copies, OString::valueOf( (sal_Int32) mrData.mnCopies ).getStr() );
+ // OOXTODO: devMode settings part RelationshipId: FSNS( XML_r, XML_id ),
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList > aAttrs(pAttrList);
+ rStrm.GetCurrentStream()->singleElement( XML_pageSetup, aAttrs );
+}
+
+void XclExpSetup::WriteBody( XclExpStream& rStrm )
+{
+ XclBiff eBiff = rStrm.GetRoot().GetBiff();
+
+ sal_uInt16 nFlags = 0;
+ ::set_flag( nFlags, EXC_SETUP_INROWS, mrData.mbPrintInRows );
+ ::set_flag( nFlags, EXC_SETUP_PORTRAIT, mrData.mbPortrait );
+ ::set_flag( nFlags, EXC_SETUP_INVALID, !mrData.mbValid );
+ ::set_flag( nFlags, EXC_SETUP_BLACKWHITE, mrData.mbBlackWhite );
+ if( eBiff >= EXC_BIFF5 )
+ {
+ ::set_flag( nFlags, EXC_SETUP_DRAFT, mrData.mbDraftQuality );
+ /* Set the Comments/Notes to "At end of sheet" if Print Notes is true.
+ We don't currently support "as displayed on sheet". Thus this value
+ will be re-interpreted to "At end of sheet". */
+ const sal_uInt16 nNotes = EXC_SETUP_PRINTNOTES | EXC_SETUP_NOTES_END;
+ ::set_flag( nFlags, nNotes, mrData.mbPrintNotes );
+ ::set_flag( nFlags, EXC_SETUP_STARTPAGE, mrData.mbManualStart );
+ }
+
+ rStrm << mrData.mnPaperSize << mrData.mnScaling << mrData.mnStartPage
+ << mrData.mnFitToWidth << mrData.mnFitToHeight << nFlags;
+ if( eBiff >= EXC_BIFF5 )
+ {
+ rStrm << mrData.mnHorPrintRes << mrData.mnVerPrintRes
+ << mrData.mfHeaderMargin << mrData.mfFooterMargin << mrData.mnCopies;
+ }
+}
+
+// Manual page breaks ---------------------------------------------------------
+
+XclExpPageBreaks::XclExpPageBreaks( sal_uInt16 nRecId, const ScfUInt16Vec& rPageBreaks, sal_uInt16 nMaxPos ) :
+ XclExpRecord( nRecId ),
+ mrPageBreaks( rPageBreaks ),
+ mnMaxPos( nMaxPos )
+{
+}
+
+void XclExpPageBreaks::Save( XclExpStream& rStrm )
+{
+ if( !mrPageBreaks.empty() )
+ {
+ SetRecSize( 2 + ((rStrm.GetRoot().GetBiff() <= EXC_BIFF5) ? 2 : 6) * mrPageBreaks.size() );
+ XclExpRecord::Save( rStrm );
+ }
+}
+
+void XclExpPageBreaks::WriteBody( XclExpStream& rStrm )
+{
+ bool bWriteRange = (rStrm.GetRoot().GetBiff() == EXC_BIFF8);
+
+ rStrm << static_cast< sal_uInt16 >( mrPageBreaks.size() );
+ for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ rStrm << *aIt;
+ if( bWriteRange )
+ rStrm << sal_uInt16( 0 ) << mnMaxPos;
+ }
+}
+
+void XclExpPageBreaks::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mrPageBreaks.empty() )
+ return;
+
+ sal_Int32 nElement = GetRecId() == EXC_ID_HORPAGEBREAKS ? XML_rowBreaks : XML_colBreaks;
+ sax_fastparser::FSHelperPtr& pWorksheet = rStrm.GetCurrentStream();
+ OString sNumPageBreaks = OString::valueOf( (sal_Int32) mrPageBreaks.size() );
+ pWorksheet->startElement( nElement,
+ XML_count, sNumPageBreaks.getStr(),
+ XML_manualBreakCount, sNumPageBreaks.getStr(),
+ FSEND );
+ for( ScfUInt16Vec::const_iterator aIt = mrPageBreaks.begin(), aEnd = mrPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ pWorksheet->singleElement( XML_brk,
+ XML_id, OString::valueOf( (sal_Int32) *aIt ).getStr(),
+ XML_man, "true",
+ XML_max, OString::valueOf( (sal_Int32) mnMaxPos ).getStr(),
+ XML_min, "0",
+ // OOXTODO: XML_pt, "",
+ FSEND );
+ }
+ pWorksheet->endElement( nElement );
+}
+
+// Page settings ==============================================================
+
+XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( rDoc.GetPageStyle( nScTab ), SFX_STYLE_FAMILY_PAGE ) )
+ {
+ const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
+ maData.mbValid = true;
+
+ // *** page settings ***
+
+ maData.mbPrintInRows = !GETITEMBOOL( rItemSet, ATTR_PAGE_TOPDOWN );
+ maData.mbHorCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_HORCENTER );
+ maData.mbVerCenter = GETITEMBOOL( rItemSet, ATTR_PAGE_VERCENTER );
+ maData.mbPrintHeadings = GETITEMBOOL( rItemSet, ATTR_PAGE_HEADERS );
+ maData.mbPrintGrid = GETITEMBOOL( rItemSet, ATTR_PAGE_GRID );
+ maData.mbPrintNotes = GETITEMBOOL( rItemSet, ATTR_PAGE_NOTES );
+
+ maData.mnStartPage = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_FIRSTPAGENO, sal_uInt16 );
+ maData.mbManualStart = maData.mnStartPage && (!nScTab || rDoc.NeedPageResetAfterTab( nScTab - 1 ));
+
+ const SvxLRSpaceItem& rLRItem = GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE );
+ maData.mfLeftMargin = XclTools::GetInchFromTwips( rLRItem.GetLeft() );
+ maData.mfRightMargin = XclTools::GetInchFromTwips( rLRItem.GetRight() );
+ const SvxULSpaceItem& rULItem = GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE );
+ maData.mfTopMargin = XclTools::GetInchFromTwips( rULItem.GetUpper() );
+ maData.mfBottomMargin = XclTools::GetInchFromTwips( rULItem.GetLower() );
+
+ const SvxPageItem& rPageItem = GETITEM( rItemSet, SvxPageItem, ATTR_PAGE );
+ const SvxSizeItem& rSizeItem = GETITEM( rItemSet, SvxSizeItem, ATTR_PAGE_SIZE );
+ maData.SetScPaperSize( rSizeItem.GetSize(), !rPageItem.IsLandscape() );
+
+ const ScPageScaleToItem& rScaleToItem = GETITEM( rItemSet, ScPageScaleToItem, ATTR_PAGE_SCALETO );
+ sal_uInt16 nPages = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALETOPAGES, sal_uInt16 );
+ sal_uInt16 nScale = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_PAGE_SCALE, sal_uInt16 );
+
+ if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETO, false ) && rScaleToItem.IsValid() )
+ {
+ maData.mnFitToWidth = rScaleToItem.GetWidth();
+ maData.mnFitToHeight = rScaleToItem.GetHeight();
+ maData.mbFitToPages = true;
+
+ }
+ else if( ScfTools::CheckItem( rItemSet, ATTR_PAGE_SCALETOPAGES, false ) && nPages )
+ {
+ maData.mnFitToWidth = 1;
+ maData.mnFitToHeight = nPages;
+ maData.mbFitToPages = true;
+ }
+ else if( nScale )
+ {
+ maData.mnScaling = nScale;
+ maData.mbFitToPages = false;
+ }
+
+ maData.mxBrushItem.reset( new SvxBrushItem( GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND ) ) );
+
+ // *** header and footer ***
+
+ XclExpHFConverter aHFConv( GetRoot() );
+
+ // header
+ const SfxItemSet& rHdrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ).GetItemSet();
+ if( GETITEMBOOL( rHdrItemSet, ATTR_PAGE_ON ) )
+ {
+ const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_HEADERRIGHT );
+ aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
+ maData.maHeader = aHFConv.GetHFString();
+ // header height (Excel excludes header from top margin)
+ sal_Int32 nHdrHeight = GETITEMBOOL( rHdrItemSet, ATTR_PAGE_DYNAMIC ) ?
+ // dynamic height: calculate header height, add header <-> sheet area distance
+ (aHFConv.GetTotalHeight() + GETITEM( rHdrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetLower()) :
+ // static height: ATTR_PAGE_SIZE already includes header <-> sheet area distance
+ static_cast< sal_Int32 >( GETITEM( rHdrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
+ maData.mfHeaderMargin = maData.mfTopMargin;
+ maData.mfTopMargin += XclTools::GetInchFromTwips( nHdrHeight );
+ }
+
+ // footer
+ const SfxItemSet& rFtrItemSet = GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ).GetItemSet();
+ if( GETITEMBOOL( rFtrItemSet, ATTR_PAGE_ON ) )
+ {
+ const ScPageHFItem& rHFItem = GETITEM( rItemSet, ScPageHFItem, ATTR_PAGE_FOOTERRIGHT );
+ aHFConv.GenerateString( rHFItem.GetLeftArea(), rHFItem.GetCenterArea(), rHFItem.GetRightArea() );
+ maData.maFooter = aHFConv.GetHFString();
+ // footer height (Excel excludes footer from bottom margin)
+ sal_Int32 nFtrHeight = GETITEMBOOL( rFtrItemSet, ATTR_PAGE_DYNAMIC ) ?
+ // dynamic height: calculate footer height, add sheet area <-> footer distance
+ (aHFConv.GetTotalHeight() + GETITEM( rFtrItemSet, SvxULSpaceItem, ATTR_ULSPACE ).GetUpper()) :
+ // static height: ATTR_PAGE_SIZE already includes sheet area <-> footer distance
+ static_cast< sal_Int32 >( GETITEM( rFtrItemSet, SvxSizeItem, ATTR_PAGE_SIZE ).GetSize().Height() );
+ maData.mfFooterMargin = maData.mfBottomMargin;
+ maData.mfBottomMargin += XclTools::GetInchFromTwips( nFtrHeight );
+ }
+ }
+
+ // *** page breaks ***
+
+ set<SCROW> aRowBreaks;
+ rDoc.GetAllRowBreaks(aRowBreaks, nScTab, false, true);
+
+ SCROW nMaxRow = numeric_limits<sal_uInt16>::max();
+ for (set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); itr != itrEnd; ++itr)
+ {
+ SCROW nRow = *itr;
+ if (nRow > nMaxRow)
+ break;
+
+ maData.maHorPageBreaks.push_back(nRow);
+ }
+
+ if (maData.maHorPageBreaks.size() > 1026)
+ {
+ // Excel allows only up to 1026 page breaks. Trim any excess page breaks.
+ ScfUInt16Vec::iterator itr = maData.maHorPageBreaks.begin();
+ ::std::advance(itr, 1026);
+ maData.maHorPageBreaks.erase(itr, maData.maHorPageBreaks.end());
+ }
+
+ set<SCCOL> aColBreaks;
+ rDoc.GetAllColBreaks(aColBreaks, nScTab, false, true);
+ for (set<SCCOL>::const_iterator itr = aColBreaks.begin(), itrEnd = aColBreaks.end(); itr != itrEnd; ++itr)
+ maData.maVerPageBreaks.push_back(*itr);
+}
+
+static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm )
+{
+ // OOXTODO: we currently only emit oddHeader/oddFooter elements, and
+ // do not support the first/even/odd page distinction.
+ rStrm.WriteAttributes(
+ // OOXTODO: XML_alignWithMargins,
+ XML_differentFirst, "false", // OOXTODO
+ XML_differentOddEven, "false", // OOXTODO
+ // OOXTODO: XML_scaleWithDoc
+ FSEND );
+ rStrm.GetCurrentStream()->write( ">" );
+}
+
+void XclExpPageSettings::Save( XclExpStream& rStrm )
+{
+ XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_GRIDSET, true ).Save( rStrm );
+ XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).Save( rStrm );
+ XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks, static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).Save( rStrm );
+ XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).Save( rStrm );
+ XclExpSetup( maData ).Save( rStrm );
+
+ if( (GetBiff() == EXC_BIFF8) && maData.mxBrushItem.get() )
+ if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
+ XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).Save( rStrm );
+}
+
+void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
+{
+ XclExpXmlStartSingleElementRecord( XML_printOptions ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTHEADERS, maData.mbPrintHeadings, XML_headings ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_PRINTGRIDLINES, maData.mbPrintGrid, XML_gridLines ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_GRIDSET, true, XML_gridLinesSet ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter, XML_horizontalCentered ).SaveXml( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter, XML_verticalCentered ).SaveXml( rStrm );
+ XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_printOptions
+
+ XclExpXmlStartSingleElementRecord( XML_pageMargins ).SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_LEFTMARGIN, maData.mfLeftMargin ).SetAttribute( XML_left )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_RIGHTMARGIN, maData.mfRightMargin ).SetAttribute( XML_right )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_TOPMARGIN, maData.mfTopMargin ).SetAttribute( XML_top )->SaveXml( rStrm );
+ XclExpDoubleRecord( EXC_ID_BOTTOMMARGIN, maData.mfBottomMargin ).SetAttribute( XML_bottom )->SaveXml( rStrm );
+ XclExpDoubleRecord( 0, maData.mfHeaderMargin).SetAttribute( XML_header )->SaveXml( rStrm );
+ XclExpDoubleRecord( 0, maData.mfFooterMargin).SetAttribute( XML_footer )->SaveXml( rStrm );
+ XclExpXmlEndSingleElementRecord().SaveXml( rStrm ); // XML_pageMargins
+
+ XclExpSetup( maData ).SaveXml( rStrm );
+
+ XclExpXmlStartElementRecord( XML_headerFooter, lcl_WriteHeaderFooter ).SaveXml( rStrm );
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
+ XclExpXmlEndElementRecord( XML_headerFooter ).SaveXml( rStrm );
+
+ XclExpPageBreaks( EXC_ID_HORPAGEBREAKS, maData.maHorPageBreaks,
+ static_cast< sal_uInt16 >( GetXclMaxPos().Col() ) ).SaveXml( rStrm );
+ XclExpPageBreaks( EXC_ID_VERPAGEBREAKS, maData.maVerPageBreaks,
+ static_cast< sal_uInt16 >( GetXclMaxPos().Row() ) ).SaveXml( rStrm );
+
+ if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() )
+ XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ).SaveXml( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpChartPageSettings::XclExpChartPageSettings( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpChartPageSettings::Save( XclExpStream& rStrm )
+{
+ XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).Save( rStrm );
+ XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_HCENTER, maData.mbHorCenter ).Save( rStrm );
+ XclExpBoolRecord( EXC_ID_VCENTER, maData.mbVerCenter ).Save( rStrm );
+ XclExpSetup( maData ).Save( rStrm );
+ XclExpUInt16Record( EXC_ID_PRINTSIZE, EXC_PRINTSIZE_FULL ).Save( rStrm );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
new file mode 100644
index 000000000000..be8557eac430
--- /dev/null
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -0,0 +1,1971 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xepivot.hxx"
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+#include <algorithm>
+#include <math.h>
+
+#include <rtl/math.hxx>
+#include <tools/date.hxx>
+#include <svl/zformat.hxx>
+#include <sot/storage.hxx>
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dpshttab.hxx"
+#include "globstr.hrc"
+#include "fapihelper.hxx"
+#include "xestring.hxx"
+#include "xelink.hxx"
+
+using namespace ::oox;
+
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_HIDDEN;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_ROW;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_COLUMN;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_PAGE;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
+using ::com::sun::star::sheet::GeneralFunction;
+using ::com::sun::star::sheet::DataPilotFieldSortInfo;
+using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
+using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+namespace {
+
+// constants to track occurrence of specific data types
+const sal_uInt16 EXC_PCITEM_DATA_STRING = 0x0001; /// String, empty, boolean, error.
+const sal_uInt16 EXC_PCITEM_DATA_DOUBLE = 0x0002; /// Double with fraction.
+const sal_uInt16 EXC_PCITEM_DATA_INTEGER = 0x0004; /// Integer, double without fraction.
+const sal_uInt16 EXC_PCITEM_DATA_DATE = 0x0008; /// Date, time, date/time.
+
+/** Maps a bitfield consisting of EXC_PCITEM_DATA_* flags above to SXFIELD data type bitfield. */
+static const sal_uInt16 spnPCItemFlags[] =
+{ // STR DBL INT DAT
+ EXC_SXFIELD_DATA_NONE, //
+ EXC_SXFIELD_DATA_STR, // x
+ EXC_SXFIELD_DATA_INT, // x
+ EXC_SXFIELD_DATA_STR_INT, // x x
+ EXC_SXFIELD_DATA_DBL, // x
+ EXC_SXFIELD_DATA_STR_DBL, // x x
+ EXC_SXFIELD_DATA_INT, // x x
+ EXC_SXFIELD_DATA_STR_INT, // x x x
+ EXC_SXFIELD_DATA_DATE, // x
+ EXC_SXFIELD_DATA_DATE_STR, // x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x
+ EXC_SXFIELD_DATA_DATE_STR, // x x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x
+ EXC_SXFIELD_DATA_DATE_STR, // x x x
+ EXC_SXFIELD_DATA_DATE_NUM, // x x x
+ EXC_SXFIELD_DATA_DATE_STR // x x x x
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpPCItem::XclExpPCItem( const String& rText ) :
+ XclExpRecord( (rText.Len() > 0) ? EXC_ID_SXSTRING : EXC_ID_SXEMPTY, 0 ),
+ mnTypeFlag( EXC_PCITEM_DATA_STRING )
+{
+ if( rText.Len() )
+ SetText( rText );
+ else
+ SetEmpty();
+}
+
+XclExpPCItem::XclExpPCItem( double fValue ) :
+ XclExpRecord( EXC_ID_SXDOUBLE, 8 )
+{
+ SetDouble( fValue );
+ mnTypeFlag = (fValue - floor( fValue ) == 0.0) ?
+ EXC_PCITEM_DATA_INTEGER : EXC_PCITEM_DATA_DOUBLE;
+}
+
+XclExpPCItem::XclExpPCItem( const DateTime& rDateTime ) :
+ XclExpRecord( EXC_ID_SXDATETIME, 8 )
+{
+ SetDateTime( rDateTime );
+ mnTypeFlag = EXC_PCITEM_DATA_DATE;
+}
+
+XclExpPCItem::XclExpPCItem( sal_Int16 nValue ) :
+ XclExpRecord( EXC_ID_SXINTEGER, 2 ),
+ mnTypeFlag( EXC_PCITEM_DATA_INTEGER )
+{
+ SetInteger( nValue );
+}
+
+XclExpPCItem::XclExpPCItem( bool bValue ) :
+ XclExpRecord( EXC_ID_SXBOOLEAN, 2 ),
+ mnTypeFlag( EXC_PCITEM_DATA_STRING )
+{
+ SetBool( bValue );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpPCItem::EqualsText( const String& rText ) const
+{
+ return (rText.Len() == 0) ? IsEmpty() : (GetText() && (*GetText() == rText));
+}
+
+bool XclExpPCItem::EqualsDouble( double fValue ) const
+{
+ return GetDouble() && (*GetDouble() == fValue);
+}
+
+bool XclExpPCItem::EqualsDateTime( const DateTime& rDateTime ) const
+{
+ return GetDateTime() && (*GetDateTime() == rDateTime);
+}
+
+bool XclExpPCItem::EqualsBool( bool bValue ) const
+{
+ return GetBool() && (*GetBool() == bValue);
+}
+
+// ----------------------------------------------------------------------------
+
+void XclExpPCItem::WriteBody( XclExpStream& rStrm )
+{
+ if( const String* pText = GetText() )
+ {
+ rStrm << XclExpString( *pText );
+ }
+ else if( const double* pfValue = GetDouble() )
+ {
+ rStrm << *pfValue;
+ }
+ else if( const sal_Int16* pnValue = GetInteger() )
+ {
+ rStrm << *pnValue;
+ }
+ else if( const DateTime* pDateTime = GetDateTime() )
+ {
+ sal_uInt16 nYear = static_cast< sal_uInt16 >( pDateTime->GetYear() );
+ sal_uInt16 nMonth = static_cast< sal_uInt16 >( pDateTime->GetMonth() );
+ sal_uInt8 nDay = static_cast< sal_uInt8 >( pDateTime->GetDay() );
+ sal_uInt8 nHour = static_cast< sal_uInt8 >( pDateTime->GetHour() );
+ sal_uInt8 nMin = static_cast< sal_uInt8 >( pDateTime->GetMin() );
+ sal_uInt8 nSec = static_cast< sal_uInt8 >( pDateTime->GetSec() );
+ if( nYear < 1900 ) { nYear = 1900; nMonth = 1; nDay = 0; }
+ rStrm << nYear << nMonth << nDay << nHour << nMin << nSec;
+ }
+ else if( const bool* pbValue = GetBool() )
+ {
+ rStrm << static_cast< sal_uInt16 >( *pbValue ? 1 : 0 );
+ }
+ else
+ {
+ // nothing to do for SXEMPTY
+ DBG_ASSERT( IsEmpty(), "XclExpPCItem::WriteBody - no data found" );
+ }
+}
+
+// ============================================================================
+
+XclExpPCField::XclExpPCField(
+ const XclExpRoot& rRoot, const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScRange& rRange ) :
+ XclExpRecord( EXC_ID_SXFIELD ),
+ XclPCField( EXC_PCFIELD_STANDARD, nFieldIdx ),
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnTypeFlags( 0 )
+{
+ // general settings for the standard field, insert all items from source range
+ InitStandardField( rRange );
+
+ // add special settings for inplace numeric grouping
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ if( const ScDPDimensionSaveData* pSaveDimData = pSaveData->GetExistingDimensionData() )
+ {
+ if( const ScDPSaveNumGroupDimension* pNumGroupDim = pSaveDimData->GetNumGroupDim( GetFieldName() ) )
+ {
+ const ScDPNumGroupInfo& rNumInfo = pNumGroupDim->GetInfo();
+ const ScDPNumGroupInfo& rDateInfo = pNumGroupDim->GetDateInfo();
+ DBG_ASSERT( !rNumInfo.Enable || !rDateInfo.Enable,
+ "XclExpPCField::XclExpPCField - numeric and date grouping enabled" );
+
+ if( rNumInfo.Enable )
+ InitNumGroupField( rDPObj, rNumInfo );
+ else if( rDateInfo.Enable )
+ InitDateGroupField( rDPObj, rDateInfo, pNumGroupDim->GetDatePart() );
+ }
+ }
+ }
+
+ // final settings (flags, item numbers)
+ Finalize();
+}
+
+XclExpPCField::XclExpPCField(
+ const XclExpRoot& rRoot, const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim, const XclExpPCField& rBaseField ) :
+ XclExpRecord( EXC_ID_SXFIELD ),
+ XclPCField( EXC_PCFIELD_STDGROUP, nFieldIdx ),
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnTypeFlags( 0 )
+{
+ // add base field info (always using first base field, not predecessor of this field) ***
+ DBG_ASSERT( rBaseField.GetFieldName() == rGroupDim.GetSourceDimName(),
+ "XclExpPCField::FillFromGroup - wrong base cache field" );
+ maFieldInfo.maName = rGroupDim.GetGroupDimName();
+ maFieldInfo.mnGroupBase = rBaseField.GetFieldIndex();
+
+ // add standard group info or date group info
+ const ScDPNumGroupInfo& rDateInfo = rGroupDim.GetDateInfo();
+ if( rDateInfo.Enable && (rGroupDim.GetDatePart() != 0) )
+ InitDateGroupField( rDPObj, rDateInfo, rGroupDim.GetDatePart() );
+ else
+ InitStdGroupField( rBaseField, rGroupDim );
+
+ // final settings (flags, item numbers)
+ Finalize();
+}
+
+XclExpPCField::~XclExpPCField()
+{
+}
+
+void XclExpPCField::SetGroupChildField( const XclExpPCField& rChildField )
+{
+ DBG_ASSERT( !::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD ),
+ "XclExpPCField::SetGroupChildIndex - field already has a grouping child field" );
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+ maFieldInfo.mnGroupChild = rChildField.GetFieldIndex();
+}
+
+sal_uInt16 XclExpPCField::GetItemCount() const
+{
+ return static_cast< sal_uInt16 >( GetVisItemList().GetSize() );
+}
+
+const XclExpPCItem* XclExpPCField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return GetVisItemList().GetRecord( nItemIdx ).get();
+}
+
+sal_uInt16 XclExpPCField::GetItemIndex( const String& rItemName ) const
+{
+ const XclExpPCItemList& rItemList = GetVisItemList();
+ for( size_t nPos = 0, nSize = rItemList.GetSize(); nPos < nSize; ++nPos )
+ if( rItemList.GetRecord( nPos )->ConvertToText() == rItemName )
+ return static_cast< sal_uInt16 >( nPos );
+ return EXC_PC_NOITEM;
+}
+
+sal_Size XclExpPCField::GetIndexSize() const
+{
+ return Has16BitIndexes() ? 2 : 1;
+}
+
+void XclExpPCField::WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const
+{
+ // only standard fields write item indexes
+ if( nSrcRow < maIndexVec.size() )
+ {
+ sal_uInt16 nIndex = maIndexVec[ nSrcRow ];
+ if( Has16BitIndexes() )
+ rStrm << nIndex;
+ else
+ rStrm << static_cast< sal_uInt8 >( nIndex );
+ }
+}
+
+void XclExpPCField::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( IsSupportedField(), "XclExpPCField::Save - unknown field type" );
+ // SXFIELD
+ XclExpRecord::Save( rStrm );
+ // SXFDBTYPE
+ XclExpUInt16Record( EXC_ID_SXFDBTYPE, EXC_SXFDBTYPE_DEFAULT ).Save( rStrm );
+ // list of grouping items
+ maGroupItemList.Save( rStrm );
+ // SXGROUPINFO
+ WriteSxgroupinfo( rStrm );
+ // SXNUMGROUP and additional grouping items (grouping limit settings)
+ WriteSxnumgroup( rStrm );
+ // list of original items
+ maOrigItemList.Save( rStrm );
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpPCField::XclExpPCItemList& XclExpPCField::GetVisItemList() const
+{
+ DBG_ASSERT( IsStandardField() == maGroupItemList.IsEmpty(),
+ "XclExpPCField::GetVisItemList - unexpected additional items in standard field" );
+ return IsStandardField() ? maOrigItemList : maGroupItemList;
+}
+
+void XclExpPCField::InitStandardField( const ScRange& rRange )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InitStandardField - only for standard fields" );
+ DBG_ASSERT( rRange.aStart.Col() == rRange.aEnd.Col(), "XclExpPCField::InitStandardField - cell range with multiple columns" );
+
+ ScDocument& rDoc = GetDoc();
+ SvNumberFormatter& rFormatter = GetFormatter();
+
+ // field name is in top cell of the range
+ ScAddress aPos( rRange.aStart );
+ rDoc.GetString( aPos.Col(), aPos.Row(), aPos.Tab(), maFieldInfo.maName );
+ // #i76047# maximum field name length in pivot cache is 255
+ maFieldInfo.maName.Erase( ::std::min( maFieldInfo.maName.Len(), EXC_PC_MAXSTRLEN ) );
+
+ // loop over all cells, create pivot cache items
+ for( aPos.IncRow(); (aPos.Row() <= rRange.aEnd.Row()) && (maOrigItemList.GetSize() < EXC_PC_MAXITEMCOUNT); aPos.IncRow() )
+ {
+ if( rDoc.HasValueData( aPos.Col(), aPos.Row(), aPos.Tab() ) )
+ {
+ double fValue = rDoc.GetValue( aPos );
+ short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( aPos ) );
+ if( nFmtType == NUMBERFORMAT_LOGICAL )
+ InsertOrigBoolItem( fValue != 0 );
+ else if( nFmtType & NUMBERFORMAT_DATETIME )
+ InsertOrigDateTimeItem( GetDateTimeFromDouble( ::std::max( fValue, 0.0 ) ) );
+ else
+ InsertOrigDoubleItem( fValue );
+ }
+ else
+ {
+ String aText;
+ rDoc.GetString( aPos.Col(), aPos.Row(), aPos.Tab(), aText );
+ InsertOrigTextItem( aText );
+ }
+ }
+}
+
+void XclExpPCField::InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim )
+{
+ DBG_ASSERT( IsGroupField(), "XclExpPCField::InitStdGroupField - only for standard grouping fields" );
+
+ maFieldInfo.mnBaseItems = rBaseField.GetItemCount();
+ maGroupOrder.resize( maFieldInfo.mnBaseItems, EXC_PC_NOITEM );
+
+ // loop over all groups of this field
+ for( long nGroupIdx = 0, nGroupCount = rGroupDim.GetGroupCount(); nGroupIdx < nGroupCount; ++nGroupIdx )
+ {
+ if( const ScDPSaveGroupItem* pGroupItem = rGroupDim.GetGroupByIndex( nGroupIdx ) )
+ {
+ // the index of the new item containing the grouping name
+ sal_uInt16 nGroupItemIdx = EXC_PC_NOITEM;
+ // loop over all elements of one group
+ for( size_t nElemIdx = 0, nElemCount = pGroupItem->GetElementCount(); nElemIdx < nElemCount; ++nElemIdx )
+ {
+ if( const String* pElemName = pGroupItem->GetElementByIndex( nElemIdx ) )
+ {
+ // try to find the item that is part of the group in the base field
+ sal_uInt16 nBaseItemIdx = rBaseField.GetItemIndex( *pElemName );
+ if( nBaseItemIdx < maFieldInfo.mnBaseItems )
+ {
+ // add group name item only if there are any valid base items
+ if( nGroupItemIdx == EXC_PC_NOITEM )
+ nGroupItemIdx = InsertGroupItem( new XclExpPCItem( pGroupItem->GetGroupName() ) );
+ maGroupOrder[ nBaseItemIdx ] = nGroupItemIdx;
+ }
+ }
+ }
+ }
+ }
+
+ // add items and base item indexes of all ungrouped elements
+ for( sal_uInt16 nBaseItemIdx = 0; nBaseItemIdx < maFieldInfo.mnBaseItems; ++nBaseItemIdx )
+ // items that are not part of a group still have the EXC_PC_NOITEM entry
+ if( maGroupOrder[ nBaseItemIdx ] == EXC_PC_NOITEM )
+ // try to find the base item
+ if( const XclExpPCItem* pBaseItem = rBaseField.GetItem( nBaseItemIdx ) )
+ // create a clone of the base item, insert its index into item order list
+ maGroupOrder[ nBaseItemIdx ] = InsertGroupItem( new XclExpPCItem( *pBaseItem ) );
+}
+
+void XclExpPCField::InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InitNumGroupField - only for standard fields" );
+ DBG_ASSERT( rNumInfo.Enable, "XclExpPCField::InitNumGroupField - numeric grouping not enabled" );
+
+ // new field type, date type, limit settings (min/max/step/auto)
+ if( rNumInfo.DateValues )
+ {
+ // special case: group by days with step count
+ meFieldType = EXC_PCFIELD_DATEGROUP;
+ maNumGroupInfo.SetScDateType( com::sun::star::sheet::DataPilotFieldGroupBy::DAYS );
+ SetDateGroupLimit( rNumInfo, true );
+ }
+ else
+ {
+ meFieldType = EXC_PCFIELD_NUMGROUP;
+ maNumGroupInfo.SetNumType();
+ SetNumGroupLimit( rNumInfo );
+ }
+
+ // generate visible items
+ InsertNumDateGroupItems( rDPObj, rNumInfo );
+}
+
+void XclExpPCField::InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart )
+{
+ DBG_ASSERT( IsStandardField() || IsStdGroupField(), "XclExpPCField::InitDateGroupField - only for standard fields" );
+ DBG_ASSERT( rDateInfo.Enable, "XclExpPCField::InitDateGroupField - date grouping not enabled" );
+
+ // new field type
+ meFieldType = IsStandardField() ? EXC_PCFIELD_DATEGROUP : EXC_PCFIELD_DATECHILD;
+
+ // date type, limit settings (min/max/step/auto)
+ maNumGroupInfo.SetScDateType( nDatePart );
+ SetDateGroupLimit( rDateInfo, false );
+
+ // generate visible items
+ InsertNumDateGroupItems( rDPObj, rDateInfo, nDatePart );
+}
+
+void XclExpPCField::InsertItemArrayIndex( size_t nListPos )
+{
+ DBG_ASSERT( IsStandardField(), "XclExpPCField::InsertItemArrayIndex - only for standard fields" );
+ maIndexVec.push_back( static_cast< sal_uInt16 >( nListPos ) );
+}
+
+void XclExpPCField::InsertOrigItem( XclExpPCItem* pNewItem )
+{
+ size_t nItemIdx = maOrigItemList.GetSize();
+ maOrigItemList.AppendNewRecord( pNewItem );
+ InsertItemArrayIndex( nItemIdx );
+ mnTypeFlags |= pNewItem->GetTypeFlag();
+}
+
+void XclExpPCField::InsertOrigTextItem( const String& rText )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ // #i76047# maximum item text length in pivot cache is 255
+ String aShortText( rText, 0, ::std::min( rText.Len(), EXC_PC_MAXSTRLEN ) );
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsText( aShortText )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( aShortText ) );
+}
+
+void XclExpPCField::InsertOrigDoubleItem( double fValue )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsDouble( fValue )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( fValue ) );
+}
+
+void XclExpPCField::InsertOrigDateTimeItem( const DateTime& rDateTime )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsDateTime( rDateTime )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( rDateTime ) );
+}
+
+void XclExpPCField::InsertOrigBoolItem( bool bValue )
+{
+ size_t nPos = 0;
+ bool bFound = false;
+ for( size_t nSize = maOrigItemList.GetSize(); !bFound && (nPos < nSize); ++nPos )
+ if( (bFound = maOrigItemList.GetRecord( nPos )->EqualsBool( bValue )) == true )
+ InsertItemArrayIndex( nPos );
+ if( !bFound )
+ InsertOrigItem( new XclExpPCItem( bValue ) );
+}
+
+sal_uInt16 XclExpPCField::InsertGroupItem( XclExpPCItem* pNewItem )
+{
+ maGroupItemList.AppendNewRecord( pNewItem );
+ return static_cast< sal_uInt16 >( maGroupItemList.GetSize() - 1 );
+}
+
+void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart )
+{
+ DBG_ASSERT( rDPObj.GetSheetDesc(), "XclExpPCField::InsertNumDateGroupItems - cannot generate element list" );
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ {
+ // get the string collection with original source elements
+ const ScDPCache* pCache = pSrcDesc->CreateCache();
+ if (!pCache)
+ return;
+
+ ScSheetDPData aDPData(GetDocPtr(), *pSrcDesc, pCache);
+ const std::vector< SCROW > aOrignial = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) );
+ // get the string collection with generated grouping elements
+ ScDPNumGroupDimension aTmpDim( rNumInfo );
+ if( nDatePart != 0 )
+ aTmpDim.MakeDateHelper( rNumInfo, nDatePart );
+ const std::vector<SCROW>& aMemberIds = aTmpDim.GetNumEntries(
+ static_cast<SCCOL>( GetBaseFieldIndex() ), aDPData.GetCacheTable().getCache(), aOrignial);
+ for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ )
+ {
+ const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] );
+ if ( pData )
+ InsertGroupItem( new XclExpPCItem( pData->GetString() ) );
+ }
+ }
+}
+
+void XclExpPCField::SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo )
+{
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN, rNumInfo.AutoStart );
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX, rNumInfo.AutoEnd );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.Start ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.End ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( rNumInfo.Step ) );
+}
+
+void XclExpPCField::SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep )
+{
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN, rDateInfo.AutoStart );
+ ::set_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX, rDateInfo.AutoEnd );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( GetDateTimeFromDouble( rDateInfo.Start ) ) );
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( GetDateTimeFromDouble( rDateInfo.End ) ) );
+ sal_Int16 nStep = bUseStep ? limit_cast< sal_Int16 >( rDateInfo.Step, 1, SAL_MAX_INT16 ) : 1;
+ maNumGroupLimits.AppendNewRecord( new XclExpPCItem( nStep ) );
+}
+
+void XclExpPCField::Finalize()
+{
+ // flags
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASITEMS, !GetVisItemList().IsEmpty() );
+ // Excel writes long indexes even for 0x0100 items (indexes from 0x00 to 0xFF)
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT, maOrigItemList.GetSize() >= 0x0100 );
+ ::set_flag( maFieldInfo.mnFlags, EXC_SXFIELD_NUMGROUP, IsNumGroupField() || IsDateGroupField() );
+ /* mnTypeFlags is updated in all Insert***Item() functions. Now the flags
+ for the current combination of item types is added to the flags. */
+ ::set_flag( maFieldInfo.mnFlags, spnPCItemFlags[ mnTypeFlags ] );
+
+ // item count fields
+ maFieldInfo.mnVisItems = static_cast< sal_uInt16 >( GetVisItemList().GetSize() );
+ maFieldInfo.mnGroupItems = static_cast< sal_uInt16 >( maGroupItemList.GetSize() );
+ // maFieldInfo.mnBaseItems set in InitStdGroupField()
+ maFieldInfo.mnOrigItems = static_cast< sal_uInt16 >( maOrigItemList.GetSize() );
+}
+
+void XclExpPCField::WriteSxnumgroup( XclExpStream& rStrm )
+{
+ if( IsNumGroupField() || IsDateGroupField() )
+ {
+ // SXNUMGROUP record
+ rStrm.StartRecord( EXC_ID_SXNUMGROUP, 2 );
+ rStrm << maNumGroupInfo;
+ rStrm.EndRecord();
+
+ // limits (min/max/step) for numeric grouping
+ DBG_ASSERT( maNumGroupLimits.GetSize() == 3,
+ "XclExpPCField::WriteSxnumgroup - missing numeric grouping limits" );
+ maNumGroupLimits.Save( rStrm );
+ }
+}
+
+void XclExpPCField::WriteSxgroupinfo( XclExpStream& rStrm )
+{
+ DBG_ASSERT( IsStdGroupField() != maGroupOrder.empty(),
+ "XclExpPCField::WriteSxgroupinfo - missing grouping info" );
+ if( IsStdGroupField() && !maGroupOrder.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXGROUPINFO, 2 * maGroupOrder.size() );
+ for( ScfUInt16Vec::const_iterator aIt = maGroupOrder.begin(), aEnd = maGroupOrder.end(); aIt != aEnd; ++aIt )
+ rStrm << *aIt;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPCField::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maFieldInfo;
+}
+
+// ============================================================================
+
+XclExpPivotCache::XclExpPivotCache( const XclExpRoot& rRoot, const ScDPObject& rDPObj, sal_uInt16 nListIdx ) :
+ XclExpRoot( rRoot ),
+ mnListIdx( nListIdx ),
+ mbValid( false )
+{
+ // source from sheet only
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ {
+ /* maOrigSrcRange: Range received from the DataPilot object.
+ maExpSrcRange: Range written to the DCONREF record.
+ maDocSrcRange: Range used to get source data from Calc document.
+ This range may be shorter than maExpSrcRange to improve export
+ performance (#i22541#). */
+ maOrigSrcRange = maExpSrcRange = maDocSrcRange = pSrcDesc->GetSourceRange();
+ maSrcRangeName = pSrcDesc->GetRangeName();
+
+ // internal sheet data only
+ SCTAB nScTab = maExpSrcRange.aStart.Tab();
+ if( (nScTab == maExpSrcRange.aEnd.Tab()) && GetTabInfo().IsExportTab( nScTab ) )
+ {
+ // ValidateRange() restricts source range to valid Excel limits
+ if( GetAddressConverter().ValidateRange( maExpSrcRange, true ) )
+ {
+ // #i22541# skip empty cell areas (performance)
+ SCCOL nDocCol1, nDocCol2;
+ SCROW nDocRow1, nDocRow2;
+ GetDoc().GetDataStart( nScTab, nDocCol1, nDocRow1 );
+ GetDoc().GetPrintArea( nScTab, nDocCol2, nDocRow2, false );
+ SCCOL nSrcCol1 = maExpSrcRange.aStart.Col();
+ SCROW nSrcRow1 = maExpSrcRange.aStart.Row();
+ SCCOL nSrcCol2 = maExpSrcRange.aEnd.Col();
+ SCROW nSrcRow2 = maExpSrcRange.aEnd.Row();
+
+ // #i22541# do not store index list for too big ranges
+ if( 2 * (nDocRow2 - nDocRow1) < (nSrcRow2 - nSrcRow1) )
+ ::set_flag( maPCInfo.mnFlags, EXC_SXDB_SAVEDATA, false );
+
+ // Excel must refresh tables to make drilldown working
+ ::set_flag( maPCInfo.mnFlags, EXC_SXDB_REFRESH_LOAD );
+
+ // adjust row indexes, keep one row of empty area to surely have the empty cache item
+ if( nSrcRow1 < nDocRow1 )
+ nSrcRow1 = nDocRow1 - 1;
+ if( nSrcRow2 > nDocRow2 )
+ nSrcRow2 = nDocRow2 + 1;
+
+ maDocSrcRange.aStart.SetCol( ::std::max( nDocCol1, nSrcCol1 ) );
+ maDocSrcRange.aStart.SetRow( nSrcRow1 );
+ maDocSrcRange.aEnd.SetCol( ::std::min( nDocCol2, nSrcCol2 ) );
+ maDocSrcRange.aEnd.SetRow( nSrcRow2 );
+
+ GetDoc().GetName( nScTab, maTabName );
+ maPCInfo.mnSrcRecs = static_cast< sal_uInt32 >( maExpSrcRange.aEnd.Row() - maExpSrcRange.aStart.Row() );
+ maPCInfo.mnStrmId = nListIdx + 1;
+ maPCInfo.mnSrcType = EXC_SXDB_SRC_SHEET;
+
+ AddFields( rDPObj );
+
+ mbValid = true;
+ }
+ }
+ }
+}
+
+bool XclExpPivotCache::HasItemIndexList() const
+{
+ return ::get_flag( maPCInfo.mnFlags, EXC_SXDB_SAVEDATA );
+}
+
+sal_uInt16 XclExpPivotCache::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFieldList.GetSize() );
+}
+
+const XclExpPCField* XclExpPivotCache::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+bool XclExpPivotCache::HasAddFields() const
+{
+ // pivot cache can be shared, if there are no additional cache fields
+ return maPCInfo.mnStdFields < maPCInfo.mnTotalFields;
+}
+
+bool XclExpPivotCache::HasEqualDataSource( const ScDPObject& rDPObj ) const
+{
+ /* For now, only sheet sources are supported, therefore it is enough to
+ compare the ScSheetSourceDesc. Later, there should be done more complicated
+ comparisons regarding the source type of rDPObj and this cache. */
+ if( const ScSheetSourceDesc* pSrcDesc = rDPObj.GetSheetDesc() )
+ return pSrcDesc->GetSourceRange() == maOrigSrcRange;
+ return false;
+}
+
+void XclExpPivotCache::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mbValid, "XclExpPivotCache::Save - invalid pivot cache" );
+ // SXIDSTM
+ XclExpUInt16Record( EXC_ID_SXIDSTM, maPCInfo.mnStrmId ).Save( rStrm );
+ // SXVS
+ XclExpUInt16Record( EXC_ID_SXVS, EXC_SXVS_SHEET ).Save( rStrm );
+
+ if (maSrcRangeName.getLength())
+ // DCONNAME
+ WriteDConName(rStrm);
+ else
+ // DCONREF
+ WriteDconref(rStrm);
+
+ // create the pivot cache storage stream
+ WriteCacheStream();
+}
+
+void XclExpPivotCache::SaveXml( XclExpXmlStream&
+#ifdef XLSX_PIVOT_CACHE
+ rStrm
+#endif
+)
+{
+ DBG_ASSERT( mbValid, "XclExpPivotCache::Save - invalid pivot cache" );
+#ifdef XLSX_PIVOT_CACHE /* <pivotCache> without xl/pivotCaches/ cacheStream
+ results in a broken .xlsx */
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ OUString sId = OUStringBuffer()
+ .appendAscii("rId")
+ .append( rStrm.GetUniqueIdOUString() )
+ .makeStringAndClear();
+ rWorkbook->startElement( XML_pivotCache,
+ XML_cacheId, OString::valueOf( (sal_Int32)maPCInfo.mnStrmId ).getStr(),
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+ // SXIDSTM
+ XclExpUInt16Record( EXC_ID_SXIDSTM, maPCInfo.mnStrmId ).SaveXml( rStrm );
+ // SXVS
+ XclExpUInt16Record( EXC_ID_SXVS, EXC_SXVS_SHEET ).SaveXml( rStrm );
+ // DCONREF
+ // OOXTODO: WriteDconref( rStrm );
+ // create the pivot cache storage stream
+ // OOXTODO: WriteCacheStream();
+ rWorkbook->endElement( XML_pivotCache );
+#endif /* XLSX_PIVOT_CACHE */
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPCField* XclExpPivotCache::GetFieldAcc( sal_uInt16 nFieldIdx )
+{
+ return maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+XclExpPCField* XclExpPivotCache::GetFieldAcc( const String& rFieldName )
+{
+ XclExpPCField* pField = 0;
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); !pField && (nPos < nSize); ++nPos )
+ if( maFieldList.GetRecord( nPos )->GetFieldName() == rFieldName )
+ pField = maFieldList.GetRecord( nPos ).get();
+ return pField;
+}
+
+void XclExpPivotCache::AddFields( const ScDPObject& rDPObj )
+{
+ AddStdFields( rDPObj );
+ maPCInfo.mnStdFields = GetFieldCount();
+ AddGroupFields( rDPObj );
+ AddCalcFields( rDPObj );
+ maPCInfo.mnTotalFields = GetFieldCount();
+};
+
+void XclExpPivotCache::AddStdFields( const ScDPObject& rDPObj )
+{
+ // if item index list is not written, used shortened source range (maDocSrcRange) for performance
+ const ScRange& rRange = HasItemIndexList() ? maExpSrcRange : maDocSrcRange;
+ // create a standard pivot cache field for each source column
+ for( SCCOL nScCol = rRange.aStart.Col(), nEndScCol = rRange.aEnd.Col(); nScCol <= nEndScCol; ++nScCol )
+ {
+ ScRange aColRange( rRange );
+ aColRange.aStart.SetCol( nScCol );
+ aColRange.aEnd.SetCol( nScCol );
+ maFieldList.AppendNewRecord( new XclExpPCField(
+ GetRoot(), *this, GetFieldCount(), rDPObj, aColRange ) );
+ }
+}
+
+void XclExpPivotCache::AddGroupFields( const ScDPObject& rDPObj )
+{
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ if( const ScDPDimensionSaveData* pSaveDimData = pSaveData->GetExistingDimensionData() )
+ {
+ // loop over all existing standard fields to find their group fields
+ for( sal_uInt16 nFieldIdx = 0; nFieldIdx < maPCInfo.mnStdFields; ++nFieldIdx )
+ {
+ if( XclExpPCField* pCurrStdField = GetFieldAcc( nFieldIdx ) )
+ {
+ const ScDPSaveGroupDimension* pGroupDim = pSaveDimData->GetGroupDimForBase( pCurrStdField->GetFieldName() );
+ XclExpPCField* pLastGroupField = pCurrStdField;
+ while( pGroupDim )
+ {
+ // insert the new grouping field
+ XclExpPCFieldRef xNewGroupField( new XclExpPCField(
+ GetRoot(), *this, GetFieldCount(), rDPObj, *pGroupDim, *pCurrStdField ) );
+ maFieldList.AppendRecord( xNewGroupField );
+
+ // register new grouping field at current grouping field, building a chain
+ pLastGroupField->SetGroupChildField( *xNewGroupField );
+
+ // next grouping dimension
+ pGroupDim = pSaveDimData->GetGroupDimForBase( pGroupDim->GetGroupDimName() );
+ pLastGroupField = xNewGroupField.get();
+ }
+ }
+ }
+ }
+ }
+}
+
+void XclExpPivotCache::AddCalcFields( const ScDPObject& /*rDPObj*/ )
+{
+ // not supported
+}
+
+void XclExpPivotCache::WriteDconref( XclExpStream& rStrm ) const
+{
+ XclExpString aRef( XclExpUrlHelper::EncodeUrl( GetRoot(), EMPTY_STRING, &maTabName ) );
+ rStrm.StartRecord( EXC_ID_DCONREF, 7 + aRef.GetSize() );
+ rStrm << static_cast< sal_uInt16 >( maExpSrcRange.aStart.Row() )
+ << static_cast< sal_uInt16 >( maExpSrcRange.aEnd.Row() )
+ << static_cast< sal_uInt8 >( maExpSrcRange.aStart.Col() )
+ << static_cast< sal_uInt8 >( maExpSrcRange.aEnd.Col() )
+ << aRef
+ << sal_uInt8( 0 );
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteDConName( XclExpStream& rStrm ) const
+{
+ XclExpString aName(maSrcRangeName);
+ rStrm.StartRecord(EXC_ID_DCONNAME, aName.GetSize() + 2);
+ rStrm << aName << sal_uInt16(0);
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteCacheStream()
+{
+ SotStorageRef xSvStrg = OpenStorage( EXC_STORAGE_PTCACHE );
+ SotStorageStreamRef xSvStrm = OpenStream( xSvStrg, ScfTools::GetHexStr( maPCInfo.mnStrmId ) );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aStrm( *xSvStrm, GetRoot() );
+ // SXDB
+ WriteSxdb( aStrm );
+ // SXDBEX
+ WriteSxdbex( aStrm );
+ // field list (SXFIELD and items)
+ maFieldList.Save( aStrm );
+ // index table (list of SXINDEXLIST)
+ WriteSxindexlistList( aStrm );
+ // EOF
+ XclExpEmptyRecord( EXC_ID_EOF ).Save( aStrm );
+ }
+}
+
+void XclExpPivotCache::WriteSxdb( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXDB, 21 );
+ rStrm << maPCInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteSxdbex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXDBEX, 12 );
+ rStrm << EXC_SXDBEX_CREATION_DATE
+ << sal_uInt32( 0 ); // number of SXFORMULA records
+ rStrm.EndRecord();
+}
+
+void XclExpPivotCache::WriteSxindexlistList( XclExpStream& rStrm ) const
+{
+ if( HasItemIndexList() )
+ {
+ sal_Size nRecSize = 0;
+ size_t nPos, nSize = maFieldList.GetSize();
+ for( nPos = 0; nPos < nSize; ++nPos )
+ nRecSize += maFieldList.GetRecord( nPos )->GetIndexSize();
+
+ for( sal_uInt32 nSrcRow = 0; nSrcRow < maPCInfo.mnSrcRecs; ++nSrcRow )
+ {
+ rStrm.StartRecord( EXC_ID_SXINDEXLIST, nRecSize );
+ for( nPos = 0; nPos < nSize; ++nPos )
+ maFieldList.GetRecord( nPos )->WriteIndex( rStrm, nSrcRow );
+ rStrm.EndRecord();
+ }
+ }
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+/** Returns a display string for a data field containing the field name and aggregation function. */
+String lclGetDataFieldCaption( const String& rFieldName, GeneralFunction eFunc )
+{
+ String aCaption;
+
+ sal_uInt16 nResIdx = 0;
+ using namespace ::com::sun::star::sheet;
+ switch( eFunc )
+ {
+ case GeneralFunction_SUM: nResIdx = STR_FUN_TEXT_SUM; break;
+ case GeneralFunction_COUNT: nResIdx = STR_FUN_TEXT_COUNT; break;
+ case GeneralFunction_AVERAGE: nResIdx = STR_FUN_TEXT_AVG; break;
+ case GeneralFunction_MAX: nResIdx = STR_FUN_TEXT_MAX; break;
+ case GeneralFunction_MIN: nResIdx = STR_FUN_TEXT_MIN; break;
+ case GeneralFunction_PRODUCT: nResIdx = STR_FUN_TEXT_PRODUCT; break;
+ case GeneralFunction_COUNTNUMS: nResIdx = STR_FUN_TEXT_COUNT; break;
+ case GeneralFunction_STDEV: nResIdx = STR_FUN_TEXT_STDDEV; break;
+ case GeneralFunction_STDEVP: nResIdx = STR_FUN_TEXT_STDDEV; break;
+ case GeneralFunction_VAR: nResIdx = STR_FUN_TEXT_VAR; break;
+ case GeneralFunction_VARP: nResIdx = STR_FUN_TEXT_VAR; break;
+ default:;
+ }
+ if( nResIdx )
+ aCaption.Assign( ScGlobal::GetRscString( nResIdx ) ).AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) );
+ aCaption.Append( rFieldName );
+ return aCaption;
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// ============================================================================
+
+XclExpPTItem::XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx ) :
+ XclExpRecord( EXC_ID_SXVI, 8 ),
+ mpCacheItem( rCacheField.GetItem( nCacheIdx ) )
+{
+ maItemInfo.mnType = EXC_SXVI_TYPE_DATA;
+ maItemInfo.mnCacheIdx = nCacheIdx;
+ maItemInfo.maVisName.mbUseCache = mpCacheItem != 0;
+}
+
+XclExpPTItem::XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache ) :
+ XclExpRecord( EXC_ID_SXVI, 8 ),
+ mpCacheItem( 0 )
+{
+ maItemInfo.mnType = nItemType;
+ maItemInfo.mnCacheIdx = nCacheIdx;
+ maItemInfo.maVisName.mbUseCache = bUseCache;
+}
+
+const String& XclExpPTItem::GetItemName() const
+{
+ return mpCacheItem ? mpCacheItem->ConvertToText() : EMPTY_STRING;
+}
+
+void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem )
+{
+ ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() );
+ ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() );
+
+ // visible name
+ const OUString* pVisName = rSaveMem.GetLayoutName();
+ if (pVisName && !pVisName->equals(GetItemName()))
+ maItemInfo.SetVisName(*pVisName);
+}
+
+void XclExpPTItem::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << maItemInfo;
+}
+
+// ============================================================================
+
+XclExpPTField::XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx ) :
+ mrPTable( rPTable ),
+ mpCacheField( rPTable.GetCacheField( nCacheIdx ) )
+{
+ maFieldInfo.mnCacheIdx = nCacheIdx;
+
+ // create field items
+ if( mpCacheField )
+ for( sal_uInt16 nItemIdx = 0, nItemCount = mpCacheField->GetItemCount(); nItemIdx < nItemCount; ++nItemIdx )
+ maItemList.AppendNewRecord( new XclExpPTItem( *mpCacheField, nItemIdx ) );
+ maFieldInfo.mnItemCount = static_cast< sal_uInt16 >( maItemList.GetSize() );
+}
+
+// data access ----------------------------------------------------------------
+
+const String& XclExpPTField::GetFieldName() const
+{
+ return mpCacheField ? mpCacheField->GetFieldName() : EMPTY_STRING;
+}
+
+sal_uInt16 XclExpPTField::GetFieldIndex() const
+{
+ // field index always equal to cache index
+ return maFieldInfo.mnCacheIdx;
+}
+
+sal_uInt16 XclExpPTField::GetLastDataInfoIndex() const
+{
+ DBG_ASSERT( !maDataInfoVec.empty(), "XclExpPTField::GetLastDataInfoIndex - no data info found" );
+ // will return 0xFFFF for empty vector -> ok
+ return static_cast< sal_uInt16 >( maDataInfoVec.size() - 1 );
+}
+
+sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const
+{
+ for( size_t nPos = 0, nSize = maItemList.GetSize(); nPos < nSize; ++nPos )
+ if( maItemList.GetRecord( nPos )->GetItemName() == rName )
+ return static_cast< sal_uInt16 >( nPos );
+ return nDefaultIdx;
+}
+
+// fill data --------------------------------------------------------------
+
+/**
+ * Calc's subtotal names are escaped with backslashes ('\'), while Excel's
+ * are not escaped at all.
+ */
+static OUString lcl_convertCalcSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ bool bEscaped = false;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ aBuf.append(c);
+ bEscaped = false;
+ }
+ return aBuf.makeStringAndClear();
+}
+
+void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ // orientation
+ DataPilotFieldOrientation eOrient = static_cast< DataPilotFieldOrientation >( rSaveDim.GetOrientation() );
+ DBG_ASSERT( eOrient != DataPilotFieldOrientation_DATA, "XclExpPTField::SetPropertiesFromDim - called for data field" );
+ maFieldInfo.AddApiOrient( eOrient );
+
+ // show empty items
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() );
+
+ // visible name
+ const OUString* pLayoutName = rSaveDim.GetLayoutName();
+ if (pLayoutName && !pLayoutName->equals(GetFieldName()))
+ maFieldInfo.SetVisName(*pLayoutName);
+
+ const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
+ if (pSubtotalName)
+ {
+ OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName);
+ maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName));
+ }
+
+ // subtotals
+ XclPTSubtotalVec aSubtotals;
+ aSubtotals.reserve( static_cast< size_t >( rSaveDim.GetSubTotalsCount() ) );
+ for( long nSubtIdx = 0, nSubtCount = rSaveDim.GetSubTotalsCount(); nSubtIdx < nSubtCount; ++nSubtIdx )
+ aSubtotals.push_back( rSaveDim.GetSubTotalFunc( nSubtIdx ) );
+ maFieldInfo.SetSubtotals( aSubtotals );
+
+ // sorting
+ if( const DataPilotFieldSortInfo* pSortInfo = rSaveDim.GetSortInfo() )
+ {
+ maFieldExtInfo.SetApiSortMode( pSortInfo->Mode );
+ if( pSortInfo->Mode == ::com::sun::star::sheet::DataPilotFieldSortMode::DATA )
+ maFieldExtInfo.mnSortField = mrPTable.GetDataFieldIndex( pSortInfo->Field, EXC_SXVDEX_SORT_OWN );
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SORT_ASC, pSortInfo->IsAscending );
+ }
+
+ // auto show
+ if( const DataPilotFieldAutoShowInfo* pShowInfo = rSaveDim.GetAutoShowInfo() )
+ {
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_AUTOSHOW, pShowInfo->IsEnabled );
+ maFieldExtInfo.SetApiAutoShowMode( pShowInfo->ShowItemsMode );
+ maFieldExtInfo.SetApiAutoShowCount( pShowInfo->ItemCount );
+ maFieldExtInfo.mnShowField = mrPTable.GetDataFieldIndex( pShowInfo->DataField, EXC_SXVDEX_SHOW_NONE );
+ }
+
+ // layout
+ if( const DataPilotFieldLayoutInfo* pLayoutInfo = rSaveDim.GetLayoutInfo() )
+ {
+ maFieldExtInfo.SetApiLayoutMode( pLayoutInfo->LayoutMode );
+ ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_LAYOUT_BLANK, pLayoutInfo->AddEmptyLines );
+ }
+
+ // special page field properties
+ if( eOrient == DataPilotFieldOrientation_PAGE )
+ {
+ maPageInfo.mnField = GetFieldIndex();
+
+ // selected item
+ if( rSaveDim.HasCurrentPage() )
+ maPageInfo.mnSelItem = GetItemIndex( rSaveDim.GetCurrentPage(), EXC_SXPI_ALLITEMS );
+ else
+ maPageInfo.mnSelItem = EXC_SXPI_ALLITEMS;
+ }
+
+ // item properties
+ const ScDPSaveDimension::MemberList &rMembers = rSaveDim.GetMembers();
+ for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; ++i)
+ if( XclExpPTItem* pItem = GetItemAcc( (*i)->GetName() ) )
+ pItem->SetPropertiesFromMember( **i );
+}
+
+void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ maDataInfoVec.push_back( XclPTDataFieldInfo() );
+ XclPTDataFieldInfo& rDataInfo = maDataInfoVec.back();
+ rDataInfo.mnField = GetFieldIndex();
+
+ // orientation
+ maFieldInfo.AddApiOrient( DataPilotFieldOrientation_DATA );
+
+ // aggregation function
+ GeneralFunction eFunc = static_cast< GeneralFunction >( rSaveDim.GetFunction() );
+ rDataInfo.SetApiAggFunc( eFunc );
+
+ // visible name
+ const rtl::OUString* pVisName = rSaveDim.GetLayoutName();
+ if (pVisName)
+ rDataInfo.SetVisName(*pVisName);
+ else
+ rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
+
+ // result field reference
+ if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() )
+ {
+ rDataInfo.SetApiRefType( pFieldRef->ReferenceType );
+ rDataInfo.SetApiRefItemType( pFieldRef->ReferenceItemType );
+ if( const XclExpPTField* pRefField = mrPTable.GetField( pFieldRef->ReferenceField ) )
+ {
+ rDataInfo.mnRefField = pRefField->GetFieldIndex();
+ if( pFieldRef->ReferenceItemType == ::com::sun::star::sheet::DataPilotFieldReferenceItemType::NAMED )
+ rDataInfo.mnRefItem = pRefField->GetItemIndex( pFieldRef->ReferenceItemName, 0 );
+ }
+ }
+}
+
+void XclExpPTField::AppendSubtotalItems()
+{
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) AppendSubtotalItem( EXC_SXVI_TYPE_DEFAULT );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_SUM ) AppendSubtotalItem( EXC_SXVI_TYPE_SUM );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_COUNT ) AppendSubtotalItem( EXC_SXVI_TYPE_COUNT );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) AppendSubtotalItem( EXC_SXVI_TYPE_AVERAGE );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_MAX ) AppendSubtotalItem( EXC_SXVI_TYPE_MAX );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_MIN ) AppendSubtotalItem( EXC_SXVI_TYPE_MIN );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_PROD ) AppendSubtotalItem( EXC_SXVI_TYPE_PROD );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) AppendSubtotalItem( EXC_SXVI_TYPE_COUNTNUM );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_STDDEV ) AppendSubtotalItem( EXC_SXVI_TYPE_STDDEV );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) AppendSubtotalItem( EXC_SXVI_TYPE_STDDEVP );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_VAR ) AppendSubtotalItem( EXC_SXVI_TYPE_VAR );
+ if( maFieldInfo.mnSubtotals & EXC_SXVD_SUBT_VARP ) AppendSubtotalItem( EXC_SXVI_TYPE_VARP );
+}
+
+// records --------------------------------------------------------------------
+
+void XclExpPTField::WriteSxpiEntry( XclExpStream& rStrm ) const
+{
+ rStrm << maPageInfo;
+}
+
+void XclExpPTField::WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const
+{
+ DBG_ASSERT( nDataInfoIdx < maDataInfoVec.size(), "XclExpPTField::WriteSxdi - data field not found" );
+ if( nDataInfoIdx < maDataInfoVec.size() )
+ {
+ rStrm.StartRecord( EXC_ID_SXDI, 12 );
+ rStrm << maDataInfoVec[ nDataInfoIdx ];
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPTField::Save( XclExpStream& rStrm )
+{
+ // SXVD
+ WriteSxvd( rStrm );
+ // list of SXVI records
+ maItemList.Save( rStrm );
+ // SXVDEX
+ WriteSxvdex( rStrm );
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPTItem* XclExpPTField::GetItemAcc( const String& rName )
+{
+ XclExpPTItem* pItem = 0;
+ for( size_t nPos = 0, nSize = maItemList.GetSize(); !pItem && (nPos < nSize); ++nPos )
+ if( maItemList.GetRecord( nPos )->GetItemName() == rName )
+ pItem = maItemList.GetRecord( nPos ).get();
+ return pItem;
+}
+
+void XclExpPTField::AppendSubtotalItem( sal_uInt16 nItemType )
+{
+ maItemList.AppendNewRecord( new XclExpPTItem( nItemType, EXC_SXVI_DEFAULT_CACHE, true ) );
+ ++maFieldInfo.mnItemCount;
+}
+
+void XclExpPTField::WriteSxvd( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVD, 10 );
+ rStrm << maFieldInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPTField::WriteSxvdex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVDEX, 20 );
+ rStrm << maFieldExtInfo;
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
+XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& rDPObj, const XclExpPivotCache& rPCache ) :
+ XclExpRoot( rRoot ),
+ mrPCache( rPCache ),
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mnOutScTab( 0 ),
+ mbValid( false ),
+ mbFilterBtn( false )
+{
+ const ScRange& rOutScRange = rDPObj.GetOutRange();
+ if( GetAddressConverter().ConvertRange( maPTInfo.maOutXclRange, rOutScRange, true ) )
+ {
+ // DataPilot properties -----------------------------------------------
+
+ // pivot table properties from DP object
+ mnOutScTab = rOutScRange.aStart.Tab();
+ maPTInfo.maTableName = rDPObj.GetName();
+ maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex();
+
+ maPTViewEx9Info.Init( rDPObj );
+
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ // additional properties from ScDPSaveData
+ SetPropertiesFromDP( *pSaveData );
+
+ // loop over all dimensions ---------------------------------------
+
+ /* 1) Default-construct all pivot table fields for all pivot cache fields. */
+ for( sal_uInt16 nFieldIdx = 0, nFieldCount = mrPCache.GetFieldCount(); nFieldIdx < nFieldCount; ++nFieldIdx )
+ maFieldList.AppendNewRecord( new XclExpPTField( *this, nFieldIdx ) );
+
+ boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
+ const boost::ptr_vector<ScDPSaveDimension>& rDimList = pSaveData->GetDimensions();
+
+ /* 2) First process all data dimensions, they are needed for extended
+ settings of row/column/page fields (sorting/auto show). */
+ for (iter = rDimList.begin(); iter != rDimList.end(); ++iter)
+ if (iter->GetOrientation() == DataPilotFieldOrientation_DATA)
+ SetDataFieldPropertiesFromDim(*iter);
+
+ /* 3) Row/column/page/hidden fields. */
+ for (iter = rDimList.begin(); iter != rDimList.end(); ++iter)
+ if (iter->GetOrientation() != DataPilotFieldOrientation_DATA)
+ SetFieldPropertiesFromDim(*iter);
+
+ // Finalize -------------------------------------------------------
+
+ Finalize();
+ mbValid = true;
+ }
+ }
+}
+
+const XclExpPCField* XclExpPivotTable::GetCacheField( sal_uInt16 nCacheIdx ) const
+{
+ return mrPCache.GetField( nCacheIdx );
+}
+
+const XclExpPTField* XclExpPivotTable::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx == EXC_SXIVD_DATA) ? &maDataOrientField : maFieldList.GetRecord( nFieldIdx ).get();
+}
+
+const XclExpPTField* XclExpPivotTable::GetField( const String& rName ) const
+{
+ return const_cast< XclExpPivotTable* >( this )->GetFieldAcc( rName );
+}
+
+sal_uInt16 XclExpPivotTable::GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const
+{
+ for( XclPTDataFieldPosVec::const_iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
+ if( const XclExpPTField* pField = GetField( aIt->first ) )
+ if( pField->GetFieldName() == rName )
+ return static_cast< sal_uInt16 >( aIt - maDataFields.begin() );
+ return nDefaultIdx;
+}
+
+void XclExpPivotTable::Save( XclExpStream& rStrm )
+{
+ if( mbValid )
+ {
+ // SXVIEW
+ WriteSxview( rStrm );
+ // pivot table fields (SXVD, SXVDEX, and item records)
+ maFieldList.Save( rStrm );
+ // SXIVD records for row and column fields
+ WriteSxivd( rStrm, maRowFields );
+ WriteSxivd( rStrm, maColFields );
+ // SXPI
+ WriteSxpi( rStrm );
+ // list of SXDI records containing data field info
+ WriteSxdiList( rStrm );
+ // SXLI records
+ WriteSxli( rStrm, maPTInfo.mnDataRows, maPTInfo.mnRowFields );
+ WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields );
+ // SXEX
+ WriteSxex( rStrm );
+ // QSISXTAG
+ WriteQsiSxTag( rStrm );
+ // SXVIEWEX9
+ WriteSxViewEx9( rStrm );
+ }
+}
+
+void XclExpPivotTable::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mbValid )
+ return;
+ sax_fastparser::FSHelperPtr aPivotTableDefinition = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "pivotTables/pivotTable", mnOutScTab+1),
+ XclXmlUtils::GetStreamName( "../", "pivotTables/pivotTable", mnOutScTab+1),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable");
+ rStrm.PushStream( aPivotTableDefinition );
+
+ aPivotTableDefinition->startElement( XML_pivotTableDefinition,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ XML_name, XclXmlUtils::ToOString( maPTInfo.maTableName ).getStr(),
+ XML_cacheId, OString::valueOf( (sal_Int32) maPTInfo.mnCacheIdx ).getStr(),
+ XML_dataOnRows, XclXmlUtils::ToPsz( maPTInfo.mnDataAxis == EXC_SXVD_AXIS_COL ),
+ XML_dataPosition, OString::valueOf( (sal_Int32) maPTInfo.mnDataPos ).getStr(),
+ XML_autoFormatId, OString::valueOf( (sal_Int32) maPTInfo.mnAutoFmtIdx ).getStr(),
+ // OOXTODO: XML_applyNumberFormats, [ SXVIEW fAtrNum (maPTInfo.mnFlags) ]
+ // OOXTODO: XML_applyBorderFormats, [ SXVIEW fAtrBdr (maPTInfo.mnFlags) ]
+ // OOXTODO: XML_applyFontFormats, [ SXVIEW fAtrFnt (maPTInfo.mnFlags) ]
+ // OOXTODO: XML_applyPatternFormats, [ SXVIEW fAtrPat (maPTInfo.mnFlags) ]
+ // OOXTODO: XML_applyAlignmentFormats, [ SXVIEW fAtrAlc (maPTInfo.mnFlags) ]
+ // OOXTODO: XML_applyWidthHeightFormats, [ SXVIEW fAtrProc (maPTInfo.mnFlags) ]
+ XML_dataCaption, XclXmlUtils::ToOString( maPTInfo.maDataName ).getStr(),
+ // OOXTODO: XML_grandTotalCaption, [ SxViewEx9 chGrand ]
+ // OOXTODO: XML_errorCaption, [ SXEx stError ]
+ // OOXTODO: XML_showError, [ SXEx fDisplayErrorString ]
+ // OOXTODO: XML_missingCaption, [ SXEx stDisplayNull ]
+ // OOXTODO: XML_showMissing, [ SXEx fDisplayNullString ]
+ // OOXTODO: XML_pageStyle, [ SXEx stPageFieldStyle ]
+ // OOXTODO: XML_pivotTableStyle, [ SXEx stTableStyle ]
+ // OOXTODO: XML_vacatedStyle, [ SXEx stVacateStyle ]
+ // OOXTODO: XML_tag, [ SXEx stTag ]
+ // OOXTODO: XML_updatedVersion, [ app-dependent ]
+ // OOXTODO: XML_minRefreshableVersion, [ app-dependent ]
+ // OOXTODO: XML_asteriskTotals, [ QsiSXTag/SXView9Save fHideTotAnnotation ]
+ // OOXTODO: XML_showItems, [ ??? ]
+ // OOXTODO: XML_editData, [ ??? ]
+ // OOXTODO: XML_disableFieldList, [ SXEx fEnableFieldDialog? ]
+ // OOXTODO: XML_showCalcMbrs, [ ??? ]
+ // OOXTODO: XML_visualTotals, [ ??? ]
+ // OOXTODO: XML_showMultipleLabel, [ SXEx fMergeLabels? ]
+ // OOXTODO: XML_showDataDropDown, [ SXEx fEnableDrillDown? ]
+ // OOXTODO: XML_showDrill, [ ??? ]
+ // OOXTODO: XML_printDrill, [ ??? ]
+ // OOXTODO: XML_showMemberPropertyTips,
+ // OOXTODO: XML_showDataTips,
+ // OOXTODO: XML_enableWizard,
+ XML_enableDrill, XclXmlUtils::ToPsz( maPTExtInfo.mnFlags & EXC_SXEX_DRILLDOWN ), // ???
+ // OOXTODO: XML_enableFieldProperties, [ SXEx fEnableFieldDialog (maPTExtInfo.mnFlags) ]
+ // OOXTODO: XML_preserveFormatting, [ SXEx fPreserveFormatting (maPTExtInfo.mnFlags) ]
+ // OOXTODO: XML_pageWrap, [ SXEx cWrapPage (maPTExtInfo.mnFlags) ]
+ // OOXTODO: XML_pageOverThenDown, [ SXEx fAcrossPageLay (maPTExtInfo.mnFlags) ]
+ // OOXTODO: XML_subtotalHiddenItems, [ SXEx fSubtotalHiddenPageItems (maPTExtInfo.mnFlags) ]
+ XML_rowGrandTotals, XclXmlUtils::ToPsz( maPTInfo.mnFlags & EXC_SXVIEW_ROWGRAND ),
+ XML_colGrandTotals, XclXmlUtils::ToPsz( maPTInfo.mnFlags & EXC_SXVIEW_COLGRAND ),
+ // OOXTODO: XML_fieldPrintTitles,
+ // OOXTODO: XML_itemPrintTitles,
+ // OOXTODO: XML_mergeItem,
+ // OOXTODO: XML_showDropZones,
+ // OOXTODO: XML_createdVersion,
+ // OOXTODO: XML_indent,
+ // OOXTODO: XML_showEmptyRow,
+ // OOXTODO: XML_showEmptyCol,
+ // OOXTODO: XML_showHeaders,
+ // OOXTODO: XML_compact,
+ // OOXTODO: XML_outline,
+ // OOXTODO: XML_outlineData,
+ // OOXTODO: XML_compactData,
+ // OOXTODO: XML_published,
+ // OOXTODO: XML_gridDropZones,
+ // OOXTODO: XML_immersive,
+ // OOXTODO: XML_multipleFieldFilters,
+ // OOXTODO: XML_chartFormat,
+ // OOXTODO: XML_rowHeaderCaption,
+ // OOXTODO: XML_colHeaderCaption,
+ // OOXTODO: XML_fieldListSortAscending,
+ // OOXTODO: XML_mdxSubqueries,
+ // OOXTODO: XML_customListSort,
+ FSEND );
+
+ aPivotTableDefinition->singleElement( XML_location,
+ XML_ref, XclXmlUtils::ToOString( maPTInfo.maOutXclRange ).getStr(),
+ XML_firstHeaderRow, OString::valueOf( (sal_Int32) maPTInfo.mnFirstHeadRow ).getStr(),
+ XML_firstDataRow, OString::valueOf( (sal_Int32) maPTInfo.maDataXclPos.mnRow ).getStr(),
+ XML_firstDataCol, OString::valueOf( (sal_Int32) maPTInfo.maDataXclPos.mnCol ).getStr(),
+ XML_rowPageCount, OString::valueOf( (sal_Int32) maPTInfo.mnDataRows ).getStr(), // OOXTODO?
+ XML_colPageCount, OString::valueOf( (sal_Int32) maPTInfo.mnDataCols ).getStr(), // OOXTODO?
+ FSEND );
+
+ // OOXTODO: XML_pivotFields
+
+ // maPTInfo.mnFields?
+ if( maPTInfo.mnRowFields )
+ {
+ aPivotTableDefinition->startElement( XML_rowFields,
+ XML_count, OString::valueOf( (sal_Int32) maPTInfo.mnRowFields ).getStr(),
+ FSEND );
+ aPivotTableDefinition->endElement( XML_rowFields );
+ }
+
+ // OOXTODO: XML_rowItems
+
+ if( maPTInfo.mnColFields )
+ {
+ aPivotTableDefinition->startElement( XML_colFields,
+ XML_count, OString::valueOf( (sal_Int32) maPTInfo.mnColFields ).getStr(),
+ FSEND );
+ aPivotTableDefinition->endElement( XML_colFields );
+ }
+
+ // OOXTODO: XML_colItems
+
+ if( maPTInfo.mnPageFields )
+ {
+ aPivotTableDefinition->startElement( XML_pageFields,
+ XML_count, OString::valueOf( (sal_Int32) maPTInfo.mnPageFields ).getStr(),
+ FSEND );
+ aPivotTableDefinition->endElement( XML_pageFields );
+ }
+
+ if( maPTInfo.mnDataFields )
+ {
+ aPivotTableDefinition->startElement( XML_dataFields,
+ XML_count, OString::valueOf( (sal_Int32) maPTInfo.mnDataFields ).getStr(),
+ FSEND );
+ aPivotTableDefinition->endElement( XML_dataFields );
+ }
+
+ // OOXTODO: XML_formats, XML_conditionalFormats, XML_chartFormats,
+ // XML_pivotHierarchies, XML_pivotTableStyleInfo, XML_filters,
+ // XML_rowHierarchiesUsage, XML_colHierarchiesUsage, XML_ext
+
+ aPivotTableDefinition->endElement( XML_pivotTableDefinition );
+
+ rStrm.PopStream();
+}
+
+// private --------------------------------------------------------------------
+
+XclExpPTField* XclExpPivotTable::GetFieldAcc( const String& rName )
+{
+ XclExpPTField* pField = 0;
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); !pField && (nPos < nSize); ++nPos )
+ if( maFieldList.GetRecord( nPos )->GetFieldName() == rName )
+ pField = maFieldList.GetRecord( nPos ).get();
+ return pField;
+}
+
+XclExpPTField* XclExpPivotTable::GetFieldAcc( const ScDPSaveDimension& rSaveDim )
+{
+ // data field orientation field?
+ if( rSaveDim.IsDataLayout() )
+ return &maDataOrientField;
+
+ // a real dimension
+ String aFieldName( rSaveDim.GetName() );
+ return aFieldName.Len() ? GetFieldAcc( aFieldName ) : 0;
+}
+
+// fill data --------------------------------------------------------------
+
+void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData )
+{
+ ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_ROWGRAND, rSaveData.GetRowGrand() );
+ ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() );
+ ::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() );
+ mbFilterBtn = rSaveData.GetFilterButton();
+ const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension();
+ if (!pDim)
+ return;
+
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maPTInfo.maDataName = *pLayoutName;
+ else
+ maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA);
+}
+
+void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ if( XclExpPTField* pField = GetFieldAcc( rSaveDim ) )
+ {
+ // field properties
+ pField->SetPropertiesFromDim( rSaveDim );
+
+ // update the corresponding field position list
+ DataPilotFieldOrientation eOrient = static_cast< DataPilotFieldOrientation >( rSaveDim.GetOrientation() );
+ sal_uInt16 nFieldIdx = pField->GetFieldIndex();
+ bool bDataLayout = nFieldIdx == EXC_SXIVD_DATA;
+ bool bMultiData = maDataFields.size() > 1;
+
+ if( !bDataLayout || bMultiData ) switch( eOrient )
+ {
+ case DataPilotFieldOrientation_ROW:
+ maRowFields.push_back( nFieldIdx );
+ if( bDataLayout )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_ROW;
+ break;
+ case DataPilotFieldOrientation_COLUMN:
+ maColFields.push_back( nFieldIdx );
+ if( bDataLayout )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_COL;
+ break;
+ case DataPilotFieldOrientation_PAGE:
+ maPageFields.push_back( nFieldIdx );
+ DBG_ASSERT( !bDataLayout, "XclExpPivotTable::SetFieldPropertiesFromDim - wrong orientation for data fields" );
+ break;
+ case DataPilotFieldOrientation_DATA:
+ DBG_ERRORFILE( "XclExpPivotTable::SetFieldPropertiesFromDim - called for data field" );
+ break;
+ default:;
+ }
+ }
+}
+
+void XclExpPivotTable::SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
+{
+ if( XclExpPTField* pField = GetFieldAcc( rSaveDim ) )
+ {
+ // field properties
+ pField->SetDataPropertiesFromDim( rSaveDim );
+ // update the data field position list
+ maDataFields.push_back( XclPTDataFieldPos( pField->GetFieldIndex(), pField->GetLastDataInfoIndex() ) );
+ }
+}
+
+void XclExpPivotTable::Finalize()
+{
+ // field numbers
+ maPTInfo.mnFields = static_cast< sal_uInt16 >( maFieldList.GetSize() );
+ maPTInfo.mnRowFields = static_cast< sal_uInt16 >( maRowFields.size() );
+ maPTInfo.mnColFields = static_cast< sal_uInt16 >( maColFields.size() );
+ maPTInfo.mnPageFields = static_cast< sal_uInt16 >( maPageFields.size() );
+ maPTInfo.mnDataFields = static_cast< sal_uInt16 >( maDataFields.size() );
+
+ maPTExtInfo.mnPagePerRow = maPTInfo.mnPageFields;
+ maPTExtInfo.mnPagePerCol = (maPTInfo.mnPageFields > 0) ? 1 : 0;
+
+ // subtotal items
+ for( size_t nPos = 0, nSize = maFieldList.GetSize(); nPos < nSize; ++nPos )
+ maFieldList.GetRecord( nPos )->AppendSubtotalItems();
+
+ // find data field orientation field
+ maPTInfo.mnDataPos = EXC_SXVIEW_DATALAST;
+ const ScfUInt16Vec* pFieldVec = 0;
+ switch( maPTInfo.mnDataAxis )
+ {
+ case EXC_SXVD_AXIS_ROW: pFieldVec = &maRowFields; break;
+ case EXC_SXVD_AXIS_COL: pFieldVec = &maColFields; break;
+ }
+
+ if( pFieldVec && !pFieldVec->empty() && (pFieldVec->back() != EXC_SXIVD_DATA) )
+ {
+ ScfUInt16Vec::const_iterator aIt = ::std::find( pFieldVec->begin(), pFieldVec->end(), EXC_SXIVD_DATA );
+ if( aIt != pFieldVec->end() )
+ maPTInfo.mnDataPos = static_cast< sal_uInt16 >( aIt - pFieldVec->begin() );
+ }
+
+ // single data field is always row oriented
+ if( maPTInfo.mnDataAxis == EXC_SXVD_AXIS_NONE )
+ maPTInfo.mnDataAxis = EXC_SXVD_AXIS_ROW;
+
+ // update output range (initialized in ctor)
+ sal_uInt16& rnXclCol1 = maPTInfo.maOutXclRange.maFirst.mnCol;
+ sal_uInt32& rnXclRow1 = maPTInfo.maOutXclRange.maFirst.mnRow;
+ sal_uInt16& rnXclCol2 = maPTInfo.maOutXclRange.maLast.mnCol;
+ sal_uInt32& rnXclRow2 = maPTInfo.maOutXclRange.maLast.mnRow;
+ // exclude page fields from output range
+ rnXclRow1 = rnXclRow1 + maPTInfo.mnPageFields;
+ // exclude filter button from output range
+ if( mbFilterBtn )
+ ++rnXclRow1;
+ // exclude empty row between (filter button and/or page fields) and table
+ if( mbFilterBtn || maPTInfo.mnPageFields )
+ ++rnXclRow1;
+
+ // data area
+ sal_uInt16& rnDataXclCol = maPTInfo.maDataXclPos.mnCol;
+ sal_uInt32& rnDataXclRow = maPTInfo.maDataXclPos.mnRow;
+ rnDataXclCol = rnXclCol1 + maPTInfo.mnRowFields;
+ rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1;
+ if( maDataFields.empty() )
+ ++rnDataXclRow;
+
+ bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0);
+ if (bExtraHeaderRow)
+ // Insert an extra row only when there is no column field.
+ ++rnDataXclRow;
+
+ rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol );
+ rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow );
+ maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1;
+ maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1;
+
+ // first heading
+ maPTInfo.mnFirstHeadRow = rnXclRow1;
+ if (bExtraHeaderRow)
+ maPTInfo.mnFirstHeadRow += 2;
+}
+
+// records ----------------------------------------------------------------
+
+void XclExpPivotTable::WriteSxview( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXVIEW, 46 + maPTInfo.maTableName.Len() + maPTInfo.maDataName.Len() );
+ rStrm << maPTInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const
+{
+ if( !rFields.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXIVD, rFields.size() * 2 );
+ for( ScfUInt16Vec::const_iterator aIt = rFields.begin(), aEnd = rFields.end(); aIt != aEnd; ++aIt )
+ rStrm << *aIt;
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxpi( XclExpStream& rStrm ) const
+{
+ if( !maPageFields.empty() )
+ {
+ rStrm.StartRecord( EXC_ID_SXPI, maPageFields.size() * 6 );
+ rStrm.SetSliceSize( 6 );
+ for( ScfUInt16Vec::const_iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ {
+ XclExpPTFieldRef xField = maFieldList.GetRecord( *aIt );
+ if( xField )
+ xField->WriteSxpiEntry( rStrm );
+ }
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxdiList( XclExpStream& rStrm ) const
+{
+ for( XclPTDataFieldPosVec::const_iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
+ {
+ XclExpPTFieldRef xField = maFieldList.GetRecord( aIt->first );
+ if( xField )
+ xField->WriteSxdi( rStrm, aIt->second );
+ }
+}
+
+void XclExpPivotTable::WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const
+{
+ if( nLineCount > 0 )
+ {
+ sal_uInt16 nLineSize = 8 + 2 * nIndexCount;
+ rStrm.StartRecord( EXC_ID_SXLI, nLineSize * nLineCount );
+
+ /* Excel expects the records to be filled completely, do not
+ set a segment size... */
+// rStrm.SetSliceSize( nLineSize );
+
+ for( sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
+ {
+ // Excel XP needs a partly initialized SXLI record
+ rStrm << sal_uInt16( 0 ) // number of equal index entries
+ << EXC_SXVI_TYPE_DATA
+ << nIndexCount
+ << EXC_SXLI_DEFAULTFLAGS;
+ rStrm.WriteZeroBytes( 2 * nIndexCount );
+ }
+ rStrm.EndRecord();
+ }
+}
+
+void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( EXC_ID_SXEX, 24 );
+ rStrm << maPTExtInfo;
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( 0x0802, 32 );
+
+ sal_uInt16 nRecordType = 0x0802;
+ sal_uInt16 nDummyFlags = 0x0000;
+ sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table
+
+ rStrm << nRecordType << nDummyFlags << nTableType;
+
+ // General flags
+ bool bEnableRefresh = true;
+ bool bPCacheInvalid = false;
+ bool bOlapPTReport = false;
+
+ sal_uInt16 nFlags = 0x0000;
+ if (bEnableRefresh) nFlags |= 0x0001;
+ if (bPCacheInvalid) nFlags |= 0x0002;
+ if (bOlapPTReport) nFlags |= 0x0004;
+ rStrm << nFlags;
+
+ // Feature-specific options. The value differs depending on the table
+ // type, but we assume the table type is always pivot table.
+ sal_uInt32 nOptions = 0x00000000;
+ bool bNoStencil = false;
+ bool bHideTotal = false;
+ bool bEmptyRows = false;
+ bool bEmptyCols = false;
+ if (bNoStencil) nOptions |= 0x00000001;
+ if (bHideTotal) nOptions |= 0x00000002;
+ if (bEmptyRows) nOptions |= 0x00000008;
+ if (bEmptyCols) nOptions |= 0x00000010;
+ rStrm << nOptions;
+
+ enum ExcelVersion
+ {
+ Excel2000 = 0,
+ ExcelXP = 1,
+ Excel2003 = 2,
+ Excel2007 = 3
+ };
+ ExcelVersion eXclVer = Excel2000;
+ sal_uInt8 nOffsetBytes = 16;
+ rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed
+ << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh
+ << nOffsetBytes
+ << static_cast<sal_uInt8>(eXclVer); // first version created
+
+ rStrm << XclExpString(maPTInfo.maTableName);
+ rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for.
+
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const
+{
+ // Until we sync the autoformat ids only export if using grid header layout
+ // That could only have been set via xls import so far.
+ if ( 0 == maPTViewEx9Info.mnGridLayout )
+ {
+ rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 );
+ rStrm << maPTViewEx9Info;
+ rStrm.EndRecord();
+ }
+}
+
+// ============================================================================
+
+namespace {
+
+const SCTAB EXC_PTMGR_PIVOTCACHES = SCTAB_MAX;
+
+/** Record wrapper class to write the pivot caches or pivot tables. */
+class XclExpPivotRecWrapper : public XclExpRecordBase
+{
+public:
+ explicit XclExpPivotRecWrapper( XclExpPivotTableManager& rPTMgr, SCTAB nScTab );
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ XclExpPivotTableManager& mrPTMgr;
+ SCTAB mnScTab;
+};
+
+XclExpPivotRecWrapper::XclExpPivotRecWrapper( XclExpPivotTableManager& rPTMgr, SCTAB nScTab ) :
+ mrPTMgr( rPTMgr ),
+ mnScTab( nScTab )
+{
+}
+
+void XclExpPivotRecWrapper::Save( XclExpStream& rStrm )
+{
+ if( mnScTab == EXC_PTMGR_PIVOTCACHES )
+ mrPTMgr.WritePivotCaches( rStrm );
+ else
+ mrPTMgr.WritePivotTables( rStrm, mnScTab );
+}
+
+void XclExpPivotRecWrapper::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnScTab == EXC_PTMGR_PIVOTCACHES )
+ mrPTMgr.WritePivotCachesXml( rStrm );
+ else
+ mrPTMgr.WritePivotTablesXml( rStrm, mnScTab );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpPivotTableManager::XclExpPivotTableManager( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mbShareCaches( true )
+{
+}
+
+void XclExpPivotTableManager::CreatePivotTables()
+{
+ if( ScDPCollection* pDPColl = GetDoc().GetDPCollection() )
+ for( size_t nDPObj = 0, nCount = pDPColl->GetCount(); nDPObj < nCount; ++nDPObj )
+ if( ScDPObject* pDPObj = (*pDPColl)[ nDPObj ] )
+ if( const XclExpPivotCache* pPCache = CreatePivotCache( *pDPObj ) )
+ maPTableList.AppendNewRecord( new XclExpPivotTable( GetRoot(), *pDPObj, *pPCache ) );
+}
+
+XclExpRecordRef XclExpPivotTableManager::CreatePivotCachesRecord()
+{
+ return XclExpRecordRef( new XclExpPivotRecWrapper( *this, EXC_PTMGR_PIVOTCACHES ) );
+}
+
+XclExpRecordRef XclExpPivotTableManager::CreatePivotTablesRecord( SCTAB nScTab )
+{
+ return XclExpRecordRef( new XclExpPivotRecWrapper( *this, nScTab ) );
+}
+
+void XclExpPivotTableManager::WritePivotCaches( XclExpStream& rStrm )
+{
+ maPCacheList.Save( rStrm );
+}
+
+void XclExpPivotTableManager::WritePivotCachesXml( XclExpXmlStream&
+#ifdef XLSX_PIVOT_CACHE
+ rStrm
+#endif
+)
+{
+#ifdef XLSX_PIVOT_CACHE /* <pivotCache> without xl/pivotCaches/ cacheStream
+ results in a broken .xlsx */
+ if( maPCacheList.IsEmpty() )
+ return;
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_pivotCaches, FSEND );
+ maPCacheList.SaveXml( rStrm );
+ rWorkbook->endElement( XML_pivotCaches );
+#endif /* XLSX_PIVOT_CACHE */
+}
+
+void XclExpPivotTableManager::WritePivotTables( XclExpStream& rStrm, SCTAB nScTab )
+{
+ for( size_t nPos = 0, nSize = maPTableList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotTableRef xPTable = maPTableList.GetRecord( nPos );
+ if( xPTable->GetScTab() == nScTab )
+ xPTable->Save( rStrm );
+ }
+}
+
+void XclExpPivotTableManager::WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab )
+{
+ for( size_t nPos = 0, nSize = maPTableList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotTableRef xPTable = maPTableList.GetRecord( nPos );
+ if( xPTable->GetScTab() == nScTab )
+ xPTable->SaveXml( rStrm );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+const XclExpPivotCache* XclExpPivotTableManager::CreatePivotCache( const ScDPObject& rDPObj )
+{
+ // try to find a pivot cache with the same data source
+ /* #i25110# In Excel, the pivot cache contains additional fields
+ (i.e. grouping info, calculated fields). If the passed DataPilot object
+ or the found cache contains this data, do not share the cache with
+ multiple pivot tables. */
+ if( mbShareCaches )
+ {
+ if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
+ {
+ const ScDPDimensionSaveData* pDimSaveData = pSaveData->GetExistingDimensionData();
+ // no dimension save data at all or save data does not contain grouping info
+ if( !pDimSaveData || !pDimSaveData->HasGroupDimensions() )
+ {
+ // check all existing pivot caches
+ for( size_t nPos = 0, nSize = maPCacheList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpPivotCacheRef xPCache = maPCacheList.GetRecord( nPos );
+ // pivot cache does not have grouping info and source data is equal
+ if( !xPCache->HasAddFields() && xPCache->HasEqualDataSource( rDPObj ) )
+ return xPCache.get();
+ }
+ }
+ }
+ }
+
+ // create a new pivot cache
+ sal_uInt16 nNewCacheIdx = static_cast< sal_uInt16 >( maPCacheList.GetSize() );
+ XclExpPivotCacheRef xNewPCache( new XclExpPivotCache( GetRoot(), rDPObj, nNewCacheIdx ) );
+ if( xNewPCache->IsValid() )
+ {
+ maPCacheList.AppendRecord( xNewPCache );
+ return xNewPCache.get();
+ }
+
+ return 0;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xerecord.cxx b/sc/source/filter/excel/xerecord.cxx
new file mode 100644
index 000000000000..f210efd1a4a1
--- /dev/null
+++ b/sc/source/filter/excel/xerecord.cxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+
+using namespace ::oox;
+
+// Base classes to export Excel records =======================================
+
+XclExpRecordBase::~XclExpRecordBase()
+{
+}
+
+void XclExpRecordBase::Save( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclExpRecordBase::SaveXml( XclExpXmlStream& /*rStrm*/ )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) :
+ mpRecord( pRecord )
+{
+}
+
+XclExpDelegatingRecord::~XclExpDelegatingRecord()
+{
+ // Do Nothing; we use Delegating Record for other objects we "know" will
+ // survive...
+}
+
+void XclExpDelegatingRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mpRecord )
+ mpRecord->SaveXml( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlElementRecord::XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : mnElement( nElement ), mpAttributes( pAttributes )
+{
+}
+
+XclExpXmlElementRecord::~XclExpXmlElementRecord()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlStartElementRecord::XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : XclExpXmlElementRecord( nElement, pAttributes )
+{
+}
+
+XclExpXmlStartElementRecord::~XclExpXmlStartElementRecord()
+{
+}
+
+void XclExpXmlStartElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
+ if( ! mpAttributes )
+ {
+ rStream->startElement( mnElement, FSEND );
+ }
+ else
+ {
+ rStream->write( "<" )->writeId( mnElement );
+ (*mpAttributes)( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlEndElementRecord::XclExpXmlEndElementRecord( sal_Int32 nElement )
+ : XclExpXmlElementRecord( nElement )
+{
+}
+
+XclExpXmlEndElementRecord::~XclExpXmlEndElementRecord()
+{
+}
+
+void XclExpXmlEndElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->endElement( mnElement );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlStartSingleElementRecord::XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
+ : XclExpXmlElementRecord( nElement, pAttributes )
+{
+}
+
+XclExpXmlStartSingleElementRecord::~XclExpXmlStartSingleElementRecord()
+{
+}
+
+void XclExpXmlStartSingleElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
+ rStream->write( "<" )->writeId( mnElement );
+ if( mpAttributes )
+ (*mpAttributes)( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXmlEndSingleElementRecord::XclExpXmlEndSingleElementRecord()
+{
+}
+
+XclExpXmlEndSingleElementRecord::~XclExpXmlEndSingleElementRecord()
+{
+}
+
+void XclExpXmlEndSingleElementRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->write( "/>" );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRecord::XclExpRecord( sal_uInt16 nRecId, sal_Size nRecSize ) :
+ mnRecSize( nRecSize ),
+ mnRecId( nRecId )
+{
+}
+
+XclExpRecord::~XclExpRecord()
+{
+}
+
+void XclExpRecord::SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize )
+{
+ SetRecId( nRecId );
+ SetRecSize( nRecSize );
+}
+
+void XclExpRecord::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclExpRecord::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mnRecId != EXC_ID_UNKNOWN, "XclExpRecord::Save - record ID uninitialized" );
+ rStrm.StartRecord( mnRecId, mnRecSize );
+ WriteBody( rStrm );
+ rStrm.EndRecord();
+}
+
+// ----------------------------------------------------------------------------
+
+template<>
+void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+ rStrm.WriteAttributes(
+ mnAttribute, rtl::OString::valueOf( maValue ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclExpBoolRecord::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt16 >( mbValue ? 1 : 0 );
+}
+
+void XclExpBoolRecord::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+
+ rStrm.WriteAttributes(
+ // HACK: HIDEOBJ (excdoc.cxx) should be its own object to handle XML_showObjects
+ mnAttribute, mnAttribute == XML_showObjects ? "all" : XclXmlUtils::ToPsz( mbValue ),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDummyRecord::XclExpDummyRecord( sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize ) :
+ XclExpRecord( nRecId )
+{
+ SetData( pRecData, nRecSize );
+}
+
+void XclExpDummyRecord::SetData( const void* pRecData, sal_Size nRecSize )
+{
+ mpData = pRecData;
+ SetRecSize( pRecData ? nRecSize : 0 );
+}
+
+void XclExpDummyRecord::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.Write( mpData, GetRecSize() );
+}
+
+// Future records =============================================================
+
+XclExpFutureRecord::XclExpFutureRecord( XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
+ XclExpRecord( nRecId, nRecSize ),
+ meRecType( eRecType )
+{
+}
+
+void XclExpFutureRecord::Save( XclExpStream& rStrm )
+{
+ rStrm.StartRecord( GetRecId(), GetRecSize() + ((meRecType == EXC_FUTUREREC_UNUSEDREF) ? 12 : 4) );
+ rStrm << GetRecId() << sal_uInt16( 0 );
+ if( meRecType == EXC_FUTUREREC_UNUSEDREF )
+ rStrm.WriteZeroBytes( 8 );
+ WriteBody( rStrm );
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
+XclExpSubStream::XclExpSubStream( sal_uInt16 nSubStrmType ) :
+ mnSubStrmType( nSubStrmType )
+{
+}
+
+void XclExpSubStream::Save( XclExpStream& rStrm )
+{
+ // BOF record
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ rStrm.StartRecord( EXC_ID2_BOF, 4 );
+ rStrm << sal_uInt16( 7 ) << mnSubStrmType;
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF3:
+ rStrm.StartRecord( EXC_ID3_BOF, 6 );
+ rStrm << sal_uInt16( 0 ) << mnSubStrmType << sal_uInt16( 2104 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF4:
+ rStrm.StartRecord( EXC_ID4_BOF, 6 );
+ rStrm << sal_uInt16( 0 ) << mnSubStrmType << sal_uInt16( 1705 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF5:
+ rStrm.StartRecord( EXC_ID5_BOF, 8 );
+ rStrm << EXC_BOF_BIFF5 << mnSubStrmType << sal_uInt16( 4915 ) << sal_uInt16( 1994 );
+ rStrm.EndRecord();
+ break;
+ case EXC_BIFF8:
+ rStrm.StartRecord( EXC_ID5_BOF, 16 );
+ rStrm << EXC_BOF_BIFF8 << mnSubStrmType << sal_uInt16( 3612 ) << sal_uInt16( 1996 );
+ rStrm << sal_uInt32( 1 ) << sal_uInt32( 6 );
+ rStrm.EndRecord();
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+
+ // substream records
+ XclExpRecordList<>::Save( rStrm );
+
+ // EOF record
+ rStrm.StartRecord( EXC_ID_EOF, 0 );
+ rStrm.EndRecord();
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
new file mode 100644
index 000000000000..d72f9c77d61d
--- /dev/null
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -0,0 +1,319 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <rtl/random.h>
+#include <sfx2/docfile.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <unotools/saveopt.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include "xecontent.hxx"
+#include "xltracer.hxx"
+#include "xeescher.hxx"
+#include "xeformula.hxx"
+#include "xehelper.hxx"
+#include "xelink.hxx"
+#include "xename.hxx"
+#include "xepivot.hxx"
+#include "xestyle.hxx"
+#include "xeroot.hxx"
+
+#include "excrecds.hxx" // for filter manager
+#include "tabprotection.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+
+using namespace ::com::sun::star;
+
+// Global data ================================================================
+
+XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
+ XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, true )
+{
+ SvtSaveOptions aSaveOpt;
+ mbRelUrl = mrMedium.IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
+}
+
+XclExpRootData::~XclExpRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRoot::XclExpRoot( XclExpRootData& rExpRootData ) :
+ XclRoot( rExpRootData ),
+ mrExpData( rExpRootData )
+{
+}
+
+XclExpTabInfo& XclExpRoot::GetTabInfo() const
+{
+ DBG_ASSERT( mrExpData.mxTabInfo, "XclExpRoot::GetTabInfo - missing object (wrong BIFF?)" );
+ return *mrExpData.mxTabInfo;
+}
+
+XclExpAddressConverter& XclExpRoot::GetAddressConverter() const
+{
+ DBG_ASSERT( mrExpData.mxAddrConv, "XclExpRoot::GetAddressConverter - missing object (wrong BIFF?)" );
+ return *mrExpData.mxAddrConv;
+}
+
+XclExpFormulaCompiler& XclExpRoot::GetFormulaCompiler() const
+{
+ DBG_ASSERT( mrExpData.mxFmlaComp, "XclExpRoot::GetFormulaCompiler - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFmlaComp;
+}
+
+XclExpProgressBar& XclExpRoot::GetProgressBar() const
+{
+ DBG_ASSERT( mrExpData.mxProgress, "XclExpRoot::GetProgressBar - missing object (wrong BIFF?)" );
+ return *mrExpData.mxProgress;
+}
+
+XclExpSst& XclExpRoot::GetSst() const
+{
+ DBG_ASSERT( mrExpData.mxSst, "XclExpRoot::GetSst - missing object (wrong BIFF?)" );
+ return *mrExpData.mxSst;
+}
+
+XclExpPalette& XclExpRoot::GetPalette() const
+{
+ DBG_ASSERT( mrExpData.mxPalette, "XclExpRoot::GetPalette - missing object (wrong BIFF?)" );
+ return *mrExpData.mxPalette;
+}
+
+XclExpFontBuffer& XclExpRoot::GetFontBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxFontBfr, "XclExpRoot::GetFontBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFontBfr;
+}
+
+XclExpNumFmtBuffer& XclExpRoot::GetNumFmtBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxNumFmtBfr, "XclExpRoot::GetNumFmtBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxNumFmtBfr;
+}
+
+XclExpXFBuffer& XclExpRoot::GetXFBuffer() const
+{
+ DBG_ASSERT( mrExpData.mxXFBfr, "XclExpRoot::GetXFBuffer - missing object (wrong BIFF?)" );
+ return *mrExpData.mxXFBfr;
+}
+
+XclExpLinkManager& XclExpRoot::GetGlobalLinkManager() const
+{
+ DBG_ASSERT( mrExpData.mxGlobLinkMgr, "XclExpRoot::GetGlobalLinkManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxGlobLinkMgr;
+}
+
+XclExpLinkManager& XclExpRoot::GetLocalLinkManager() const
+{
+ DBG_ASSERT( GetLocalLinkMgrRef(), "XclExpRoot::GetLocalLinkManager - missing object (wrong BIFF?)" );
+ return *GetLocalLinkMgrRef();
+}
+
+XclExpNameManager& XclExpRoot::GetNameManager() const
+{
+ DBG_ASSERT( mrExpData.mxNameMgr, "XclExpRoot::GetNameManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxNameMgr;
+}
+
+XclExpObjectManager& XclExpRoot::GetObjectManager() const
+{
+ DBG_ASSERT( mrExpData.mxObjMgr, "XclExpRoot::GetObjectManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxObjMgr;
+}
+
+XclExpFilterManager& XclExpRoot::GetFilterManager() const
+{
+ DBG_ASSERT( mrExpData.mxFilterMgr, "XclExpRoot::GetFilterManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxFilterMgr;
+}
+
+XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const
+{
+ DBG_ASSERT( mrExpData.mxPTableMgr, "XclExpRoot::GetPivotTableManager - missing object (wrong BIFF?)" );
+ return *mrExpData.mxPTableMgr;
+}
+
+void XclExpRoot::InitializeConvert()
+{
+ mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) );
+ mrExpData.mxAddrConv.reset( new XclExpAddressConverter( GetRoot() ) );
+ mrExpData.mxFmlaComp.reset( new XclExpFormulaCompiler( GetRoot() ) );
+ mrExpData.mxProgress.reset( new XclExpProgressBar( GetRoot() ) );
+
+ GetProgressBar().Initialize();
+}
+
+void XclExpRoot::InitializeGlobals()
+{
+ SetCurrScTab( SCTAB_GLOBAL );
+
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ mrExpData.mxPalette.reset( new XclExpPalette( GetRoot() ) );
+ mrExpData.mxFontBfr.reset( new XclExpFontBuffer( GetRoot() ) );
+ mrExpData.mxNumFmtBfr.reset( new XclExpNumFmtBuffer( GetRoot() ) );
+ mrExpData.mxXFBfr.reset( new XclExpXFBuffer( GetRoot() ) );
+ mrExpData.mxGlobLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
+ mrExpData.mxNameMgr.reset( new XclExpNameManager( GetRoot() ) );
+ }
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mrExpData.mxSst.reset( new XclExpSst );
+ mrExpData.mxObjMgr.reset( new XclExpObjectManager( GetRoot() ) );
+ mrExpData.mxFilterMgr.reset( new XclExpFilterManager( GetRoot() ) );
+ mrExpData.mxPTableMgr.reset( new XclExpPivotTableManager( GetRoot() ) );
+ // BIFF8: only one link manager for all sheets
+ mrExpData.mxLocLinkMgr = mrExpData.mxGlobLinkMgr;
+ }
+
+ GetXFBuffer().Initialize();
+ GetNameManager().Initialize();
+}
+
+void XclExpRoot::InitializeTable( SCTAB nScTab )
+{
+ SetCurrScTab( nScTab );
+ if( GetBiff() == EXC_BIFF5 )
+ {
+ // local link manager per sheet
+ mrExpData.mxLocLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
+ }
+}
+
+void XclExpRoot::InitializeSave()
+{
+ GetPalette().Finalize();
+ GetXFBuffer().Finalize();
+}
+
+XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const
+{
+ XclExpRecordRef xRec;
+ switch( nRecId )
+ {
+ case EXC_ID_PALETTE: xRec = mrExpData.mxPalette; break;
+ case EXC_ID_FONTLIST: xRec = mrExpData.mxFontBfr; break;
+ case EXC_ID_FORMATLIST: xRec = mrExpData.mxNumFmtBfr; break;
+ case EXC_ID_XFLIST: xRec = mrExpData.mxXFBfr; break;
+ case EXC_ID_SST: xRec = mrExpData.mxSst; break;
+ case EXC_ID_EXTERNSHEET: xRec = GetLocalLinkMgrRef(); break;
+ case EXC_ID_NAME: xRec = mrExpData.mxNameMgr; break;
+ }
+ DBG_ASSERT( xRec, "XclExpRoot::CreateRecord - unknown record ID or missing object" );
+ return xRec;
+}
+
+bool XclExpRoot::IsDocumentEncrypted() const
+{
+ // We need to encrypt the content when the document structure is protected.
+ const ScDocProtection* pDocProt = GetDoc().GetDocProtection();
+ if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE))
+ return true;
+
+ if ( GetEncryptionData().getLength() > 0 )
+ // Password is entered directly into the save dialog.
+ return true;
+
+ return false;
+}
+
+uno::Sequence< beans::NamedValue > XclExpRoot::GenerateEncryptionData( const ::rtl::OUString& aPass ) const
+{
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+
+ if ( aPass.getLength() > 0 && aPass.getLength() < 16 )
+ {
+ TimeValue aTime;
+ osl_getSystemTime( &aTime );
+ rtlRandomPool aRandomPool = rtl_random_createPool ();
+ rtl_random_addBytes ( aRandomPool, &aTime, 8 );
+
+ sal_uInt8 pnDocId[16];
+ rtl_random_getBytes( aRandomPool, pnDocId, 16 );
+
+ rtl_random_destroyPool( aRandomPool );
+
+ sal_uInt16 pnPasswd[16];
+ memset( pnPasswd, 0, sizeof( pnPasswd ) );
+ for (xub_StrLen nChar = 0; nChar < aPass.getLength(); ++nChar )
+ pnPasswd[nChar] = aPass.getStr()[nChar];
+
+ ::msfilter::MSCodec_Std97 aCodec;
+ aCodec.InitKey( pnPasswd, pnDocId );
+ aEncryptionData = aCodec.GetEncryptionData();
+ }
+
+ return aEncryptionData;
+}
+
+uno::Sequence< beans::NamedValue > XclExpRoot::GetEncryptionData() const
+{
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
+ if ( pEncryptionDataItem )
+ pEncryptionDataItem->GetValue() >>= aEncryptionData;
+ else
+ {
+ // try to get the encryption data from the password
+ SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false );
+ if ( pPasswordItem && pPasswordItem->GetValue().Len() )
+ aEncryptionData = GenerateEncryptionData( pPasswordItem->GetValue() );
+ }
+
+ return aEncryptionData;
+}
+
+uno::Sequence< beans::NamedValue > XclExpRoot::GenerateDefaultEncryptionData() const
+{
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ if ( GetDefaultPassword().Len() > 0 )
+ aEncryptionData = GenerateEncryptionData( GetDefaultPassword() );
+
+ return aEncryptionData;
+}
+
+XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const
+{
+ return IsInGlobals() ? mrExpData.mxGlobLinkMgr : mrExpData.mxLocLinkMgr;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
new file mode 100644
index 000000000000..4e2798e06ee9
--- /dev/null
+++ b/sc/source/filter/excel/xestream.cxx
@@ -0,0 +1,1221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <utility>
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/random.h>
+#include <sax/fshelper.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include "precompiled_sc.hxx"
+#include "docuno.hxx"
+#include "xestream.hxx"
+#include "xladdress.hxx"
+#include "xlstring.hxx"
+#include "xeroot.hxx"
+#include "xestyle.hxx"
+#include "xcl97rec.hxx"
+#include "rangelst.hxx"
+#include "compiler.hxx"
+
+#include <../../ui/inc/docsh.hxx>
+#include <../../ui/inc/viewdata.hxx>
+#include <excdoc.hxx>
+
+#include <oox/token/tokens.hxx>
+#include <formula/grammar.hxx>
+#include <oox/export/drawingml.hxx>
+#include <oox/xls/excelvbaproject.hxx>
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#define DEBUG_XL_ENCRYPTION 0
+
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::embed::XStorage;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::io::XStream;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::lang::XSingleServiceFactory;
+using ::com::sun::star::registry::InvalidRegistryException;
+using ::com::sun::star::registry::XRegistryKey;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::XInterface;
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::utl::OStreamWrapper;
+using ::std::vector;
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+using namespace ::formula;
+using namespace ::oox;
+
+// ============================================================================
+
+XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
+ mrStrm( rOutStrm ),
+ mrRoot( rRoot ),
+ mnMaxRecSize( nMaxRecSize ),
+ mnCurrMaxSize( 0 ),
+ mnMaxSliceSize( 0 ),
+ mnHeaderSize( 0 ),
+ mnCurrSize( 0 ),
+ mnSliceSize( 0 ),
+ mnPredictSize( 0 ),
+ mnLastSizePos( 0 ),
+ mbInRec( false )
+{
+ if( mnMaxRecSize == 0 )
+ mnMaxRecSize = (mrRoot.GetBiff() <= EXC_BIFF5) ? EXC_MAXRECSIZE_BIFF5 : EXC_MAXRECSIZE_BIFF8;
+ mnMaxContSize = mnMaxRecSize;
+}
+
+XclExpStream::~XclExpStream()
+{
+ mrStrm.Flush();
+}
+
+void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
+{
+ DBG_ASSERT( !mbInRec, "XclExpStream::StartRecord - another record still open" );
+ DisableEncryption();
+ mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
+ mnPredictSize = nRecSize;
+ mbInRec = true;
+ InitRecord( nRecId );
+ SetSliceSize( 0 );
+ EnableEncryption();
+}
+
+void XclExpStream::EndRecord()
+{
+ DBG_ASSERT( mbInRec, "XclExpStream::EndRecord - no record open" );
+ DisableEncryption();
+ UpdateRecSize();
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mbInRec = false;
+}
+
+void XclExpStream::SetSliceSize( sal_uInt16 nSize )
+{
+ mnMaxSliceSize = nSize;
+ mnSliceSize = 0;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( float fValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( double fValue )
+{
+ PrepareWrite( 8 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
+sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( pData && (nBytes > 0) )
+ {
+ if( mbInRec )
+ {
+ const sal_uInt8* pBuffer = reinterpret_cast< const sal_uInt8* >( pData );
+ sal_Size nBytesLeft = nBytes;
+ bool bValid = true;
+
+ while( bValid && (nBytesLeft > 0) )
+ {
+ sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
+ sal_Size nWriteRet = nWriteLen;
+ if (mbUseEncrypter && HasValidEncrypter())
+ {
+ DBG_ASSERT(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
+ vector<sal_uInt8> aBytes(nWriteLen);
+ memcpy(&aBytes[0], pBuffer, nWriteLen);
+ mxEncrypter->EncryptBytes(mrStrm, aBytes);
+ // TODO: How do I check if all the bytes have been successfully written ?
+ }
+ else
+ {
+ nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
+ bValid = (nWriteLen == nWriteRet);
+ DBG_ASSERT( bValid, "XclExpStream::Write - stream write error" );
+ }
+ pBuffer += nWriteRet;
+ nRet += nWriteRet;
+ nBytesLeft -= nWriteRet;
+ UpdateSizeVars( nWriteRet );
+ }
+ }
+ else
+ nRet = mrStrm.Write( pData, nBytes );
+ }
+ return nRet;
+}
+
+void XclExpStream::WriteZeroBytes( sal_Size nBytes )
+{
+ if( mbInRec )
+ {
+ sal_Size nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
+ WriteRawZeroBytes( nWriteLen );
+ nBytesLeft -= nWriteLen;
+ UpdateSizeVars( nWriteLen );
+ }
+ }
+ else
+ WriteRawZeroBytes( nBytes );
+}
+
+void XclExpStream::WriteZeroBytesToRecord( sal_Size nBytes )
+{
+ if (!mbInRec)
+ // not in record.
+ return;
+
+ sal_uInt8 nZero = 0;
+ for (sal_Size i = 0; i < nBytes; ++i)
+ *this << nZero;
+}
+
+sal_Size XclExpStream::CopyFromStream( SvStream& rInStrm, sal_Size nBytes )
+{
+ sal_Size nStrmPos = rInStrm.Tell();
+ rInStrm.Seek( STREAM_SEEK_TO_END );
+ sal_Size nStrmSize = rInStrm.Tell();
+ rInStrm.Seek( nStrmPos );
+
+ sal_Size nBytesLeft = ::std::min( nBytes, nStrmSize - nStrmPos );
+ sal_Size nRet = 0;
+ if( nBytesLeft > 0 )
+ {
+ const sal_Size nMaxBuffer = 4096;
+ sal_uInt8* pBuffer = new sal_uInt8[ ::std::min( nBytesLeft, nMaxBuffer ) ];
+ bool bValid = true;
+
+ while( bValid && (nBytesLeft > 0) )
+ {
+ sal_Size nWriteLen = ::std::min( nBytesLeft, nMaxBuffer );
+ rInStrm.Read( pBuffer, nWriteLen );
+ sal_Size nWriteRet = Write( pBuffer, nWriteLen );
+ bValid = (nWriteLen == nWriteRet);
+ nRet += nWriteRet;
+ nBytesLeft -= nWriteRet;
+ }
+ delete[] pBuffer;
+ }
+ return nRet;
+}
+
+void XclExpStream::WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags )
+{
+ SetSliceSize( 0 );
+ nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
+ sal_uInt16 nCharLen = nFlags ? 2 : 1;
+
+ ScfUInt16Vec::const_iterator aEnd = rBuffer.end();
+ for( ScfUInt16Vec::const_iterator aIter = rBuffer.begin(); aIter != aEnd; ++aIter )
+ {
+ if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
+ {
+ StartContinue();
+ operator<<( nFlags );
+ }
+ if( nCharLen == 2 )
+ operator<<( *aIter );
+ else
+ operator<<( static_cast< sal_uInt8 >( *aIter ) );
+ }
+}
+
+// Xcl has an obscure sense of whether starting a new record or not,
+// and crashes if it encounters the string header at the very end of a record.
+// Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
+void XclExpStream::WriteByteString( const ByteString& rString, sal_uInt16 nMaxLen, bool b16BitCount )
+{
+ SetSliceSize( 0 );
+ sal_Size nLen = ::std::min< sal_Size >( rString.Len(), nMaxLen );
+ if( !b16BitCount )
+ nLen = ::std::min< sal_Size >( nLen, 0xFF );
+
+ sal_uInt16 nLeft = PrepareWrite();
+ sal_uInt16 nLenFieldSize = b16BitCount ? 2 : 1;
+ if( mbInRec && (nLeft <= nLenFieldSize) )
+ StartContinue();
+
+ if( b16BitCount )
+ operator<<( static_cast< sal_uInt16 >( nLen ) );
+ else
+ operator<<( static_cast< sal_uInt8 >( nLen ) );
+ Write( rString.GetBuffer(), nLen );
+}
+
+void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
+{
+ SetSliceSize( 0 );
+ Write( &rBuffer[ 0 ], rBuffer.size() );
+}
+
+void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
+{
+ mxEncrypter = xEncrypter;
+}
+
+bool XclExpStream::HasValidEncrypter() const
+{
+ return mxEncrypter && mxEncrypter->IsValid();
+}
+
+void XclExpStream::EnableEncryption( bool bEnable )
+{
+ mbUseEncrypter = bEnable && HasValidEncrypter();
+}
+
+void XclExpStream::DisableEncryption()
+{
+ EnableEncryption(false);
+}
+
+sal_Size XclExpStream::SetSvStreamPos( sal_Size nPos )
+{
+ DBG_ASSERT( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
+ return mbInRec ? 0 : mrStrm.Seek( nPos );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpStream::InitRecord( sal_uInt16 nRecId )
+{
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mrStrm << nRecId;
+
+ mnLastSizePos = mrStrm.Tell();
+ mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( mnPredictSize, mnCurrMaxSize ) );
+ mrStrm << mnHeaderSize;
+ mnCurrSize = mnSliceSize = 0;
+}
+
+void XclExpStream::UpdateRecSize()
+{
+ if( mnCurrSize != mnHeaderSize )
+ {
+ mrStrm.Seek( mnLastSizePos );
+ mrStrm << mnCurrSize;
+ }
+}
+
+void XclExpStream::UpdateSizeVars( sal_Size nSize )
+{
+ DBG_ASSERT( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
+ mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
+
+ if( mnMaxSliceSize > 0 )
+ {
+ DBG_ASSERT( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
+ mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
+ if( mnSliceSize >= mnMaxSliceSize )
+ mnSliceSize = 0;
+ }
+}
+
+void XclExpStream::StartContinue()
+{
+ UpdateRecSize();
+ mnCurrMaxSize = mnMaxContSize;
+ mnPredictSize -= mnCurrSize;
+ InitRecord( EXC_ID_CONT );
+}
+
+void XclExpStream::PrepareWrite( sal_uInt16 nSize )
+{
+ if( mbInRec )
+ {
+ if( (mnCurrSize + nSize > mnCurrMaxSize) ||
+ ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
+ StartContinue();
+ UpdateSizeVars( nSize );
+ }
+}
+
+sal_uInt16 XclExpStream::PrepareWrite()
+{
+ sal_uInt16 nRet = 0;
+ if( mbInRec )
+ {
+ if( (mnCurrSize >= mnCurrMaxSize) ||
+ ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
+ StartContinue();
+ UpdateSizeVars( 0 );
+
+ nRet = (mnMaxSliceSize > 0) ? (mnMaxSliceSize - mnSliceSize) : (mnCurrMaxSize - mnCurrSize);
+ }
+ return nRet;
+}
+
+void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
+{
+ const sal_uInt32 nData = 0;
+ sal_Size nBytesLeft = nBytes;
+ while( nBytesLeft >= sizeof( nData ) )
+ {
+ mrStrm << nData;
+ nBytesLeft -= sizeof( nData );
+ }
+ if( nBytesLeft )
+ mrStrm.Write( &nData, nBytesLeft );
+}
+
+// ============================================================================
+
+XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot ) :
+ mrRoot(rRoot),
+ mnOldPos(STREAM_SEEK_TO_END),
+ mbValid(false)
+{
+ Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData();
+ if( !aEncryptionData.hasElements() )
+ // Empty password. Get the default biff8 password.
+ aEncryptionData = rRoot.GenerateDefaultEncryptionData();
+ Init( aEncryptionData );
+}
+
+XclExpBiff8Encrypter::~XclExpBiff8Encrypter()
+{
+}
+
+bool XclExpBiff8Encrypter::IsValid() const
+{
+ return mbValid;
+}
+
+void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const
+{
+ if ( sizeof( mpnSaltDigest ) == 16 )
+ memcpy( pnSaltDigest, mpnSaltDigest, 16 );
+}
+
+void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const
+{
+ if ( sizeof( mpnSalt ) == 16 )
+ memcpy( pnSalt, mpnSalt, 16 );
+}
+
+void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const
+{
+ if ( sizeof( mpnDocId ) == 16 )
+ memcpy( pnDocId, mpnDocId, 16 );
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData )
+{
+ vector<sal_uInt8> aByte(1);
+ aByte[0] = nData;
+ EncryptBytes(rStrm, aByte);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
+{
+ ::std::vector<sal_uInt8> pnBytes(2);
+ pnBytes[0] = nData & 0xFF;
+ pnBytes[1] = (nData >> 8) & 0xFF;
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
+{
+ ::std::vector<sal_uInt8> pnBytes(4);
+ pnBytes[0] = nData & 0xFF;
+ pnBytes[1] = (nData >> 8) & 0xFF;
+ pnBytes[2] = (nData >> 16) & 0xFF;
+ pnBytes[3] = (nData >> 24) & 0xFF;
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
+{
+ ::std::vector<sal_uInt8> pnBytes(4);
+ memcpy(&pnBytes[0], &fValue, 4);
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
+{
+ ::std::vector<sal_uInt8> pnBytes(8);
+ memcpy(&pnBytes[0], &fValue, 8);
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int8 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt8>(nData));
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt16>(nData));
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt32>(nData));
+}
+
+void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
+{
+ mbValid = false;
+
+ if( maCodec.InitCodec( rEncryptionData ) )
+ {
+ maCodec.GetDocId( mpnDocId );
+
+ // generate the salt here
+ TimeValue aTime;
+ osl_getSystemTime( &aTime );
+ rtlRandomPool aRandomPool = rtl_random_createPool ();
+ rtl_random_addBytes( aRandomPool, &aTime, 8 );
+ rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
+ rtl_random_destroyPool( aRandomPool );
+
+ memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
+
+ // generate salt hash.
+ ::msfilter::MSCodec_Std97 aCodec;
+ aCodec.InitCodec( rEncryptionData );
+ aCodec.CreateSaltDigest( mpnSalt, mpnSaltDigest );
+
+ // verify to make sure it's in good shape.
+ mbValid = maCodec.VerifyKey( mpnSalt, mpnSaltDigest );
+ }
+}
+
+sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
+}
+
+sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
+}
+
+void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
+{
+ sal_Size nStrmPos = rStrm.Tell();
+ sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
+ sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
+
+#if DEBUG_XL_ENCRYPTION
+ fprintf(stdout, "XclExpBiff8Encrypter::EncryptBytes: stream pos = %ld offset in block = %d block pos = %ld\n",
+ nStrmPos, nBlockOffset, nBlockPos);
+#endif
+
+ sal_uInt16 nSize = static_cast< sal_uInt16 >( aBytes.size() );
+ if (nSize == 0)
+ return;
+
+#if DEBUG_XL_ENCRYPTION
+ fprintf(stdout, "RAW: ");
+ for (sal_uInt16 i = 0; i < nSize; ++i)
+ fprintf(stdout, "%2.2X ", aBytes[i]);
+ fprintf(stdout, "\n");
+#endif
+
+ if (mnOldPos != nStrmPos)
+ {
+ sal_uInt16 nOldOffset = GetOffsetInBlock(mnOldPos);
+ sal_uInt32 nOldBlockPos = GetBlockPos(mnOldPos);
+
+ if ( (nBlockPos != nOldBlockPos) || (nBlockOffset < nOldOffset) )
+ {
+ maCodec.InitCipher(nBlockPos);
+ nOldOffset = 0;
+ }
+
+ if (nBlockOffset > nOldOffset)
+ maCodec.Skip(nBlockOffset - nOldOffset);
+ }
+
+ sal_uInt16 nBytesLeft = nSize;
+ sal_uInt16 nPos = 0;
+ while (nBytesLeft > 0)
+ {
+ sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - nBlockOffset;
+ sal_uInt16 nEncBytes = ::std::min(nBlockLeft, nBytesLeft);
+
+ bool bRet = maCodec.Encode(&aBytes[nPos], nEncBytes, &aBytes[nPos], nEncBytes);
+ DBG_ASSERT(bRet, "XclExpBiff8Encrypter::EncryptBytes: encryption failed!!");
+ bRet = bRet; // to remove a silly compiler warning.
+
+ sal_Size nRet = rStrm.Write(&aBytes[nPos], nEncBytes);
+ DBG_ASSERT(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
+ nRet = nRet; // to remove a silly compiler warning.
+
+ nStrmPos = rStrm.Tell();
+ nBlockOffset = GetOffsetInBlock(nStrmPos);
+ nBlockPos = GetBlockPos(nStrmPos);
+ if (nBlockOffset == 0)
+ maCodec.InitCipher(nBlockPos);
+
+ nBytesLeft -= nEncBytes;
+ nPos += nEncBytes;
+ }
+ mnOldPos = nStrmPos;
+}
+
+static const char* lcl_GetErrorString( sal_uInt16 nScErrCode )
+{
+ sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
+ switch( nXclErrCode )
+ {
+ case EXC_ERR_NULL: return "#NULL!";
+ case EXC_ERR_DIV0: return "#DIV/0!";
+ case EXC_ERR_VALUE: return "#VALUE!";
+ case EXC_ERR_REF: return "#REF!";
+ case EXC_ERR_NAME: return "#NAME?";
+ case EXC_ERR_NUM: return "#NUM!";
+ case EXC_ERR_NA:
+ default: return "#N/A";
+ }
+}
+
+void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
+{
+ switch( rCell.GetFormatType() )
+ {
+ case NUMBERFORMAT_NUMBER:
+ {
+ // either value or error code
+ sal_uInt16 nScErrCode = rCell.GetErrCode();
+ if( nScErrCode )
+ {
+ rsType = "e";
+ rsValue = ToOUString( lcl_GetErrorString( nScErrCode ) );
+ }
+ else
+ {
+ rsType = "n";
+ rsValue = OUString::valueOf( rCell.GetValue() );
+ }
+ }
+ break;
+
+ case NUMBERFORMAT_TEXT:
+ {
+ rsType = "str";
+ String aResult;
+ rCell.GetString( aResult );
+ rsValue = ToOUString( aResult );
+ }
+ break;
+
+ case NUMBERFORMAT_LOGICAL:
+ {
+ rsType = "b";
+ rsValue = ToOUString( rCell.GetValue() == 0.0 ? "0" : "1" );
+ }
+ break;
+
+ default:
+ {
+ rsType = "inlineStr";
+ String aResult;
+ rCell.GetString( aResult );
+ rsValue = ToOUString( aResult );
+ }
+ break;
+ }
+}
+
+rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
+{
+ OUStringBuffer sBuf;
+ if( sStreamDir )
+ sBuf.appendAscii( sStreamDir );
+ sBuf.appendAscii( sStream );
+ if( nId )
+ sBuf.append( nId );
+ if( strstr(sStream, "vml") )
+ sBuf.appendAscii( ".vml" );
+ else
+ sBuf.appendAscii( ".xml" );
+ return sBuf.makeStringAndClear();
+}
+
+OString XclXmlUtils::ToOString( const Color& rColor )
+{
+ char buf[9];
+ sprintf( buf, "%.2X%.2X%.2X%.2X", rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
+ buf[8] = '\0';
+ return OString( buf );
+}
+
+OString XclXmlUtils::ToOString( const OUString& s )
+{
+ return OUStringToOString( s, RTL_TEXTENCODING_UTF8 );
+}
+
+OString XclXmlUtils::ToOString( const String& s )
+{
+ return OString( s.GetBuffer(), s.Len(), RTL_TEXTENCODING_UTF8 );
+}
+
+OString XclXmlUtils::ToOString( const ScAddress& rAddress )
+{
+ String sAddress;
+ rAddress.Format( sAddress, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
+ return ToOString( sAddress );
+}
+
+OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
+{
+ const sal_uInt16* pBuffer = &rBuffer [0];
+ return OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 );
+}
+
+OString XclXmlUtils::ToOString( const ScRange& rRange )
+{
+ String sRange;
+ rRange.Format( sRange, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
+ return ToOString( sRange );
+}
+
+OString XclXmlUtils::ToOString( const ScRangeList& rRangeList )
+{
+ String s;
+ rRangeList.Format( s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ' );
+ return ToOString( s );
+}
+
+static ScAddress lcl_ToAddress( const XclAddress& rAddress )
+{
+ ScAddress aAddress;
+
+ // For some reason, ScRange::Format() returns omits row numbers if
+ // the row is >= MAXROW or the column is >= MAXCOL, and Excel doesn't
+ // like "A:IV" (i.e. no row numbers). Prevent this.
+ // KOHEI: Find out if the above comment is still true.
+ aAddress.SetRow( std::min<sal_Int32>( rAddress.mnRow, MAXROW ) );
+ aAddress.SetCol( static_cast<sal_Int16>(std::min<sal_Int32>( rAddress.mnCol, MAXCOL )) );
+
+ return aAddress;
+}
+
+OString XclXmlUtils::ToOString( const XclAddress& rAddress )
+{
+ return ToOString( lcl_ToAddress( rAddress ) );
+}
+
+OString XclXmlUtils::ToOString( const XclExpString& s )
+{
+ DBG_ASSERT( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
+ return ToOString( s.GetUnicodeBuffer() );
+}
+
+static ScRange lcl_ToRange( const XclRange& rRange )
+{
+ ScRange aRange;
+
+ aRange.aStart = lcl_ToAddress( rRange.maFirst );
+ aRange.aEnd = lcl_ToAddress( rRange.maLast );
+
+ return aRange;
+}
+
+rtl::OString XclXmlUtils::ToOString( const XclRange& rRange )
+{
+ return ToOString( lcl_ToRange( rRange ) );
+}
+
+rtl::OString XclXmlUtils::ToOString( const XclRangeList& rRanges )
+{
+ ScRangeList aRanges;
+ for( XclRangeList::const_iterator i = rRanges.begin(), end = rRanges.end();
+ i != end; ++i )
+ {
+ aRanges.Append( lcl_ToRange( *i ) );
+ }
+ return ToOString( aRanges );
+}
+
+OUString XclXmlUtils::ToOUString( const char* s )
+{
+ return OUString( s, (sal_Int32) strlen( s ), RTL_TEXTENCODING_ASCII_US );
+}
+
+OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
+{
+ if( nLength == -1 || ( nLength > (rBuf.size() - nStart) ) )
+ nLength = (rBuf.size() - nStart);
+
+ return (nLength > 0) ? OUString( &rBuf[nStart], nLength ) : OUString();
+}
+
+OUString XclXmlUtils::ToOUString( const String& s )
+{
+ return OUString( s.GetBuffer(), s.Len() );
+}
+
+OUString XclXmlUtils::ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray )
+{
+ ScCompiler aCompiler( &rDocument, rAddress, *pTokenArray);
+ aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH_XL_A1);
+ String s;
+ aCompiler.CreateStringFromTokenArray( s );
+ return ToOUString( s );
+}
+
+OUString XclXmlUtils::ToOUString( const XclExpString& s )
+{
+ DBG_ASSERT( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
+ return ToOUString( s.GetUnicodeBuffer() );
+}
+
+const char* XclXmlUtils::ToPsz( bool b )
+{
+ return b ? "true" : "false";
+}
+
+sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue )
+{
+ pStream->startElement( nElement, FSEND );
+ pStream->write( nValue );
+ pStream->endElement( nElement );
+
+ return pStream;
+}
+
+sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue )
+{
+ pStream->startElement( nElement, FSEND );
+ pStream->write( nValue );
+ pStream->endElement( nElement );
+
+ return pStream;
+}
+
+sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue )
+{
+ pStream->startElement( nElement, FSEND );
+ pStream->write( sValue );
+ pStream->endElement( nElement );
+
+ return pStream;
+}
+
+static void lcl_WriteValue( sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
+{
+ if( !pValue )
+ return;
+ rStream->singleElement( nElement,
+ XML_val, pValue,
+ FSEND );
+}
+
+static const char* lcl_GetUnderlineStyle( FontUnderline eUnderline, bool& bHaveUnderline )
+{
+ bHaveUnderline = true;
+ switch( eUnderline )
+ {
+ // OOXTODO: doubleAccounting, singleAccounting
+ // OOXTODO: what should be done with the other FontUnderline values?
+ case UNDERLINE_SINGLE: return "single";
+ case UNDERLINE_DOUBLE: return "double";
+ case UNDERLINE_NONE:
+ default: bHaveUnderline = false; return "none";
+ }
+}
+
+static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
+{
+ bHaveAlignment = true;
+ switch( eEscapement )
+ {
+ case SVX_ESCAPEMENT_SUPERSCRIPT: return "superscript";
+ case SVX_ESCAPEMENT_SUBSCRIPT: return "subscript";
+ case SVX_ESCAPEMENT_OFF:
+ default: bHaveAlignment = false; return "baseline";
+ }
+}
+
+sax_fastparser::FSHelperPtr XclXmlUtils::WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nFontId )
+{
+ bool bHaveUnderline, bHaveVertAlign;
+ const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
+ const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
+
+ lcl_WriteValue( pStream, nFontId, XclXmlUtils::ToOString( rFontData.maName ).getStr() );
+ lcl_WriteValue( pStream, XML_charset, rFontData.mnCharSet != 0 ? OString::valueOf( (sal_Int32) rFontData.mnCharSet ).getStr() : NULL );
+ lcl_WriteValue( pStream, XML_family, OString::valueOf( (sal_Int32) rFontData.mnFamily ).getStr() );
+ lcl_WriteValue( pStream, XML_b, rFontData.mnWeight > 400 ? XclXmlUtils::ToPsz( rFontData.mnWeight > 400 ) : NULL );
+ lcl_WriteValue( pStream, XML_i, rFontData.mbItalic ? XclXmlUtils::ToPsz( rFontData.mbItalic ) : NULL );
+ lcl_WriteValue( pStream, XML_strike, rFontData.mbStrikeout ? XclXmlUtils::ToPsz( rFontData.mbStrikeout ) : NULL );
+ lcl_WriteValue( pStream, XML_outline, rFontData.mbOutline ? XclXmlUtils::ToPsz( rFontData.mbOutline ) : NULL );
+ lcl_WriteValue( pStream, XML_shadow, rFontData.mbShadow ? XclXmlUtils::ToPsz( rFontData.mbShadow ) : NULL );
+ // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
+ // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
+ if( rFontData.maColor != Color( 0xFF, 0xFF, 0xFF, 0xFF ) )
+ pStream->singleElement( XML_color,
+ // OOXTODO: XML_auto, bool
+ // OOXTODO: XML_indexed, uint
+ XML_rgb, XclXmlUtils::ToOString( rFontData.maColor ).getStr(),
+ // OOXTODO: XML_theme, index into <clrScheme/>
+ // OOXTODO: XML_tint, double
+ FSEND );
+ lcl_WriteValue( pStream, XML_sz, OString::valueOf( (double) (rFontData.mnHeight / 20.0) ) ); // Twips->Pt
+ lcl_WriteValue( pStream, XML_u, bHaveUnderline ? pUnderline : NULL );
+ lcl_WriteValue( pStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : NULL );
+
+ return pStream;
+}
+
+
+// ============================================================================
+
+XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
+ : XmlFilterBase( rCC ),
+ mpRoot( NULL )
+{
+}
+
+XclExpXmlStream::~XclExpXmlStream()
+{
+}
+
+sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
+{
+ DBG_ASSERT( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
+ return maStreams.top();
+}
+
+void XclExpXmlStream::PushStream( sax_fastparser::FSHelperPtr aStream )
+{
+ maStreams.push( aStream );
+}
+
+void XclExpXmlStream::PopStream()
+{
+ DBG_ASSERT( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
+ maStreams.pop();
+}
+
+sax_fastparser::FSHelperPtr XclExpXmlStream::GetStreamForPath( const OUString& sPath )
+{
+ if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
+ return sax_fastparser::FSHelperPtr();
+ return maOpenedStreamMap[ sPath ].second;
+}
+
+sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteAttributes( sal_Int32 nAttribute, ... )
+{
+ sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
+
+ va_list args;
+ va_start( args, nAttribute );
+ do {
+ const char* pValue = va_arg( args, const char* );
+ if( pValue )
+ {
+ rStream->write( " " )
+ ->writeId( nAttribute )
+ ->write( "=\"" )
+ ->writeEscaped( pValue )
+ ->write( "\"" );
+ }
+
+ nAttribute = va_arg( args, sal_Int32 );
+ if( nAttribute == FSEND )
+ break;
+ } while( true );
+ va_end( args );
+
+ return rStream;
+}
+sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
+ const OUString& sFullStream,
+ const OUString& sRelativeStream,
+ const Reference< XOutputStream >& xParentRelation,
+ const char* sContentType,
+ const char* sRelationshipType,
+ OUString* pRelationshipId )
+{
+ OUString sRelationshipId;
+ if (xParentRelation.is())
+ sRelationshipId = addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
+ else
+ sRelationshipId = addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
+
+ if( pRelationshipId )
+ *pRelationshipId = sRelationshipId;
+
+ sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
+
+ maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
+
+ return p;
+}
+
+bool XclExpXmlStream::importDocument() throw()
+{
+ return false;
+}
+
+oox::vml::Drawing* XclExpXmlStream::getVmlDrawing()
+{
+ return 0;
+}
+
+const oox::drawingml::Theme* XclExpXmlStream::getCurrentTheme() const
+{
+ return 0;
+}
+
+const oox::drawingml::table::TableStyleListPtr XclExpXmlStream::getTableStyles()
+{
+ return oox::drawingml::table::TableStyleListPtr();
+}
+
+oox::drawingml::chart::ChartConverter& XclExpXmlStream::getChartConverter()
+{
+ // DO NOT CALL
+ return * (oox::drawingml::chart::ChartConverter*) NULL;
+}
+
+ScDocShell* XclExpXmlStream::getDocShell()
+{
+ Reference< XInterface > xModel( getModel(), UNO_QUERY );
+
+ ScModelObj *pObj = dynamic_cast < ScModelObj* >( xModel.get() );
+
+ if ( pObj )
+ return reinterpret_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
+
+ return 0;
+}
+
+bool XclExpXmlStream::exportDocument() throw()
+{
+ ScDocShell* pShell = getDocShell();
+ ScDocument* pDoc = pShell->GetDocument();
+ // NOTE: Don't use SotStorage or SvStream any more, and never call
+ // SfxMedium::GetOutStream() anywhere in the xlsx export filter code!
+ // Instead, write via XOutputStream instance.
+ SotStorageRef rStorage = static_cast<SotStorage*>(NULL);
+ XclExpObjList::ResetCounters();
+
+ XclExpRootData aData( EXC_BIFF8, *pShell->GetMedium (), rStorage, *pDoc, RTL_TEXTENCODING_DONTKNOW );
+ aData.meOutput = EXC_OUTPUT_XML_2007;
+ aData.maXclMaxPos.Set( EXC_MAXCOL_XML_2007, EXC_MAXROW_XML_2007, EXC_MAXTAB_XML_2007 );
+ aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
+ aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
+ aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
+
+ XclExpRoot aRoot( aData );
+
+ mpRoot = &aRoot;
+ aRoot.GetOldRoot().pER = &aRoot;
+ aRoot.GetOldRoot().eDateiTyp = Biff8;
+ // Get the viewsettings before processing
+ if( pShell->GetViewData() )
+ pShell->GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
+
+ OUString const workbook = CREATE_OUSTRING( "xl/workbook.xml" );
+ PushStream( CreateOutputStream( workbook, workbook,
+ Reference <XOutputStream>(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
+
+ // destruct at the end of the block
+ {
+ ExcDocument aDocRoot( aRoot );
+ aDocRoot.ReadDoc();
+ aDocRoot.WriteXml( *this );
+ }
+
+ mpRoot = NULL;
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// UNO stuff so that the filter is registered
+//////////////////////////////////////////////////////////////////////////
+
+#define IMPL_NAME "com.sun.star.comp.oox.ExcelFilterExport"
+
+OUString XlsxExport_getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPL_NAME ) );
+}
+
+::oox::ole::VbaProject* XclExpXmlStream::implCreateVbaProject() const
+{
+ return new ::oox::xls::ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
+}
+
+OUString XclExpXmlStream::implGetImplementationName() const
+{
+ return CREATE_OUSTRING( "TODO" );
+}
+
+
+Sequence< OUString > SAL_CALL XlsxExport_getSupportedServiceNames() throw()
+{
+ const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ExportFilter" ) );
+ const Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL XlsxExport_createInstance(const Reference< XComponentContext > & rCC ) throw( Exception )
+{
+ return (cppu::OWeakObject*) new XclExpXmlStream( rCC );
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+// ------------------------
+// - component_getFactory -
+// ------------------------
+::cppu::ImplementationEntry entries [] =
+{
+ {
+ XlsxExport_createInstance, XlsxExport_getImplementationName,
+ XlsxExport_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplName, XMultiServiceFactory* pServiceManager, XRegistryKey* pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, entries );
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xestring.cxx b/sc/source/filter/excel/xestring.cxx
new file mode 100644
index 000000000000..987b25dba294
--- /dev/null
+++ b/sc/source/filter/excel/xestring.cxx
@@ -0,0 +1,606 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+#include <stdio.h>
+#include "xlstyle.hxx"
+#include "xestyle.hxx"
+#include "xestream.hxx"
+#include "xlstyle.hxx"
+#include "xestyle.hxx"
+#include "xestring.hxx"
+
+using namespace ::oox;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+// compare vectors
+
+/** Compares two vectors.
+ @return A negative value, if rLeft<rRight; or a positive value, if rLeft>rRight;
+ or 0, if rLeft==rRight. */
+template< typename Type >
+int lclCompareVectors( const ::std::vector< Type >& rLeft, const ::std::vector< Type >& rRight )
+{
+ int nResult = 0;
+
+ // 1st: compare all elements of the vectors
+ typedef typename ::std::vector< Type >::const_iterator CIT;
+ CIT aEndL = rLeft.end(), aEndR = rRight.end();
+ for( CIT aItL = rLeft.begin(), aItR = rRight.begin(); !nResult && (aItL != aEndL) && (aItR != aEndR); ++aItL, ++aItR )
+ nResult = static_cast< int >( *aItL ) - static_cast< int >( *aItR );
+
+ // 2nd: no differences found so far -> compare the vector sizes. Shorter vector is less
+ if( !nResult )
+ nResult = static_cast< int >( rLeft.size() ) - static_cast< int >( rRight.size() );
+
+ return nResult;
+}
+
+// hashing helpers
+
+/** Base class for value hashers.
+ @descr These function objects are used to hash any value to a sal_uInt32 value. */
+template< typename Type >
+struct XclHasher : public ::std::unary_function< Type, sal_uInt32 > {};
+
+template< typename Type >
+struct XclDirectHasher : public XclHasher< Type >
+{
+ inline sal_uInt32 operator()( Type nVal ) const { return nVal; }
+};
+
+struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
+{
+ inline sal_uInt32 operator()( const XclFormatRun& rRun ) const
+ { return (rRun.mnChar << 8) ^ rRun.mnFontIdx; }
+};
+
+/** Calculates a hash value from a vector.
+ @descr Uses the passed hasher function object to calculate hash values from
+ all vector elements. */
+template< typename Type, typename ValueHasher >
+sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec, const ValueHasher& rHasher )
+{
+ sal_uInt32 nHash = rVec.size();
+ typedef typename ::std::vector< Type >::const_iterator CIT;
+ for( CIT aIt = rVec.begin(), aEnd = rVec.end(); aIt != aEnd; ++aIt )
+ (nHash *= 31) += rHasher( *aIt );
+ return static_cast< sal_uInt16 >( nHash ^ (nHash >> 16) );
+}
+
+/** Calculates a hash value from a vector. Uses XclDirectHasher to hash the vector elements. */
+template< typename Type >
+inline sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec )
+{
+ return lclHashVector( rVec, XclDirectHasher< Type >() );
+}
+
+} // namespace
+
+// constructors ---------------------------------------------------------------
+
+XclExpString::XclExpString( XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( 0, nFlags, nMaxLen, true );
+}
+
+XclExpString::XclExpString( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+}
+
+XclExpString::XclExpString( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Assign( rString, nFlags, nMaxLen );
+}
+
+// assign ---------------------------------------------------------------------
+
+void XclExpString::Assign( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( rString.GetBuffer(), rString.Len(), nFlags, nMaxLen );
+}
+
+void XclExpString::Assign( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( rString.getStr(), rString.getLength(), nFlags, nMaxLen );
+}
+
+void XclExpString::Assign( sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Build( &cChar, 1, nFlags, nMaxLen );
+}
+
+void XclExpString::AssignByte(
+ const String& rString, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
+ Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
+}
+
+// append ---------------------------------------------------------------------
+
+void XclExpString::Append( const String& rString )
+{
+ BuildAppend( rString.GetBuffer(), rString.Len() );
+}
+
+void XclExpString::AppendByte( const String& rString, rtl_TextEncoding eTextEnc )
+{
+ if( rString.Len() > 0 )
+ {
+ ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
+ BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
+ }
+}
+
+void XclExpString::AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc )
+{
+ if( !cChar )
+ {
+ sal_Char cByteChar = 0;
+ BuildAppend( &cByteChar, 1 );
+ }
+ else
+ {
+ ByteString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
+ BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
+ }
+}
+
+// formatting runs ------------------------------------------------------------
+
+void XclExpString::SetFormats( const XclFormatRunVec& rFormats )
+{
+ maFormats = rFormats;
+#ifdef DBG_UTIL
+ if( IsRich() )
+ {
+ XclFormatRunVec::const_iterator aCurr = maFormats.begin();
+ XclFormatRunVec::const_iterator aPrev = aCurr;
+ XclFormatRunVec::const_iterator aEnd = maFormats.end();
+ for( ++aCurr; aCurr != aEnd; ++aCurr, ++aPrev )
+ DBG_ASSERT( aPrev->mnChar < aCurr->mnChar, "XclExpString::SetFormats - invalid char order" );
+ DBG_ASSERT( aPrev->mnChar <= mnLen, "XclExpString::SetFormats - invalid char index" );
+ }
+#endif
+ LimitFormatCount( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
+}
+
+void XclExpString::AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate )
+{
+ DBG_ASSERT( maFormats.empty() || (maFormats.back().mnChar < nChar), "XclExpString::AppendFormat - invalid char index" );
+ size_t nMaxSize = static_cast< size_t >( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
+ if( maFormats.empty() || ((maFormats.size() < nMaxSize) && (!bDropDuplicate || (maFormats.back().mnFontIdx != nFontIdx))) )
+ maFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
+}
+
+void XclExpString::AppendTrailingFormat( sal_uInt16 nFontIdx )
+{
+ AppendFormat( mnLen, nFontIdx, false );
+}
+
+void XclExpString::LimitFormatCount( sal_uInt16 nMaxCount )
+{
+ if( maFormats.size() > nMaxCount )
+ maFormats.erase( maFormats.begin() + nMaxCount, maFormats.end() );
+}
+
+sal_uInt16 XclExpString::RemoveLeadingFont()
+{
+ sal_uInt16 nFontIdx = EXC_FONT_NOTFOUND;
+ if( !maFormats.empty() && (maFormats.front().mnChar == 0) )
+ {
+ nFontIdx = maFormats.front().mnFontIdx;
+ maFormats.erase( maFormats.begin() );
+ }
+ return nFontIdx;
+}
+
+bool XclExpString::IsEqual( const XclExpString& rCmp ) const
+{
+ return
+ (mnLen == rCmp.mnLen) &&
+ (mbIsBiff8 == rCmp.mbIsBiff8) &&
+ (mbIsUnicode == rCmp.mbIsUnicode) &&
+ (mbWrapped == rCmp.mbWrapped) &&
+ (
+ ( mbIsBiff8 && (maUniBuffer == rCmp.maUniBuffer)) ||
+ (!mbIsBiff8 && (maCharBuffer == rCmp.maCharBuffer))
+ ) &&
+ (maFormats == rCmp.maFormats);
+}
+
+bool XclExpString::IsLessThan( const XclExpString& rCmp ) const
+{
+ int nResult = mbIsBiff8 ?
+ lclCompareVectors( maUniBuffer, rCmp.maUniBuffer ) :
+ lclCompareVectors( maCharBuffer, rCmp.maCharBuffer );
+ return (nResult != 0) ? (nResult < 0) : (maFormats < rCmp.maFormats);
+}
+
+// get data -------------------------------------------------------------------
+
+sal_uInt16 XclExpString::GetFormatsCount() const
+{
+ return static_cast< sal_uInt16 >( maFormats.size() );
+}
+
+sal_uInt8 XclExpString::GetFlagField() const
+{
+ return (mbIsUnicode ? EXC_STRF_16BIT : 0) | (IsWriteFormats() ? EXC_STRF_RICH : 0);
+}
+
+sal_uInt16 XclExpString::GetHeaderSize() const
+{
+ return
+ (mb8BitLen ? 1 : 2) + // length field
+ (IsWriteFlags() ? 1 : 0) + // flag field
+ (IsWriteFormats() ? 2 : 0); // richtext formattting count
+}
+
+sal_Size XclExpString::GetBufferSize() const
+{
+ return mnLen * (mbIsUnicode ? 2 : 1);
+}
+
+sal_Size XclExpString::GetSize() const
+{
+ return
+ GetHeaderSize() + // header
+ GetBufferSize() + // character buffer
+ (IsWriteFormats() ? (4 * GetFormatsCount()) : 0); // richtext formattting
+}
+
+sal_uInt16 XclExpString::GetChar( sal_uInt16 nCharIdx ) const
+{
+ DBG_ASSERT( nCharIdx < Len(), "XclExpString::GetChar - invalid character index" );
+ return static_cast< sal_uInt16 >( mbIsBiff8 ? maUniBuffer[ nCharIdx ] : maCharBuffer[ nCharIdx ] );
+}
+
+sal_uInt16 XclExpString::GetHash() const
+{
+ return
+ (mbIsBiff8 ? lclHashVector( maUniBuffer ) : lclHashVector( maCharBuffer )) ^
+ lclHashVector( maFormats, XclFormatRunHasher() );
+}
+
+// streaming ------------------------------------------------------------------
+
+void XclExpString::WriteLenField( XclExpStream& rStrm ) const
+{
+ if( mb8BitLen )
+ rStrm << static_cast< sal_uInt8 >( mnLen );
+ else
+ rStrm << mnLen;
+}
+
+void XclExpString::WriteFlagField( XclExpStream& rStrm ) const
+{
+ if( mbIsBiff8 )
+ {
+ PrepareWrite( rStrm, 1 );
+ rStrm << GetFlagField();
+ rStrm.SetSliceSize( 0 );
+ }
+}
+
+void XclExpString::WriteHeader( XclExpStream& rStrm ) const
+{
+ DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeader - string too long" );
+ PrepareWrite( rStrm, GetHeaderSize() );
+ // length
+ WriteLenField( rStrm );
+ // flag field
+ if( IsWriteFlags() )
+ rStrm << GetFlagField();
+ // format run count
+ if( IsWriteFormats() )
+ rStrm << GetFormatsCount();
+ rStrm.SetSliceSize( 0 );
+}
+
+void XclExpString::WriteBuffer( XclExpStream& rStrm ) const
+{
+ if( mbIsBiff8 )
+ rStrm.WriteUnicodeBuffer( maUniBuffer, GetFlagField() );
+ else
+ rStrm.WriteCharBuffer( maCharBuffer );
+}
+
+void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
+{
+ if( IsRich() )
+ {
+ XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
+ if( mbIsBiff8 )
+ {
+ if( bWriteSize )
+ rStrm << GetFormatsCount();
+ rStrm.SetSliceSize( 4 );
+ for( ; aIt != aEnd; ++aIt )
+ rStrm << aIt->mnChar << aIt->mnFontIdx;
+ }
+ else
+ {
+ if( bWriteSize )
+ rStrm << static_cast< sal_uInt8 >( GetFormatsCount() );
+ rStrm.SetSliceSize( 2 );
+ for( ; aIt != aEnd; ++aIt )
+ rStrm << static_cast< sal_uInt8 >( aIt->mnChar ) << static_cast< sal_uInt8 >( aIt->mnFontIdx );
+ }
+ rStrm.SetSliceSize( 0 );
+ }
+}
+
+void XclExpString::Write( XclExpStream& rStrm ) const
+{
+ if (!mbSkipHeader)
+ WriteHeader( rStrm );
+ WriteBuffer( rStrm );
+ if( IsWriteFormats() ) // only in BIFF8 included in string
+ WriteFormats( rStrm );
+}
+
+void XclExpString::WriteHeaderToMem( sal_uInt8* pnMem ) const
+{
+ DBG_ASSERT( pnMem, "XclExpString::WriteHeaderToMem - no memory to write to" );
+ DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeaderToMem - string too long" );
+ DBG_ASSERT( !IsWriteFormats(), "XclExpString::WriteHeaderToMem - formatted strings not supported" );
+ // length
+ if( mb8BitLen )
+ {
+ *pnMem = static_cast< sal_uInt8 >( mnLen );
+ ++pnMem;
+ }
+ else
+ {
+ ShortToSVBT16( mnLen, pnMem );
+ pnMem += 2;
+ }
+ // flag field
+ if( IsWriteFlags() )
+ *pnMem = GetFlagField();
+}
+
+void XclExpString::WriteBufferToMem( sal_uInt8* pnMem ) const
+{
+ DBG_ASSERT( pnMem, "XclExpString::WriteBufferToMem - no memory to write to" );
+ if( !IsEmpty() )
+ {
+ if( mbIsBiff8 )
+ {
+ for( ScfUInt16Vec::const_iterator aIt = maUniBuffer.begin(), aEnd = maUniBuffer.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nChar = *aIt;
+ *pnMem = static_cast< sal_uInt8 >( nChar );
+ ++pnMem;
+ if( mbIsUnicode )
+ {
+ *pnMem = static_cast< sal_uInt8 >( nChar >> 8 );
+ ++pnMem;
+ }
+ }
+ }
+ else
+ memcpy( pnMem, &maCharBuffer[ 0 ], mnLen );
+ }
+}
+
+void XclExpString::WriteToMem( sal_uInt8* pnMem ) const
+{
+ WriteHeaderToMem( pnMem );
+ WriteBufferToMem( pnMem + GetHeaderSize() );
+}
+
+static sal_uInt16 lcl_WriteRun( XclExpXmlStream& rStrm, const ScfUInt16Vec& rBuffer, sal_uInt16 nStart, sal_Int32 nLength, const XclExpFont* pFont )
+{
+ if( nLength == 0 )
+ return nStart;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+
+ rWorksheet->startElement( XML_r, FSEND );
+ if( pFont )
+ {
+ const XclFontData& rFontData = pFont->GetFontData();
+ rWorksheet->startElement( XML_rPr, FSEND );
+ XclXmlUtils::WriteFontData( rWorksheet, rFontData, XML_rFont );
+ rWorksheet->endElement( XML_rPr );
+ }
+ rWorksheet->startElement( XML_t,
+ FSNS( XML_xml, XML_space ), "preserve",
+ FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rBuffer, nStart, nLength ) );
+ rWorksheet->endElement( XML_t );
+ rWorksheet->endElement( XML_r );
+ return nStart + nLength;
+}
+
+void XclExpString::WriteXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr rWorksheet = rStrm.GetCurrentStream();
+
+ if( !IsWriteFormats() )
+ {
+ rWorksheet->startElement( XML_t, FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *this ) );
+ rWorksheet->endElement( XML_t );
+ }
+ else
+ {
+ XclExpFontBuffer& rFonts = rStrm.GetRoot().GetFontBuffer();
+ XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
+
+ sal_uInt16 nStart = 0;
+ const XclExpFont* pFont = NULL;
+ for ( ; aIt != aEnd; ++aIt )
+ {
+ nStart = lcl_WriteRun( rStrm, GetUnicodeBuffer(),
+ nStart, aIt->mnChar-nStart, pFont );
+ pFont = rFonts.GetFont( aIt->mnFontIdx );
+ }
+ lcl_WriteRun( rStrm, GetUnicodeBuffer(),
+ nStart, GetUnicodeBuffer().size() - nStart, pFont );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpString::IsWriteFlags() const
+{
+ return mbIsBiff8 && (!IsEmpty() || !mbSmartFlags);
+}
+
+bool XclExpString::IsWriteFormats() const
+{
+ return mbIsBiff8 && !mbSkipFormats && IsRich();
+}
+
+void XclExpString::SetStrLen( sal_Int32 nNewLen )
+{
+ sal_uInt16 nAllowedLen = (mb8BitLen && (mnMaxLen > 255)) ? 255 : mnMaxLen;
+ mnLen = limit_cast< sal_uInt16 >( nNewLen, 0, nAllowedLen );
+}
+
+void XclExpString::CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
+{
+ DBG_ASSERT( maUniBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
+ "XclExpString::CharsToBuffer - char buffer invalid" );
+ ScfUInt16Vec::iterator aBeg = maUniBuffer.begin() + nBegin;
+ ScfUInt16Vec::iterator aEnd = aBeg + nLen;
+ const sal_Unicode* pcSrcChar = pcSource;
+ for( ScfUInt16Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
+ {
+ *aIt = static_cast< sal_uInt16 >( *pcSrcChar );
+ if( *aIt & 0xFF00 )
+ mbIsUnicode = true;
+ }
+ if( !mbWrapped )
+ mbWrapped = ::std::find( aBeg, aEnd, EXC_LF ) != aEnd;
+}
+
+void XclExpString::CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
+{
+ DBG_ASSERT( maCharBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
+ "XclExpString::CharsToBuffer - char buffer invalid" );
+ ScfUInt8Vec::iterator aBeg = maCharBuffer.begin() + nBegin;
+ ScfUInt8Vec::iterator aEnd = aBeg + nLen;
+ const sal_Char* pcSrcChar = pcSource;
+ for( ScfUInt8Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
+ *aIt = static_cast< sal_uInt8 >( *pcSrcChar );
+ mbIsUnicode = false;
+ if( !mbWrapped )
+ mbWrapped = ::std::find( aBeg, aEnd, EXC_LF_C ) != aEnd;
+}
+
+void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 )
+{
+ mbIsBiff8 = bBiff8;
+ mbIsUnicode = bBiff8 && ::get_flag( nFlags, EXC_STR_FORCEUNICODE );
+ mb8BitLen = ::get_flag( nFlags, EXC_STR_8BITLENGTH );
+ mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
+ mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
+ mbWrapped = false;
+ mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
+ mnMaxLen = nMaxLen;
+ SetStrLen( nCurrLen );
+
+ maFormats.clear();
+ if( mbIsBiff8 )
+ {
+ maCharBuffer.clear();
+ maUniBuffer.resize( mnLen );
+ }
+ else
+ {
+ maUniBuffer.clear();
+ maCharBuffer.resize( mnLen );
+ }
+}
+
+void XclExpString::Build( const sal_Unicode* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( nCurrLen, nFlags, nMaxLen, true );
+ CharsToBuffer( pcSource, 0, mnLen );
+}
+
+void XclExpString::Build( const sal_Char* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
+{
+ Init( nCurrLen, nFlags, nMaxLen, false );
+ CharsToBuffer( pcSource, 0, mnLen );
+}
+
+void XclExpString::InitAppend( sal_Int32 nAddLen )
+{
+ SetStrLen( static_cast< sal_Int32 >( mnLen ) + nAddLen );
+ if( mbIsBiff8 )
+ maUniBuffer.resize( mnLen );
+ else
+ maCharBuffer.resize( mnLen );
+}
+
+void XclExpString::BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen )
+{
+ DBG_ASSERT( mbIsBiff8, "XclExpString::BuildAppend - must not be called at byte strings" );
+ if( mbIsBiff8 )
+ {
+ sal_uInt16 nOldLen = mnLen;
+ InitAppend( nAddLen );
+ CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
+ }
+}
+
+void XclExpString::BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen )
+{
+ DBG_ASSERT( !mbIsBiff8, "XclExpString::BuildAppend - must not be called at unicode strings" );
+ if( !mbIsBiff8 )
+ {
+ sal_uInt16 nOldLen = mnLen;
+ InitAppend( nAddLen );
+ CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
+ }
+}
+
+void XclExpString::PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const
+{
+ rStrm.SetSliceSize( nBytes + (mbIsUnicode ? 2 : 1) );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx
new file mode 100644
index 000000000000..eb5075c189ca
--- /dev/null
+++ b/sc/source/filter/excel/xestyle.cxx
@@ -0,0 +1,2860 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xestyle.hxx"
+
+#include <algorithm>
+#include <iterator>
+#include <set>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <vcl/font.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/printer.hxx>
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "globstr.hrc"
+#include "xestring.hxx"
+
+#include <oox/token/tokens.hxx>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using namespace oox;
+
+// PALETTE record - color information =========================================
+
+namespace {
+
+sal_uInt32 lclGetWeighting( XclExpColorType eType )
+{
+ switch( eType )
+ {
+ case EXC_COLOR_CHARTLINE: return 1;
+ case EXC_COLOR_CELLBORDER:
+ case EXC_COLOR_CHARTAREA: return 2;
+ case EXC_COLOR_CELLTEXT:
+ case EXC_COLOR_CHARTTEXT:
+ case EXC_COLOR_CTRLTEXT: return 10;
+ case EXC_COLOR_TABBG:
+ case EXC_COLOR_CELLAREA: return 20;
+ case EXC_COLOR_GRID: return 50;
+ default: DBG_ERRORFILE( "lclGetWeighting - unknown color type" );
+ }
+ return 1;
+}
+
+sal_Int32 lclGetColorDistance( const Color& rColor1, const Color& rColor2 )
+{
+ sal_Int32 nDist = rColor1.GetRed() - rColor2.GetRed();
+ nDist *= nDist * 77;
+ sal_Int32 nDummy = rColor1.GetGreen() - rColor2.GetGreen();
+ nDist += nDummy * nDummy * 151;
+ nDummy = rColor1.GetBlue() - rColor2.GetBlue();
+ nDist += nDummy * nDummy * 28;
+ return nDist;
+}
+
+sal_uInt8 lclGetMergedColorComp( sal_uInt8 nComp1, sal_uInt32 nWeight1, sal_uInt8 nComp2, sal_uInt32 nWeight2 )
+{
+ sal_uInt8 nComp1Dist = ::std::min< sal_uInt8 >( nComp1, 0xFF - nComp1 );
+ sal_uInt8 nComp2Dist = ::std::min< sal_uInt8 >( nComp2, 0xFF - nComp2 );
+ if( nComp1Dist != nComp2Dist )
+ {
+ /* #i36945# One of the passed RGB components is nearer at the limits (0x00 or 0xFF).
+ Increase its weighting to prevent fading of the colors during reduction. */
+ const sal_uInt8& rnCompNearer = (nComp1Dist < nComp2Dist) ? nComp1 : nComp2;
+ sal_uInt32& rnWeight = (nComp1Dist < nComp2Dist) ? nWeight1 : nWeight2;
+ rnWeight *= ((rnCompNearer - 0x80L) * (rnCompNearer - 0x7FL) / 0x1000L + 1);
+ }
+ sal_uInt32 nWSum = nWeight1 + nWeight2;
+ return static_cast< sal_uInt8 >( (nComp1 * nWeight1 + nComp2 * nWeight2 + nWSum / 2) / nWSum );
+}
+
+void lclSetMixedColor( Color& rDest, const Color& rSrc1, const Color& rSrc2 )
+{
+ rDest.SetRed( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetRed() ) + rSrc2.GetRed()) / 2 ) );
+ rDest.SetGreen( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetGreen() ) + rSrc2.GetGreen()) / 2 ) );
+ rDest.SetBlue( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetBlue() ) + rSrc2.GetBlue()) / 2 ) );
+}
+
+} // namespace
+
+// additional classes for color reduction -------------------------------------
+
+namespace {
+
+/** Represents an entry in a color list.
+
+ The color stores a weighting value, which increases the more the color is
+ used in the document. Heavy-weighted colors will change less than others on
+ color reduction.
+ */
+class XclListColor
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclListColor )
+
+private:
+ Color maColor; /// The color value of this palette entry.
+ sal_uInt32 mnColorId; /// Unique color ID for color reduction.
+ sal_uInt32 mnWeight; /// Weighting for color reduction.
+ bool mbBaseColor; /// true = Handle as base color, (don't remove/merge).
+
+public:
+ explicit XclListColor( const Color& rColor, sal_uInt32 nColorId );
+
+ /** Returns the RGB color value of the color. */
+ inline const Color& GetColor() const { return maColor; }
+ /** Returns the unique ID of the color. */
+ inline sal_uInt32 GetColorId() const { return mnColorId; }
+ /** Returns the current weighting of the color. */
+ inline sal_uInt32 GetWeighting() const { return mnWeight; }
+ /** Returns true, if this color is a base color, i.e. it will not be removed or merged. */
+ inline bool IsBaseColor() const { return mbBaseColor; }
+
+ /** Adds the passed weighting to this color. */
+ inline void AddWeighting( sal_uInt32 nWeight ) { mnWeight += nWeight; }
+ /** Merges this color with rColor, regarding weighting settings. */
+ void Merge( const XclListColor& rColor );
+};
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclListColor, 100, 100 )
+
+XclListColor::XclListColor( const Color& rColor, sal_uInt32 nColorId ) :
+ maColor( rColor ),
+ mnColorId( nColorId ),
+ mnWeight( 0 )
+{
+ mbBaseColor =
+ ((rColor.GetRed() == 0x00) || (rColor.GetRed() == 0xFF)) &&
+ ((rColor.GetGreen() == 0x00) || (rColor.GetGreen() == 0xFF)) &&
+ ((rColor.GetBlue() == 0x00) || (rColor.GetBlue() == 0xFF));
+}
+
+void XclListColor::Merge( const XclListColor& rColor )
+{
+ sal_uInt32 nWeight2 = rColor.GetWeighting();
+ // do not change RGB value of base colors
+ if( !mbBaseColor )
+ {
+ maColor.SetRed( lclGetMergedColorComp( maColor.GetRed(), mnWeight, rColor.maColor.GetRed(), nWeight2 ) );
+ maColor.SetGreen( lclGetMergedColorComp( maColor.GetGreen(), mnWeight, rColor.maColor.GetGreen(), nWeight2 ) );
+ maColor.SetBlue( lclGetMergedColorComp( maColor.GetBlue(), mnWeight, rColor.maColor.GetBlue(), nWeight2 ) );
+ }
+ AddWeighting( nWeight2 );
+}
+
+// ----------------------------------------------------------------------------
+
+/** Data for each inserted original color, represented by a color ID. */
+struct XclColorIdData
+{
+ Color maColor; /// The original inserted color.
+ sal_uInt32 mnIndex; /// Maps current color ID to color list or export color vector.
+ /** Sets the contents of this struct. */
+ inline void Set( const Color& rColor, sal_uInt32 nIndex ) { maColor = rColor; mnIndex = nIndex; }
+};
+
+/** A color that will be written to the Excel file. */
+struct XclPaletteColor
+{
+ Color maColor; /// Resulting color to export.
+ bool mbUsed; /// true = Entry is used in the document.
+
+ inline explicit XclPaletteColor( const Color& rColor ) : maColor( rColor ), mbUsed( false ) {}
+ inline void SetColor( const Color& rColor ) { maColor = rColor; mbUsed = true; }
+};
+
+/** Maps a color list index to a palette index.
+ @descr Used to remap the color ID data vector from list indexes to palette indexes. */
+struct XclRemap
+{
+ sal_uInt32 mnPalIndex; /// Index to palette.
+ bool mbProcessed; /// true = List color already processed.
+
+ inline explicit XclRemap() : mnPalIndex( 0 ), mbProcessed( false ) {}
+ inline void SetIndex( sal_uInt32 nPalIndex )
+ { mnPalIndex = nPalIndex; mbProcessed = true; }
+};
+
+/** Stores the nearest palette color index of a list color. */
+struct XclNearest
+{
+ sal_uInt32 mnPalIndex; /// Index to nearest palette color.
+ sal_Int32 mnDist; /// Distance to palette color.
+
+ inline explicit XclNearest() : mnPalIndex( 0 ), mnDist( 0 ) {}
+};
+
+typedef ::std::vector< XclRemap > XclRemapVec;
+typedef ::std::vector< XclNearest > XclNearestVec;
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+class XclExpPaletteImpl
+{
+public:
+ explicit XclExpPaletteImpl( const XclDefaultPalette& rDefPal );
+
+ /** Inserts the color into the list and updates weighting.
+ @param nAutoDefault The Excel palette index for automatic color.
+ @return A unique ID for this color. */
+ sal_uInt32 InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
+ /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
+ static sal_uInt32 GetColorIdFromIndex( sal_uInt16 nIndex );
+
+ /** Reduces the color list to the maximum count of the current BIFF version. */
+ void Finalize();
+
+ /** Returns the Excel palette index of the color with passed color ID. */
+ sal_uInt16 GetColorIndex( sal_uInt32 nColorId ) const;
+
+ /** Returns a foreground and background color for the two passed color IDs.
+ @descr If rnXclPattern contains a solid pattern, this function tries to find
+ the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
+ This will result in a better approximation to the passed foreground color. */
+ void GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+
+ /** Returns true, if all colors of the palette are equal to default palette colors. */
+ bool IsDefaultPalette() const;
+ /** Writes the color list (contents of the palette record) to the passed stream. */
+ void WriteBody( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Returns the Excel index of a 0-based color index. */
+ inline sal_uInt16 GetXclIndex( sal_uInt32 nIndex ) const
+ { return static_cast< sal_uInt16 >( nIndex + EXC_COLOR_USEROFFSET ); }
+
+ /** Returns the original inserted color represented by the color ID nColorId. */
+ const Color& GetOriginalColor( sal_uInt32 nColorId ) const;
+
+ /** Searches for rColor, returns the ordered insertion index for rColor in rnIndex. */
+ XclListColor* SearchListEntry( const Color& rColor, sal_uInt32& rnIndex );
+ /** Creates and inserts a new color list entry at the specified list position. */
+ XclListColor* CreateListEntry( const Color& rColor, sal_uInt32 nIndex );
+
+ /** Raw and fast reduction of the palette. */
+ void RawReducePalette( sal_uInt32 nPass );
+ /** Reduction of one color using advanced color merging based on color weighting. */
+ void ReduceLeastUsedColor();
+
+ /** Finds the least used color and returns its current list index. */
+ sal_uInt32 GetLeastUsedListColor() const;
+ /** Returns the list index of the color nearest to rColor.
+ @param nIgnore List index of a color which will be ignored.
+ @return The list index of the found color. */
+ sal_uInt32 GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const;
+ /** Returns the list index of the color nearest to the color with list index nIndex. */
+ sal_uInt32 GetNearestListColor( sal_uInt32 nIndex ) const;
+
+ /** Returns in rnIndex the palette index of the color nearest to rColor.
+ @param bDefaultOnly true = Searches for default colors only (colors never replaced).
+ @return The distance from passed color to found color. */
+ sal_Int32 GetNearestPaletteColor(
+ sal_uInt32& rnIndex,
+ const Color& rColor, bool bDefaultOnly ) const;
+ /** Returns in rnFirst and rnSecond the palette indexes of the two colors nearest to rColor.
+ @return The minimum distance from passed color to found colors. */
+ sal_Int32 GetNearPaletteColors(
+ sal_uInt32& rnFirst, sal_uInt32& rnSecond,
+ const Color& rColor ) const;
+
+private:
+ typedef boost::ptr_vector< XclListColor > XclListColorList;
+ typedef boost::shared_ptr< XclListColorList > XclListColorListRef;
+ typedef ::std::vector< XclColorIdData > XclColorIdDataVec;
+ typedef ::std::vector< XclPaletteColor > XclPaletteColorVec;
+
+ const XclDefaultPalette& mrDefPal; /// The default palette for the current BIFF version.
+ XclListColorListRef mxColorList; /// Working color list.
+ XclColorIdDataVec maColorIdDataVec; /// Data of all CIDs.
+ XclPaletteColorVec maPalette; /// Contains resulting colors to export.
+ sal_uInt32 mnLastIdx; /// Last insertion index for search opt.
+};
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 EXC_PAL_INDEXBASE = 0xFFFF0000;
+const sal_uInt32 EXC_PAL_MAXRAWSIZE = 1024;
+
+XclExpPaletteImpl::XclExpPaletteImpl( const XclDefaultPalette& rDefPal ) :
+ mrDefPal( rDefPal ),
+ mxColorList( new XclListColorList ),
+ mnLastIdx( 0 )
+{
+ // initialize maPalette with default colors
+ sal_uInt16 nCount = static_cast< sal_uInt16 >( mrDefPal.GetColorCount() );
+ maPalette.reserve( nCount );
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ maPalette.push_back( XclPaletteColor( mrDefPal.GetDefColor( GetXclIndex( nIdx ) ) ) );
+
+ InsertColor( Color( COL_BLACK ), EXC_COLOR_CELLTEXT );
+}
+
+sal_uInt32 XclExpPaletteImpl::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
+{
+ if( rColor.GetColor() == COL_AUTO )
+ return GetColorIdFromIndex( nAutoDefault );
+
+ sal_uInt32 nFoundIdx = 0;
+ XclListColor* pEntry = SearchListEntry( rColor, nFoundIdx );
+ if( !pEntry || (pEntry->GetColor() != rColor) )
+ pEntry = CreateListEntry( rColor, nFoundIdx );
+ pEntry->AddWeighting( lclGetWeighting( eType ) );
+
+ return pEntry->GetColorId();
+}
+
+sal_uInt32 XclExpPaletteImpl::GetColorIdFromIndex( sal_uInt16 nIndex )
+{
+ return EXC_PAL_INDEXBASE | nIndex;
+}
+
+void XclExpPaletteImpl::Finalize()
+{
+// --- build initial color ID data vector (maColorIdDataVec) ---
+
+ sal_uInt32 nCount = mxColorList->size();
+ maColorIdDataVec.resize( nCount );
+ for( sal_uInt32 nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ const XclListColor& listColor = mxColorList->at( nIdx );
+ maColorIdDataVec[ listColor.GetColorId() ].Set( listColor.GetColor(), nIdx );
+ }
+
+// --- loop as long as current color count does not fit into palette of current BIFF ---
+
+ // phase 1: raw reduction (performance reasons, #i36945#)
+ sal_uInt32 nPass = 0;
+ while( mxColorList->size() > EXC_PAL_MAXRAWSIZE )
+ RawReducePalette( nPass++ );
+
+ // phase 2: precise reduction using advanced color merging based on color weighting
+ while( mxColorList->size() > mrDefPal.GetColorCount() )
+ ReduceLeastUsedColor();
+
+// --- use default palette and replace colors with nearest used colors ---
+
+ nCount = mxColorList->size();
+ XclRemapVec aRemapVec( nCount );
+ XclNearestVec aNearestVec( nCount );
+
+ // in each run: search the best fitting color and replace a default color with it
+ for( sal_uInt32 nRun = 0; nRun < nCount; ++nRun )
+ {
+ sal_uInt32 nIndex;
+ // find nearest unused default color for each unprocessed list color
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ aNearestVec[ nIndex ].mnDist = aRemapVec[ nIndex ].mbProcessed ? SAL_MAX_INT32 :
+ GetNearestPaletteColor( aNearestVec[ nIndex ].mnPalIndex, mxColorList->at( nIndex ).GetColor(), true );
+ // find the list color which is nearest to a default color
+ sal_uInt32 nFound = 0;
+ for( nIndex = 1; nIndex < nCount; ++nIndex )
+ if( aNearestVec[ nIndex ].mnDist < aNearestVec[ nFound ].mnDist )
+ nFound = nIndex;
+ // replace default color with list color
+ sal_uInt32 nNearest = aNearestVec[ nFound ].mnPalIndex;
+ DBG_ASSERT( nNearest < maPalette.size(), "XclExpPaletteImpl::Finalize - algorithm error" );
+ maPalette[ nNearest ].SetColor( mxColorList->at( nFound ).GetColor() );
+ aRemapVec[ nFound ].SetIndex( nNearest );
+ }
+
+ // remap color ID data map (maColorIdDataVec) from list indexes to palette indexes
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ aIt->mnIndex = aRemapVec[ aIt->mnIndex ].mnPalIndex;
+}
+
+sal_uInt16 XclExpPaletteImpl::GetColorIndex( sal_uInt32 nColorId ) const
+{
+ sal_uInt16 nRet = 0;
+ if( nColorId >= EXC_PAL_INDEXBASE )
+ nRet = static_cast< sal_uInt16 >( nColorId & ~EXC_PAL_INDEXBASE );
+ else if( nColorId < maColorIdDataVec.size() )
+ nRet = GetXclIndex( maColorIdDataVec[ nColorId ].mnIndex );
+ return nRet;
+}
+
+void XclExpPaletteImpl::GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
+{
+ rnXclForeIx = GetColorIndex( nForeColorId );
+ rnXclBackIx = GetColorIndex( nBackColorId );
+ if( (rnXclPattern != EXC_PATT_SOLID) || (nForeColorId >= maColorIdDataVec.size()) )
+ return;
+
+ // now we have solid pattern, and a defined foreground (background doesn't care for solid pattern)
+
+ sal_uInt32 nIndex1, nIndex2;
+ Color aForeColor( GetOriginalColor( nForeColorId ) );
+ sal_Int32 nFirstDist = GetNearPaletteColors( nIndex1, nIndex2, aForeColor );
+ if( (nIndex1 >= maPalette.size()) || (nIndex2 >= maPalette.size()) )
+ return;
+
+ Color aColorArr[ 5 ];
+ aColorArr[ 0 ] = maPalette[ nIndex1 ].maColor;
+ aColorArr[ 4 ] = maPalette[ nIndex2 ].maColor;
+ lclSetMixedColor( aColorArr[ 2 ], aColorArr[ 0 ], aColorArr[ 4 ] );
+ lclSetMixedColor( aColorArr[ 1 ], aColorArr[ 0 ], aColorArr[ 2 ] );
+ lclSetMixedColor( aColorArr[ 3 ], aColorArr[ 2 ], aColorArr[ 4 ] );
+
+ sal_Int32 nMinDist = nFirstDist;
+ sal_uInt32 nMinIndex = 0;
+ for( sal_uInt32 nCnt = 1; nCnt < 4; ++nCnt )
+ {
+ sal_Int32 nDist = lclGetColorDistance( aForeColor, aColorArr[ nCnt ] );
+ if( nDist < nMinDist )
+ {
+ nMinDist = nDist;
+ nMinIndex = nCnt;
+ }
+ }
+ rnXclForeIx = GetXclIndex( nIndex1 );
+ rnXclBackIx = GetXclIndex( nIndex2 );
+ if( nMinDist < nFirstDist )
+ {
+ switch( nMinIndex )
+ {
+ case 1: rnXclPattern = EXC_PATT_75_PERC; break;
+ case 2: rnXclPattern = EXC_PATT_50_PERC; break;
+ case 3: rnXclPattern = EXC_PATT_25_PERC; break;
+ }
+ }
+}
+
+ColorData XclExpPaletteImpl::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ if( nXclIndex >= EXC_COLOR_USEROFFSET )
+ {
+ sal_uInt32 nIdx = nXclIndex - EXC_COLOR_USEROFFSET;
+ if( nIdx < maPalette.size() )
+ return maPalette[ nIdx ].maColor.GetColor();
+ }
+ return mrDefPal.GetDefColorData( nXclIndex );
+}
+
+bool XclExpPaletteImpl::IsDefaultPalette() const
+{
+ bool bDefault = true;
+ for( sal_uInt32 nIdx = 0, nSize = static_cast< sal_uInt32 >( maPalette.size() ); bDefault && (nIdx < nSize); ++nIdx )
+ bDefault = maPalette[ nIdx ].maColor == mrDefPal.GetDefColor( GetXclIndex( nIdx ) );
+ return bDefault;
+}
+
+void XclExpPaletteImpl::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt16 >( maPalette.size() );
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
+ rStrm << aIt->maColor;
+}
+
+void XclExpPaletteImpl::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !maPalette.size() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_colors, FSEND );
+ rStyleSheet->startElement( XML_indexedColors, FSEND );
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
+ rStyleSheet->singleElement( XML_rgbColor,
+ XML_rgb, XclXmlUtils::ToOString( aIt->maColor ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( XML_indexedColors );
+ rStyleSheet->endElement( XML_colors );
+}
+
+const Color& XclExpPaletteImpl::GetOriginalColor( sal_uInt32 nColorId ) const
+{
+ if( nColorId < maColorIdDataVec.size() )
+ return maColorIdDataVec[ nColorId ].maColor;
+ return maPalette[ 0 ].maColor;
+}
+
+XclListColor* XclExpPaletteImpl::SearchListEntry( const Color& rColor, sal_uInt32& rnIndex )
+{
+ rnIndex = mnLastIdx;
+ XclListColor* pEntry = NULL;
+
+ if (mxColorList->empty())
+ return NULL;
+
+ // search optimization for equal-colored objects occurring repeatedly
+ if (rnIndex < mxColorList->size())
+ {
+ pEntry = &(*mxColorList)[rnIndex];
+ if( pEntry->GetColor() == rColor )
+ return pEntry;
+ }
+
+ // binary search for color
+ sal_uInt32 nBegIdx = 0;
+ sal_uInt32 nEndIdx = mxColorList->size();
+ bool bFound = false;
+ while( !bFound && (nBegIdx < nEndIdx) )
+ {
+ rnIndex = (nBegIdx + nEndIdx) / 2;
+ pEntry = &(*mxColorList)[rnIndex];
+ bFound = pEntry->GetColor() == rColor;
+ if( !bFound )
+ {
+ if( pEntry->GetColor().GetColor() < rColor.GetColor() )
+ nBegIdx = rnIndex + 1;
+ else
+ nEndIdx = rnIndex;
+ }
+ }
+
+ // not found - use end of range as new insertion position
+ if( !bFound )
+ rnIndex = nEndIdx;
+
+ mnLastIdx = rnIndex;
+ return pEntry;
+}
+
+XclListColor* XclExpPaletteImpl::CreateListEntry( const Color& rColor, sal_uInt32 nIndex )
+{
+ XclListColor* pEntry = new XclListColor( rColor, mxColorList->size() );
+ XclListColorList::iterator itr = mxColorList->begin();
+ ::std::advance(itr, nIndex);
+ mxColorList->insert(itr, pEntry);
+ return pEntry;
+}
+
+void XclExpPaletteImpl::RawReducePalette( sal_uInt32 nPass )
+{
+ /* Fast palette reduction - in each call of this function one RGB component
+ of each color is reduced to a lower number of distinct values.
+ Pass 0: Blue is reduced to 128 distinct values.
+ Pass 1: Red is reduced to 128 distinct values.
+ Pass 2: Green is reduced to 128 distinct values.
+ Pass 3: Blue is reduced to 64 distinct values.
+ Pass 4: Red is reduced to 64 distinct values.
+ Pass 5: Green is reduced to 64 distinct values.
+ And so on...
+ */
+
+ XclListColorListRef xOldList = mxColorList;
+ mxColorList.reset( new XclListColorList );
+
+ // maps old list indexes to new list indexes, used to update maColorIdDataVec
+ ScfUInt32Vec aListIndexMap;
+ aListIndexMap.reserve( xOldList->size() );
+
+ // preparations
+ sal_uInt8 nR, nG, nB;
+ sal_uInt8& rnComp = ((nPass % 3 == 0) ? nB : ((nPass % 3 == 1) ? nR : nG));
+ nPass /= 3;
+ DBG_ASSERT( nPass < 7, "XclExpPaletteImpl::RawReducePalette - reduction not terminated" );
+
+ static const sal_uInt8 spnFactor2[] = { 0x81, 0x82, 0x84, 0x88, 0x92, 0xAA, 0xFF };
+ sal_uInt8 nFactor1 = static_cast< sal_uInt8 >( 0x02 << nPass );
+ sal_uInt8 nFactor2 = spnFactor2[ nPass ];
+ sal_uInt8 nFactor3 = static_cast< sal_uInt8 >( 0x40 >> nPass );
+
+ // process each color in the old color list
+ for( sal_uInt32 nIdx = 0, nCount = xOldList->size(); nIdx < nCount; ++nIdx )
+ {
+ // get the old list entry
+ const XclListColor* pOldEntry = &(xOldList->at( nIdx ));
+ nR = pOldEntry->GetColor().GetRed();
+ nG = pOldEntry->GetColor().GetGreen();
+ nB = pOldEntry->GetColor().GetBlue();
+
+ /* Calculate the new RGB component (rnComp points to one of nR, nG, nB).
+ Using integer arithmetic with its rounding errors, the results of
+ this calculation are always exactly in the range 0x00 to 0xFF
+ (simply cutting the lower bits would darken the colors slightly). */
+ sal_uInt32 nNewComp = rnComp;
+ nNewComp /= nFactor1;
+ nNewComp *= nFactor2;
+ nNewComp /= nFactor3;
+ rnComp = static_cast< sal_uInt8 >( nNewComp );
+ Color aNewColor( nR, nG, nB );
+
+ // find or insert the new color
+ sal_uInt32 nFoundIdx = 0;
+ XclListColor* pNewEntry = SearchListEntry( aNewColor, nFoundIdx );
+ if( !pNewEntry || (pNewEntry->GetColor() != aNewColor) )
+ pNewEntry = CreateListEntry( aNewColor, nFoundIdx );
+ pNewEntry->AddWeighting( pOldEntry->GetWeighting() );
+ aListIndexMap.push_back( nFoundIdx );
+ }
+
+ // update color ID data map (maps color IDs to color list indexes), replace old by new list indexes
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ aIt->mnIndex = aListIndexMap[ aIt->mnIndex ];
+}
+
+void XclExpPaletteImpl::ReduceLeastUsedColor()
+{
+ // find a list color to remove
+ sal_uInt32 nRemove = GetLeastUsedListColor();
+ // find its nearest neighbor
+ sal_uInt32 nKeep = GetNearestListColor( nRemove );
+
+ // merge both colors to one color, remove one color from list
+ XclListColor* pKeepEntry = &mxColorList->at(nKeep);
+ XclListColor* pRemoveEntry = &mxColorList->at(nRemove);
+ if( pKeepEntry && pRemoveEntry )
+ {
+ // merge both colors (if pKeepEntry is a base color, it will not change)
+ pKeepEntry->Merge( *pRemoveEntry );
+ // remove the less used color, adjust nKeep index if kept color follows removed color
+ XclListColorList::iterator itr = mxColorList->begin();
+ ::std::advance(itr, nRemove);
+ mxColorList->erase(itr);
+ if( nKeep > nRemove ) --nKeep;
+
+ // recalculate color ID data map (maps color IDs to color list indexes)
+ for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mnIndex > nRemove )
+ --aIt->mnIndex;
+ else if( aIt->mnIndex == nRemove )
+ aIt->mnIndex = nKeep;
+ }
+ }
+}
+
+sal_uInt32 XclExpPaletteImpl::GetLeastUsedListColor() const
+{
+ sal_uInt32 nFound = 0;
+ sal_uInt32 nMinW = SAL_MAX_UINT32;
+
+ for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
+ {
+ XclListColor& pEntry = mxColorList->at( nIdx );
+ // ignore the base colors
+ if( !pEntry.IsBaseColor() && (pEntry.GetWeighting() < nMinW) )
+ {
+ nFound = nIdx;
+ nMinW = pEntry.GetWeighting();
+ }
+ }
+ return nFound;
+}
+
+sal_uInt32 XclExpPaletteImpl::GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const
+{
+ sal_uInt32 nFound = 0;
+ sal_Int32 nMinD = SAL_MAX_INT32;
+
+ for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
+ {
+ if( nIdx != nIgnore )
+ {
+ if( XclListColor* pEntry = &mxColorList->at(nIdx) )
+ {
+ sal_Int32 nDist = lclGetColorDistance( rColor, pEntry->GetColor() );
+ if( nDist < nMinD )
+ {
+ nFound = nIdx;
+ nMinD = nDist;
+ }
+ }
+ }
+ }
+ return nFound;
+}
+
+sal_uInt32 XclExpPaletteImpl::GetNearestListColor( sal_uInt32 nIndex ) const
+{
+ if (nIndex >= mxColorList->size())
+ return 0;
+ XclListColor* pEntry = &mxColorList->at(nIndex);
+ return GetNearestListColor( pEntry->GetColor(), nIndex );
+}
+
+sal_Int32 XclExpPaletteImpl::GetNearestPaletteColor(
+ sal_uInt32& rnIndex, const Color& rColor, bool bDefaultOnly ) const
+{
+ rnIndex = 0;
+ sal_Int32 nDist = SAL_MAX_INT32;
+
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
+ aIt != aEnd; ++aIt )
+ {
+ if( !bDefaultOnly || !aIt->mbUsed )
+ {
+ sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
+ if( nCurrDist < nDist )
+ {
+ rnIndex = aIt - maPalette.begin();
+ nDist = nCurrDist;
+ }
+ }
+ }
+ return nDist;
+}
+
+sal_Int32 XclExpPaletteImpl::GetNearPaletteColors(
+ sal_uInt32& rnFirst, sal_uInt32& rnSecond, const Color& rColor ) const
+{
+ rnFirst = rnSecond = 0;
+ sal_Int32 nDist1 = SAL_MAX_INT32;
+ sal_Int32 nDist2 = SAL_MAX_INT32;
+
+ for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
+ aIt != aEnd; ++aIt )
+ {
+ sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
+ if( nCurrDist < nDist1 )
+ {
+ rnSecond = rnFirst;
+ nDist2 = nDist1;
+ rnFirst = aIt - maPalette.begin();
+ nDist1 = nCurrDist;
+ }
+ else if( nCurrDist < nDist2 )
+ {
+ rnSecond = aIt - maPalette.begin();
+ nDist2 = nCurrDist;
+ }
+ }
+ return nDist1;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpPalette::XclExpPalette( const XclExpRoot& rRoot ) :
+ XclDefaultPalette( rRoot ),
+ XclExpRecord( EXC_ID_PALETTE )
+{
+ mxImpl.reset( new XclExpPaletteImpl( *this ) );
+ SetRecSize( GetColorCount() * 4 + 2 );
+}
+
+XclExpPalette::~XclExpPalette()
+{
+}
+
+sal_uInt32 XclExpPalette::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
+{
+ return mxImpl->InsertColor( rColor, eType, nAutoDefault );
+}
+
+sal_uInt32 XclExpPalette::GetColorIdFromIndex( sal_uInt16 nIndex )
+{
+ return XclExpPaletteImpl::GetColorIdFromIndex( nIndex );
+}
+
+void XclExpPalette::Finalize()
+{
+ mxImpl->Finalize();
+}
+
+sal_uInt16 XclExpPalette::GetColorIndex( sal_uInt32 nColorId ) const
+{
+ return mxImpl->GetColorIndex( nColorId );
+}
+
+void XclExpPalette::GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
+{
+ return mxImpl->GetMixedColors( rnXclForeIx, rnXclBackIx, rnXclPattern, nForeColorId, nBackColorId );
+}
+
+ColorData XclExpPalette::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ return mxImpl->GetColorData( nXclIndex );
+}
+
+void XclExpPalette::Save( XclExpStream& rStrm )
+{
+ if( !mxImpl->IsDefaultPalette() )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpPalette::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mxImpl->IsDefaultPalette() )
+ mxImpl->SaveXml( rStrm );
+}
+
+void XclExpPalette::WriteBody( XclExpStream& rStrm )
+{
+ mxImpl->WriteBody( rStrm );
+}
+
+// FONT record - font information =============================================
+
+namespace {
+
+typedef ::std::pair< sal_uInt16, sal_Int16 > WhichAndScript;
+
+sal_Int16 lclCheckFontItems( const SfxItemSet& rItemSet,
+ const WhichAndScript& rWAS1, const WhichAndScript& rWAS2, const WhichAndScript& rWAS3 )
+{
+ if( ScfTools::CheckItem( rItemSet, rWAS1.first, false ) ) return rWAS1.second;
+ if( ScfTools::CheckItem( rItemSet, rWAS2.first, false ) ) return rWAS2.second;
+ if( ScfTools::CheckItem( rItemSet, rWAS3.first, false ) ) return rWAS3.second;
+ return 0;
+};
+
+} // namespace
+
+sal_Int16 XclExpFontHelper::GetFirstUsedScript( const XclExpRoot& rRoot, const SfxItemSet& rItemSet )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ /* #i17050# #i107170# We need to determine which font items are set in the
+ item set, and which script type we should prefer according to the
+ current language settings. */
+
+ static const WhichAndScript WAS_LATIN( ATTR_FONT, ::com::sun::star::i18n::ScriptType::LATIN );
+ static const WhichAndScript WAS_ASIAN( ATTR_CJK_FONT, ::com::sun::star::i18n::ScriptType::ASIAN );
+ static const WhichAndScript WAS_CMPLX( ATTR_CTL_FONT, ::com::sun::star::i18n::ScriptType::COMPLEX );
+
+ /* do not let a font from a parent style override an explicit
+ cell font. */
+
+ sal_Int16 nDefScript = rRoot.GetDefApiScript();
+ sal_Int16 nScript = 0;
+ const SfxItemSet* pCurrSet = &rItemSet;
+
+ while( (nScript == 0) && pCurrSet )
+ {
+ switch( nDefScript )
+ {
+ case ApiScriptType::LATIN:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_LATIN, WAS_CMPLX, WAS_ASIAN );
+ break;
+ case ApiScriptType::ASIAN:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_ASIAN, WAS_CMPLX, WAS_LATIN );
+ break;
+ case ApiScriptType::COMPLEX:
+ nScript = lclCheckFontItems( *pCurrSet, WAS_CMPLX, WAS_ASIAN, WAS_LATIN );
+ break;
+ default:
+ DBG_ERRORFILE( "XclExpFontHelper::GetFirstUsedScript - unknown script type" );
+ nScript = ApiScriptType::LATIN;
+ };
+ pCurrSet = pCurrSet->GetParent();
+ }
+
+ return nScript;
+}
+
+Font XclExpFontHelper::GetFontFromItemSet( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+ // if WEAK is passed, guess script type from existing items in the item set
+ if( nScript == ApiScriptType::WEAK )
+ nScript = GetFirstUsedScript( rRoot, rItemSet );
+
+ // convert to core script type constants
+ sal_uInt8 nScScript = SCRIPTTYPE_LATIN;
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: nScScript = SCRIPTTYPE_LATIN; break;
+ case ApiScriptType::ASIAN: nScScript = SCRIPTTYPE_ASIAN; break;
+ case ApiScriptType::COMPLEX: nScScript = SCRIPTTYPE_COMPLEX; break;
+ default: DBG_ERRORFILE( "XclExpFontHelper::GetFontFromItemSet - unknown script type" );
+ }
+
+ // fill the font object
+ Font aFont;
+ ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW, 0, 0, 0, nScScript );
+ return aFont;
+}
+
+bool XclExpFontHelper::CheckItems( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript, bool bDeep )
+{
+ static const sal_uInt16 pnCommonIds[] = {
+ ATTR_FONT_UNDERLINE, ATTR_FONT_CROSSEDOUT, ATTR_FONT_CONTOUR,
+ ATTR_FONT_SHADOWED, ATTR_FONT_COLOR, ATTR_FONT_LANGUAGE, 0 };
+ static const sal_uInt16 pnLatinIds[] = {
+ ATTR_FONT, ATTR_FONT_HEIGHT, ATTR_FONT_WEIGHT, ATTR_FONT_POSTURE, 0 };
+ static const sal_uInt16 pnAsianIds[] = {
+ ATTR_CJK_FONT, ATTR_CJK_FONT_HEIGHT, ATTR_CJK_FONT_WEIGHT, ATTR_CJK_FONT_POSTURE, 0 };
+ static const sal_uInt16 pnComplexIds[] = {
+ ATTR_CTL_FONT, ATTR_CTL_FONT_HEIGHT, ATTR_CTL_FONT_WEIGHT, ATTR_CTL_FONT_POSTURE, 0 };
+
+ bool bUsed = ScfTools::CheckItems( rItemSet, pnCommonIds, bDeep );
+ if( !bUsed )
+ {
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ // if WEAK is passed, guess script type from existing items in the item set
+ if( nScript == ApiScriptType::WEAK )
+ nScript = GetFirstUsedScript( rRoot, rItemSet );
+ // check the correct items
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: bUsed = ScfTools::CheckItems( rItemSet, pnLatinIds, bDeep ); break;
+ case ApiScriptType::ASIAN: bUsed = ScfTools::CheckItems( rItemSet, pnAsianIds, bDeep ); break;
+ case ApiScriptType::COMPLEX: bUsed = ScfTools::CheckItems( rItemSet, pnComplexIds, bDeep ); break;
+ default: DBG_ERRORFILE( "XclExpFontHelper::CheckItems - unknown script type" );
+ }
+ }
+ return bUsed;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_uInt32 lclCalcHash( const XclFontData& rFontData )
+{
+ sal_uInt32 nHash = rFontData.maName.Len();
+ nHash += rFontData.maColor.GetColor() * 2;
+ nHash += rFontData.mnWeight * 3;
+ nHash += rFontData.mnCharSet * 5;
+ nHash += rFontData.mnFamily * 7;
+ nHash += rFontData.mnHeight * 11;
+ nHash += rFontData.mnUnderline * 13;
+ nHash += rFontData.mnEscapem * 17;
+ if( rFontData.mbItalic ) nHash += 19;
+ if( rFontData.mbStrikeout ) nHash += 23;
+ if( rFontData.mbOutline ) nHash += 29;
+ if( rFontData.mbShadow ) nHash += 31;
+ return nHash;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpFont::XclExpFont( const XclExpRoot& rRoot,
+ const XclFontData& rFontData, XclExpColorType eColorType ) :
+ XclExpRecord( EXC_ID2_FONT, 14 ),
+ XclExpRoot( rRoot ),
+ maData( rFontData )
+{
+ // insert font color into palette
+ mnColorId = rRoot.GetPalette().InsertColor( rFontData.maColor, eColorType, EXC_COLOR_FONTAUTO );
+ // hash value for faster comparison
+ mnHash = lclCalcHash( maData );
+ // record size
+ sal_Size nStrLen = maData.maName.Len();
+ SetRecSize( ((GetBiff() == EXC_BIFF8) ? (nStrLen * 2 + 1) : nStrLen) + 15 );
+}
+
+bool XclExpFont::Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const
+{
+ return (mnHash == nHash) && (maData == rFontData);
+}
+
+void XclExpFont::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_font, FSEND );
+ XclXmlUtils::WriteFontData( rStyleSheet, maData, XML_name );
+ // OOXTODO: XML_scheme; //scheme/@val values: "major", "minor", "none"
+ rStyleSheet->endElement( XML_font );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpFont::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nAttr = EXC_FONTATTR_NONE;
+ ::set_flag( nAttr, EXC_FONTATTR_ITALIC, maData.mbItalic );
+ ::set_flag( nAttr, EXC_FONTATTR_STRIKEOUT, maData.mbStrikeout );
+ ::set_flag( nAttr, EXC_FONTATTR_OUTLINE, maData.mbOutline );
+ ::set_flag( nAttr, EXC_FONTATTR_SHADOW, maData.mbShadow );
+
+ DBG_ASSERT( maData.maName.Len() < 256, "XclExpFont::WriteBody - font name too long" );
+ XclExpString aFontName;
+ if( GetBiff() <= EXC_BIFF5 )
+ aFontName.AssignByte( maData.maName, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aFontName.Assign( maData.maName, EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH );
+
+ rStrm << maData.mnHeight
+ << nAttr
+ << GetPalette().GetColorIndex( mnColorId )
+ << maData.mnWeight
+ << maData.mnEscapem
+ << maData.mnUnderline
+ << maData.mnFamily
+ << maData.mnCharSet
+ << sal_uInt8( 0 )
+ << aFontName;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpBlindFont::XclExpBlindFont( const XclExpRoot& rRoot ) :
+ XclExpFont( rRoot, XclFontData(), EXC_COLOR_CELLTEXT )
+{
+}
+
+bool XclExpBlindFont::Equals( const XclFontData& /*rFontData*/, sal_uInt32 /*nHash*/ ) const
+{
+ return false;
+}
+
+void XclExpBlindFont::Save( XclExpStream& /*rStrm*/ )
+{
+ // do nothing
+}
+
+// ============================================================================
+
+XclExpFontBuffer::XclExpFontBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ mnXclMaxSize( 0 )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF4: mnXclMaxSize = EXC_FONT_MAXCOUNT4; break;
+ case EXC_BIFF5: mnXclMaxSize = EXC_FONT_MAXCOUNT5; break;
+ case EXC_BIFF8: mnXclMaxSize = EXC_FONT_MAXCOUNT8; break;
+ default: DBG_ERROR_BIFF();
+ }
+ InitDefaultFonts();
+}
+
+const XclExpFont* XclExpFontBuffer::GetFont( sal_uInt16 nXclFont ) const
+{
+ return maFontList.GetRecord( nXclFont ).get();
+}
+
+const XclFontData& XclExpFontBuffer::GetAppFontData() const
+{
+ return maFontList.GetRecord( EXC_FONT_APP )->GetFontData(); // exists always
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const XclFontData& rFontData, XclExpColorType eColorType, bool bAppFont )
+{
+ if( bAppFont )
+ {
+ XclExpFontRef xFont( new XclExpFont( GetRoot(), rFontData, eColorType ) );
+ maFontList.ReplaceRecord( xFont, EXC_FONT_APP );
+ // set width of '0' character for column width export
+ SetCharWidth( xFont->GetFontData() );
+ return EXC_FONT_APP;
+ }
+
+ size_t nPos = Find( rFontData );
+ if( nPos == EXC_FONTLIST_NOTFOUND )
+ {
+ // not found in buffer - create new font
+ size_t nSize = maFontList.GetSize();
+ if( nSize < mnXclMaxSize )
+ {
+ // possible to insert
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), rFontData, eColorType ) );
+ nPos = nSize; // old size is last position now
+ }
+ else
+ {
+ // buffer is full - ignore new font, use default font
+ nPos = EXC_FONT_APP;
+ }
+ }
+ return static_cast< sal_uInt16 >( nPos );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const Font& rFont, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( XclFontData( rFont ), eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert(
+ const SvxFont& rFont, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( XclFontData( rFont ), eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert( const SfxItemSet& rItemSet,
+ sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
+{
+ // #i17050# script type now provided by caller
+ Font aFont = XclExpFontHelper::GetFontFromItemSet( GetRoot(), rItemSet, nScript );
+ return Insert( aFont, eColorType, bAppFont );
+}
+
+sal_uInt16 XclExpFontBuffer::Insert( const ScPatternAttr& rPattern,
+ sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
+{
+ return Insert( rPattern.GetItemSet(), nScript, eColorType, bAppFont );
+}
+
+void XclExpFontBuffer::Save( XclExpStream& rStrm )
+{
+ maFontList.Save( rStrm );
+}
+
+void XclExpFontBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maFontList.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_fonts,
+ XML_count, OString::valueOf( (sal_Int32) maFontList.GetSize() ).getStr(),
+ FSEND );
+
+ maFontList.SaveXml( rStrm );
+
+ rStyleSheet->endElement( XML_fonts );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpFontBuffer::InitDefaultFonts()
+{
+ XclFontData aFontData;
+ aFontData.maName.AssignAscii( "Arial" );
+ aFontData.SetScFamily( FAMILY_DONTKNOW );
+ aFontData.SetFontEncoding( ScfTools::GetSystemTextEncoding() );
+ aFontData.SetScHeight( 200 ); // 200 twips = 10 pt
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_BOLD );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+ aFontData.SetScPosture( ITALIC_NORMAL );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ aFontData.SetScWeight( WEIGHT_BOLD );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ // the blind font with index 4
+ maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
+ // already add the first user defined font (Excel does it too)
+ aFontData.SetScWeight( WEIGHT_NORMAL );
+ aFontData.SetScPosture( ITALIC_NONE );
+ maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ }
+ break;
+ case EXC_BIFF8:
+ {
+ XclExpFontRef xFont( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ maFontList.AppendRecord( xFont );
+ if( GetOutput() == EXC_OUTPUT_BINARY )
+ // the blind font with index 4
+ maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+size_t XclExpFontBuffer::Find( const XclFontData& rFontData )
+{
+ sal_uInt32 nHash = lclCalcHash( rFontData );
+ for( size_t nPos = 0, nSize = maFontList.GetSize(); nPos < nSize; ++nPos )
+ if( maFontList.GetRecord( nPos )->Equals( rFontData, nHash ) )
+ return nPos;
+ return EXC_FONTLIST_NOTFOUND;
+}
+
+// FORMAT record - number formats =============================================
+
+/** Predicate for search algorithm. */
+struct XclExpNumFmtPred
+{
+ sal_uLong mnScNumFmt;
+ inline explicit XclExpNumFmtPred( sal_uLong nScNumFmt ) : mnScNumFmt( nScNumFmt ) {}
+ inline bool operator()( const XclExpNumFmt& rFormat ) const
+ { return rFormat.mnScNumFmt == mnScNumFmt; }
+};
+
+// ----------------------------------------------------------------------------
+
+XclExpNumFmtBuffer::XclExpNumFmtBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ /* Compiler needs a hint, this doesn't work: new NfKeywordTable;
+ cannot convert from 'class String *' to 'class String (*)[54]'
+ The effective result here is class String (*)[54*1] */
+ mxFormatter( new SvNumberFormatter( rRoot.GetDoc().GetServiceManager(), LANGUAGE_ENGLISH_US ) ),
+ mpKeywordTable( new NfKeywordTable[ 1 ] ),
+ mnStdFmt( GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: mnXclOffset = EXC_FORMAT_OFFSET5; break;
+ case EXC_BIFF8: mnXclOffset = EXC_FORMAT_OFFSET8; break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
+ // remap codes unknown to Excel
+ (*mpKeywordTable)[ NF_KEY_NN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDD" ) );
+ (*mpKeywordTable)[ NF_KEY_NNN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDDD" ) );
+ // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
+ (*mpKeywordTable)[ NF_KEY_NNNN ] = String( RTL_CONSTASCII_USTRINGPARAM( "DDDD" ) );
+ // Export the Thai T NatNum modifier.
+ (*mpKeywordTable)[ NF_KEY_THAI_T ] = String( RTL_CONSTASCII_USTRINGPARAM( "T" ) );
+}
+
+XclExpNumFmtBuffer::~XclExpNumFmtBuffer()
+{
+ delete[] mpKeywordTable;
+}
+
+sal_uInt16 XclExpNumFmtBuffer::Insert( sal_uLong nScNumFmt )
+{
+ XclExpNumFmtVec::const_iterator aIt =
+ ::std::find_if( maFormatMap.begin(), maFormatMap.end(), XclExpNumFmtPred( nScNumFmt ) );
+ if( aIt != maFormatMap.end() )
+ return aIt->mnXclNumFmt;
+
+ size_t nSize = maFormatMap.size();
+ if( nSize < static_cast< size_t >( 0xFFFF - mnXclOffset ) )
+ {
+ sal_uInt16 nXclNumFmt = static_cast< sal_uInt16 >( nSize + mnXclOffset );
+ maFormatMap.push_back( XclExpNumFmt( nScNumFmt, nXclNumFmt ) );
+ return nXclNumFmt;
+ }
+
+ return 0;
+}
+
+void XclExpNumFmtBuffer::Save( XclExpStream& rStrm )
+{
+ for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
+ WriteFormatRecord( rStrm, *aIt );
+}
+
+void XclExpNumFmtBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !maFormatMap.size() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_numFmts,
+ XML_count, OString::valueOf( (sal_Int32) maFormatMap.size() ).getStr(),
+ FSEND );
+ for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
+ {
+ rStyleSheet->singleElement( XML_numFmt,
+ XML_numFmtId, OString::valueOf( sal_Int32(aIt->mnXclNumFmt) ).getStr(),
+ XML_formatCode, XclXmlUtils::ToOString( GetFormatCode( *aIt ) ).getStr(),
+ FSEND );
+ }
+ rStyleSheet->endElement( XML_numFmts );
+}
+
+void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const String& rFormatStr )
+{
+ XclExpString aExpStr;
+ if( GetBiff() <= EXC_BIFF5 )
+ aExpStr.AssignByte( rFormatStr, GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ aExpStr.Assign( rFormatStr );
+
+ rStrm.StartRecord( EXC_ID4_FORMAT, 2 + aExpStr.GetSize() );
+ rStrm << nXclNumFmt << aExpStr;
+ rStrm.EndRecord();
+}
+
+void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat )
+{
+ WriteFormatRecord( rStrm, rFormat.mnXclNumFmt, GetFormatCode( rFormat ) );
+}
+
+String XclExpNumFmtBuffer::GetFormatCode( const XclExpNumFmt& rFormat )
+{
+ String aFormatStr;
+
+ if( const SvNumberformat* pEntry = GetFormatter().GetEntry( rFormat.mnScNumFmt ) )
+ {
+ if( pEntry->GetType() == NUMBERFORMAT_LOGICAL )
+ {
+ // build Boolean number format
+ Color* pColor = 0;
+ String aTemp;
+ const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
+ aFormatStr.Append( '"' ).Append( aTemp ).AppendAscii( "\";\"" ).Append( aTemp ).AppendAscii( "\";\"" );
+ const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
+ aFormatStr.Append( aTemp ).Append( '"' );
+ }
+ else
+ {
+ LanguageType eLang = pEntry->GetLanguage();
+ if( eLang != LANGUAGE_ENGLISH_US )
+ {
+ xub_StrLen nCheckPos;
+ short nType = NUMBERFORMAT_DEFINED;
+ sal_uInt32 nKey;
+ String aTemp( pEntry->GetFormatstring() );
+ mxFormatter->PutandConvertEntry( aTemp, nCheckPos, nType, nKey, eLang, LANGUAGE_ENGLISH_US );
+ DBG_ASSERT( nCheckPos == 0, "XclExpNumFmtBuffer::WriteFormatRecord - format code not convertible" );
+ pEntry = mxFormatter->GetEntry( nKey );
+ }
+
+ aFormatStr = pEntry->GetMappedFormatstring( *mpKeywordTable, *mxFormatter->GetLocaleData() );
+ if( aFormatStr.EqualsAscii( "Standard" ) )
+ aFormatStr.AssignAscii( "General" );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpNumFmtBuffer::WriteFormatRecord - format not found" );
+ aFormatStr.AssignAscii( "General" );
+ }
+
+ return aFormatStr;
+}
+
+// XF, STYLE record - Cell formatting =========================================
+
+bool XclExpCellProt::FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle )
+{
+ const ScProtectionAttr& rProtItem = GETITEM( rItemSet, ScProtectionAttr, ATTR_PROTECTION );
+ mbLocked = rProtItem.GetProtection();
+ mbHidden = rProtItem.GetHideFormula() || rProtItem.GetHideCell();
+ return ScfTools::CheckItem( rItemSet, ATTR_PROTECTION, bStyle );
+}
+
+void XclExpCellProt::FillToXF3( sal_uInt16& rnProt ) const
+{
+ ::set_flag( rnProt, EXC_XF_LOCKED, mbLocked );
+ ::set_flag( rnProt, EXC_XF_HIDDEN, mbHidden );
+}
+
+void XclExpCellProt::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ rStrm.GetCurrentStream()->singleElement( XML_protection,
+ XML_locked, XclXmlUtils::ToPsz( mbLocked ),
+ XML_hidden, XclXmlUtils::ToPsz( mbHidden ),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclExpCellAlign::FillFromItemSet(
+ const SfxItemSet& rItemSet, bool bForceLineBreak, XclBiff eBiff, bool bStyle )
+{
+ bool bUsed = false;
+ SvxCellHorJustify eHorAlign = GETITEMVALUE( rItemSet, SvxHorJustifyItem, ATTR_HOR_JUSTIFY, SvxCellHorJustify );
+ SvxCellVerJustify eVerAlign = GETITEMVALUE( rItemSet, SvxVerJustifyItem, ATTR_VER_JUSTIFY, SvxCellVerJustify );
+
+ switch( eBiff )
+ {
+ // ALL 'case's - run through!
+
+ case EXC_BIFF8: // attributes new in BIFF8
+ {
+ // text indent
+ long nTmpIndent = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_INDENT, sal_Int32 );
+ (nTmpIndent += 100) /= 200; // 1 Excel unit == 10 pt == 200 twips
+ mnIndent = limit_cast< sal_uInt8 >( nTmpIndent, 0, 15 );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_INDENT, bStyle );
+
+ // shrink to fit
+ mbShrink = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_SHRINKTOFIT, sal_Bool );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_SHRINKTOFIT, bStyle );
+
+ // CTL text direction
+ SetScFrameDir( GETITEMVALUE( rItemSet, SvxFrameDirectionItem, ATTR_WRITINGDIR, SvxFrameDirection ) );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_WRITINGDIR, bStyle );
+ }
+
+ case EXC_BIFF5: // attributes new in BIFF5
+ case EXC_BIFF4: // attributes new in BIFF4
+ {
+ // vertical alignment
+ SetScVerAlign( eVerAlign );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_VER_JUSTIFY, bStyle );
+
+ // stacked/rotation
+ bool bStacked = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_STACKED, sal_Bool );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_STACKED, bStyle );
+ if( bStacked )
+ {
+ mnRotation = EXC_ROT_STACKED;
+ }
+ else
+ {
+ // rotation
+ sal_Int32 nScRot = GETITEMVALUE( rItemSet, SfxInt32Item, ATTR_ROTATE_VALUE, sal_Int32 );
+ mnRotation = XclTools::GetXclRotation( nScRot );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_ROTATE_VALUE, bStyle );
+ }
+ mnOrient = XclTools::GetXclOrientFromRot( mnRotation );
+ }
+
+ case EXC_BIFF3: // attributes new in BIFF3
+ {
+ // text wrap
+ mbLineBreak = bForceLineBreak || GETITEMBOOL( rItemSet, ATTR_LINEBREAK );
+ bUsed |= bForceLineBreak || ScfTools::CheckItem( rItemSet, ATTR_LINEBREAK, bStyle );
+ }
+
+ case EXC_BIFF2: // attributes new in BIFF2
+ {
+ // horizontal alignment
+ SetScHorAlign( eHorAlign );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_HOR_JUSTIFY, bStyle );
+ }
+
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ if (eBiff == EXC_BIFF8)
+ {
+ // Adjust for distributed alignments.
+ if (eHorAlign == SVX_HOR_JUSTIFY_BLOCK)
+ {
+ SvxCellJustifyMethod eHorJustMethod = GETITEMVALUE(
+ rItemSet, SvxJustifyMethodItem, ATTR_HOR_JUSTIFY_METHOD, SvxCellJustifyMethod);
+ if (eHorJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
+ mnHorAlign = EXC_XF_HOR_DISTRIB;
+ }
+
+ if (eVerAlign == SVX_VER_JUSTIFY_BLOCK)
+ {
+ SvxCellJustifyMethod eVerJustMethod = GETITEMVALUE(
+ rItemSet, SvxJustifyMethodItem, ATTR_VER_JUSTIFY_METHOD, SvxCellJustifyMethod);
+ if (eVerJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
+ mnVerAlign = EXC_XF_VER_DISTRIB;
+ }
+ }
+
+ return bUsed;
+}
+
+void XclExpCellAlign::FillToXF5( sal_uInt16& rnAlign ) const
+{
+ ::insert_value( rnAlign, mnHorAlign, 0, 3 );
+ ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
+ ::insert_value( rnAlign, mnVerAlign, 4, 3 );
+ ::insert_value( rnAlign, mnOrient, 8, 2 );
+}
+
+void XclExpCellAlign::FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const
+{
+ ::insert_value( rnAlign, mnHorAlign, 0, 3 );
+ ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
+ ::insert_value( rnAlign, mnVerAlign, 4, 3 );
+ ::insert_value( rnAlign, mnRotation, 8, 8 );
+ ::insert_value( rnMiscAttrib, mnIndent, 0, 4 );
+ ::set_flag( rnMiscAttrib, EXC_XF8_SHRINK, mbShrink );
+ ::insert_value( rnMiscAttrib, mnTextDir, 6, 2 );
+}
+
+static const char* ToHorizontalAlignment( sal_uInt8 nHorAlign )
+{
+ switch( nHorAlign )
+ {
+ case EXC_XF_HOR_GENERAL: return "general";
+ case EXC_XF_HOR_LEFT: return "left";
+ case EXC_XF_HOR_CENTER: return "center";
+ case EXC_XF_HOR_RIGHT: return "right";
+ case EXC_XF_HOR_FILL: return "fill";
+ case EXC_XF_HOR_JUSTIFY: return "justify";
+ case EXC_XF_HOR_CENTER_AS: return "centerContinuous";
+ case EXC_XF_HOR_DISTRIB: return "distributed";
+ }
+ return "*unknown*";
+}
+
+static const char* ToVerticalAlignment( sal_uInt8 nVerAlign )
+{
+ switch( nVerAlign )
+ {
+ case EXC_XF_VER_TOP: return "top";
+ case EXC_XF_VER_CENTER: return "center";
+ case EXC_XF_VER_BOTTOM: return "bottom";
+ case EXC_XF_VER_JUSTIFY: return "justify";
+ case EXC_XF_VER_DISTRIB: return "distributed";
+ }
+ return "*unknown*";
+}
+
+void XclExpCellAlign::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ rStrm.GetCurrentStream()->singleElement( XML_alignment,
+ XML_horizontal, ToHorizontalAlignment( mnHorAlign ),
+ XML_vertical, ToVerticalAlignment( mnVerAlign ),
+ XML_textRotation, OString::valueOf( (sal_Int32) mnRotation ).getStr(),
+ XML_wrapText, XclXmlUtils::ToPsz( mbLineBreak ),
+ XML_indent, OString::valueOf( (sal_Int32) mnIndent ).getStr(),
+ // OOXTODO: XML_relativeIndent, mnIndent?
+ // OOXTODO: XML_justifyLastLine,
+ XML_shrinkToFit, XclXmlUtils::ToPsz( mbShrink ),
+ // OOXTODO: XML_readingOrder,
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+void lclGetBorderLine(
+ sal_uInt8& rnXclLine, sal_uInt32& rnColorId,
+ const ::editeng::SvxBorderLine* pLine, XclExpPalette& rPalette, XclBiff eBiff )
+{
+ rnXclLine = EXC_LINE_NONE;
+ if( pLine )
+ {
+ sal_uInt16 nOuterWidth = pLine->GetOutWidth();
+ sal_uInt16 nDistance = pLine->GetDistance();
+ if( nDistance > 0 )
+ rnXclLine = EXC_LINE_DOUBLE;
+ else if( nOuterWidth > DEF_LINE_WIDTH_2 )
+ rnXclLine = EXC_LINE_THICK;
+ else if( nOuterWidth > DEF_LINE_WIDTH_1 )
+ {
+ rnXclLine = EXC_LINE_MEDIUM;
+ if ( pLine->GetStyle( ) == ::editeng::DASHED )
+ rnXclLine = EXC_LINE_MEDIUMDASHED;
+ }
+ else if( nOuterWidth > DEF_LINE_WIDTH_0 )
+ {
+ rnXclLine = EXC_LINE_THIN;
+ switch ( pLine->GetStyle( ) )
+ {
+ case ::editeng::DASHED:
+ rnXclLine = EXC_LINE_DASHED;
+ break;
+ case ::editeng::DOTTED:
+ rnXclLine = EXC_LINE_DOTTED;
+ break;
+ default:
+ break;
+ }
+ }
+ else if( nOuterWidth > 0 )
+ rnXclLine = EXC_LINE_HAIR;
+ else
+ rnXclLine = EXC_LINE_NONE;
+ }
+ if( (eBiff == EXC_BIFF2) && (rnXclLine != EXC_LINE_NONE) )
+ rnXclLine = EXC_LINE_THIN;
+
+ rnColorId = (pLine && (rnXclLine != EXC_LINE_NONE)) ?
+ rPalette.InsertColor( pLine->GetColor(), EXC_COLOR_CELLBORDER ) :
+ XclExpPalette::GetColorIdFromIndex( 0 );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpCellBorder::XclExpCellBorder() :
+ mnLeftColorId( XclExpPalette::GetColorIdFromIndex( mnLeftColor ) ),
+ mnRightColorId( XclExpPalette::GetColorIdFromIndex( mnRightColor ) ),
+ mnTopColorId( XclExpPalette::GetColorIdFromIndex( mnTopColor ) ),
+ mnBottomColorId( XclExpPalette::GetColorIdFromIndex( mnBottomColor ) ),
+ mnDiagColorId( XclExpPalette::GetColorIdFromIndex( mnDiagColor ) )
+{
+}
+
+bool XclExpCellBorder::FillFromItemSet(
+ const SfxItemSet& rItemSet, XclExpPalette& rPalette, XclBiff eBiff, bool bStyle )
+{
+ bool bUsed = false;
+
+ switch( eBiff )
+ {
+ // ALL 'case's - run through!
+
+ case EXC_BIFF8: // attributes new in BIFF8
+ {
+ const SvxLineItem& rTLBRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_TLBR );
+ sal_uInt8 nTLBRLine;
+ sal_uInt32 nTLBRColorId;
+ lclGetBorderLine( nTLBRLine, nTLBRColorId, rTLBRItem.GetLine(), rPalette, eBiff );
+ mbDiagTLtoBR = (nTLBRLine != EXC_LINE_NONE);
+
+ const SvxLineItem& rBLTRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_BLTR );
+ sal_uInt8 nBLTRLine;
+ sal_uInt32 nBLTRColorId;
+ lclGetBorderLine( nBLTRLine, nBLTRColorId, rBLTRItem.GetLine(), rPalette, eBiff );
+ mbDiagBLtoTR = (nBLTRLine != EXC_LINE_NONE);
+
+ if( ::ScHasPriority( rTLBRItem.GetLine(), rBLTRItem.GetLine() ) )
+ {
+ mnDiagLine = nTLBRLine;
+ mnDiagColorId = nTLBRColorId;
+ }
+ else
+ {
+ mnDiagLine = nBLTRLine;
+ mnDiagColorId = nBLTRColorId;
+ }
+
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER_TLBR, bStyle ) ||
+ ScfTools::CheckItem( rItemSet, ATTR_BORDER_BLTR, bStyle );
+ }
+
+ case EXC_BIFF5:
+ case EXC_BIFF4:
+ case EXC_BIFF3:
+ case EXC_BIFF2:
+ {
+ const SvxBoxItem& rBoxItem = GETITEM( rItemSet, SvxBoxItem, ATTR_BORDER );
+ lclGetBorderLine( mnLeftLine, mnLeftColorId, rBoxItem.GetLeft(), rPalette, eBiff );
+ lclGetBorderLine( mnRightLine, mnRightColorId, rBoxItem.GetRight(), rPalette, eBiff );
+ lclGetBorderLine( mnTopLine, mnTopColorId, rBoxItem.GetTop(), rPalette, eBiff );
+ lclGetBorderLine( mnBottomLine, mnBottomColorId, rBoxItem.GetBottom(), rPalette, eBiff );
+ bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER, bStyle );
+ }
+
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+
+ return bUsed;
+}
+
+void XclExpCellBorder::SetFinalColors( const XclExpPalette& rPalette )
+{
+ mnLeftColor = rPalette.GetColorIndex( mnLeftColorId );
+ mnRightColor = rPalette.GetColorIndex( mnRightColorId );
+ mnTopColor = rPalette.GetColorIndex( mnTopColorId );
+ mnBottomColor = rPalette.GetColorIndex( mnBottomColorId );
+ mnDiagColor = rPalette.GetColorIndex( mnDiagColorId );
+}
+
+
+void XclExpCellBorder::FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const
+{
+ ::insert_value( rnBorder, mnTopLine, 0, 3 );
+ ::insert_value( rnBorder, mnLeftLine, 3, 3 );
+ ::insert_value( rnArea, mnBottomLine, 22, 3 );
+ ::insert_value( rnBorder, mnRightLine, 6, 3 );
+ ::insert_value( rnBorder, mnTopColor, 9, 7 );
+ ::insert_value( rnBorder, mnLeftColor, 16, 7 );
+ ::insert_value( rnArea, mnBottomColor, 25, 7 );
+ ::insert_value( rnBorder, mnRightColor, 23, 7 );
+}
+
+void XclExpCellBorder::FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const
+{
+ ::insert_value( rnBorder1, mnLeftLine, 0, 4 );
+ ::insert_value( rnBorder1, mnRightLine, 4, 4 );
+ ::insert_value( rnBorder1, mnTopLine, 8, 4 );
+ ::insert_value( rnBorder1, mnBottomLine, 12, 4 );
+ ::insert_value( rnBorder1, mnLeftColor, 16, 7 );
+ ::insert_value( rnBorder1, mnRightColor, 23, 7 );
+ ::insert_value( rnBorder2, mnTopColor, 0, 7 );
+ ::insert_value( rnBorder2, mnBottomColor, 7, 7 );
+ ::insert_value( rnBorder2, mnDiagColor, 14, 7 );
+ ::insert_value( rnBorder2, mnDiagLine, 21, 4 );
+ ::set_flag( rnBorder1, EXC_XF_DIAGONAL_TL_TO_BR, mbDiagTLtoBR );
+ ::set_flag( rnBorder1, EXC_XF_DIAGONAL_BL_TO_TR, mbDiagBLtoTR );
+}
+
+void XclExpCellBorder::FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const
+{
+ ::insert_value( rnLine, mnLeftLine, 0, 4 );
+ ::insert_value( rnLine, mnRightLine, 4, 4 );
+ ::insert_value( rnLine, mnTopLine, 8, 4 );
+ ::insert_value( rnLine, mnBottomLine, 12, 4 );
+ ::insert_value( rnColor, mnLeftColor, 0, 7 );
+ ::insert_value( rnColor, mnRightColor, 7, 7 );
+ ::insert_value( rnColor, mnTopColor, 16, 7 );
+ ::insert_value( rnColor, mnBottomColor, 23, 7 );
+}
+
+static const char* ToLineStyle( sal_uInt8 nLineStyle )
+{
+ switch( nLineStyle )
+ {
+ case EXC_LINE_NONE: return "none";
+ case EXC_LINE_THIN: return "thin";
+ case EXC_LINE_MEDIUM: return "medium";
+ case EXC_LINE_THICK: return "thick";
+ case EXC_LINE_DOUBLE: return "double";
+ case EXC_LINE_HAIR: return "hair";
+ case EXC_LINE_DOTTED: return "dotted";
+ case EXC_LINE_DASHED: return "dashed";
+ case EXC_LINE_MEDIUMDASHED: return "mediumdashed";
+ }
+ return "*unknown*";
+}
+
+static void lcl_WriteBorder( XclExpXmlStream& rStrm, sal_Int32 nElement, sal_uInt8 nLineStyle, const Color& rColor )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ if( nLineStyle == EXC_LINE_NONE )
+ rStyleSheet->singleElement( nElement, FSEND );
+ else if( rColor == Color( 0, 0, 0, 0 ) )
+ rStyleSheet->singleElement( nElement,
+ XML_style, ToLineStyle( nLineStyle ),
+ FSEND );
+ else
+ {
+ rStyleSheet->startElement( nElement,
+ XML_style, ToLineStyle( nLineStyle ),
+ FSEND );
+ rStyleSheet->singleElement( XML_color,
+ XML_rgb, XclXmlUtils::ToOString( rColor ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( nElement );
+ }
+}
+
+void XclExpCellBorder::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
+
+ rStyleSheet->startElement( XML_border,
+ XML_diagonalUp, XclXmlUtils::ToPsz( mbDiagBLtoTR ),
+ XML_diagonalDown, XclXmlUtils::ToPsz( mbDiagTLtoBR ),
+ // OOXTODO: XML_outline,
+ FSEND );
+ lcl_WriteBorder( rStrm, XML_left, mnLeftLine, rPalette.GetColor( mnLeftColor ) );
+ lcl_WriteBorder( rStrm, XML_right, mnRightLine, rPalette.GetColor( mnRightColor ) );
+ lcl_WriteBorder( rStrm, XML_top, mnTopLine, rPalette.GetColor( mnTopColor ) );
+ lcl_WriteBorder( rStrm, XML_bottom, mnBottomLine, rPalette.GetColor( mnBottomColor ) );
+ lcl_WriteBorder( rStrm, XML_diagonal, mnDiagLine, rPalette.GetColor( mnDiagColor ) );
+ // OOXTODO: XML_vertical, XML_horizontal
+ rStyleSheet->endElement( XML_border );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpCellArea::XclExpCellArea() :
+ mnForeColorId( XclExpPalette::GetColorIdFromIndex( mnForeColor ) ),
+ mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) )
+{
+}
+
+bool XclExpCellArea::FillFromItemSet( const SfxItemSet& rItemSet, XclExpPalette& rPalette, bool bStyle )
+{
+ const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
+ if( rBrushItem.GetColor().GetTransparency() )
+ {
+ mnPattern = EXC_PATT_NONE;
+ mnForeColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
+ mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWBACK );
+ }
+ else
+ {
+ mnPattern = EXC_PATT_SOLID;
+ mnForeColorId = rPalette.InsertColor( rBrushItem.GetColor(), EXC_COLOR_CELLAREA );
+ mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
+ }
+ return ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, bStyle );
+}
+
+void XclExpCellArea::SetFinalColors( const XclExpPalette& rPalette )
+{
+ rPalette.GetMixedColors( mnForeColor, mnBackColor, mnPattern, mnForeColorId, mnBackColorId );
+}
+
+void XclExpCellArea::FillToXF5( sal_uInt32& rnArea ) const
+{
+ ::insert_value( rnArea, mnPattern, 16, 6 );
+ ::insert_value( rnArea, mnForeColor, 0, 7 );
+ ::insert_value( rnArea, mnBackColor, 7, 7 );
+}
+
+void XclExpCellArea::FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const
+{
+ ::insert_value( rnBorder2, mnPattern, 26, 6 );
+ ::insert_value( rnArea, mnForeColor, 0, 7 );
+ ::insert_value( rnArea, mnBackColor, 7, 7 );
+}
+
+void XclExpCellArea::FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const
+{
+ XclCellArea aTmp( *this );
+ if( !aTmp.IsTransparent() && (aTmp.mnBackColor == EXC_COLOR_WINDOWTEXT) )
+ aTmp.mnBackColor = 0;
+ if( aTmp.mnPattern == EXC_PATT_SOLID )
+ ::std::swap( aTmp.mnForeColor, aTmp.mnBackColor );
+ ::insert_value( rnColor, aTmp.mnForeColor, 0, 7 );
+ ::insert_value( rnColor, aTmp.mnBackColor, 7, 7 );
+ ::insert_value( rnPattern, aTmp.mnPattern, 10, 6 );
+}
+
+static const char* ToPatternType( sal_uInt8 nPattern )
+{
+ switch( nPattern )
+ {
+ case EXC_PATT_NONE: return "none";
+ case EXC_PATT_SOLID: return "solid";
+ case EXC_PATT_50_PERC: return "mediumGray";
+ case EXC_PATT_75_PERC: return "darkGray";
+ case EXC_PATT_25_PERC: return "lightGray";
+ case EXC_PATT_12_5_PERC: return "gray125";
+ case EXC_PATT_6_25_PERC: return "gray0625";
+ }
+ return "*unknown*";
+}
+
+void XclExpCellArea::SaveXml( XclExpXmlStream& rStrm ) const
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+ rStyleSheet->startElement( XML_fill,
+ FSEND );
+
+ // OOXTODO: XML_gradientFill
+
+ XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
+
+ if( mnPattern == EXC_PATT_NONE || ( mnForeColor == 0 && mnBackColor == 0 ) )
+ rStyleSheet->singleElement( XML_patternFill,
+ XML_patternType, ToPatternType( mnPattern ),
+ FSEND );
+ else
+ {
+ rStyleSheet->startElement( XML_patternFill,
+ XML_patternType, ToPatternType( mnPattern ),
+ FSEND );
+ rStyleSheet->singleElement( XML_fgColor,
+ XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnForeColor ) ).getStr(),
+ FSEND );
+ rStyleSheet->singleElement( XML_bgColor,
+ XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnBackColor ) ).getStr(),
+ FSEND );
+ rStyleSheet->endElement( XML_patternFill );
+ }
+
+ rStyleSheet->endElement( XML_fill );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXFId::XclExpXFId() :
+ mnXFId( XclExpXFBuffer::GetDefCellXFId() ),
+ mnXFIndex( EXC_XF_DEFAULTCELL )
+{
+}
+
+XclExpXFId::XclExpXFId( sal_uInt32 nXFId ) :
+ mnXFId( nXFId ),
+ mnXFIndex( EXC_XF_DEFAULTCELL )
+{
+}
+
+void XclExpXFId::ConvertXFIndex( const XclExpRoot& rRoot )
+{
+ mnXFIndex = rRoot.GetXFBuffer().GetXFIndex( mnXFId );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpXF::XclExpXF(
+ const XclExpRoot& rRoot, const ScPatternAttr& rPattern, sal_Int16 nScript,
+ sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) :
+ XclXFBase( true ),
+ XclExpRoot( rRoot )
+{
+ mnParentXFId = GetXFBuffer().InsertStyle( rPattern.GetStyleSheet() );
+ Init( rPattern.GetItemSet(), nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak, false );
+}
+
+XclExpXF::XclExpXF( const XclExpRoot& rRoot, const SfxStyleSheetBase& rStyleSheet ) :
+ XclXFBase( false ),
+ XclExpRoot( rRoot ),
+ mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
+{
+ bool bDefStyle = (rStyleSheet.GetName() == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ));
+ sal_Int16 nScript = bDefStyle ? GetDefApiScript() : ::com::sun::star::i18n::ScriptType::WEAK;
+ Init( const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet(), nScript,
+ NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false, bDefStyle );
+}
+
+XclExpXF::XclExpXF( const XclExpRoot& rRoot, bool bCellXF ) :
+ XclXFBase( bCellXF ),
+ XclExpRoot( rRoot ),
+ mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
+{
+ InitDefault();
+}
+
+bool XclExpXF::Equals( const ScPatternAttr& rPattern,
+ sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
+{
+ return IsCellXF() && (mpItemSet == &rPattern.GetItemSet()) &&
+ (!bForceLineBreak || maAlignment.mbLineBreak) &&
+ ((nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) || (mnScNumFmt == nForceScNumFmt)) &&
+ ((nForceXclFont == EXC_FONT_NOTFOUND) || (mnXclFont == nForceXclFont));
+}
+
+bool XclExpXF::Equals( const SfxStyleSheetBase& rStyleSheet ) const
+{
+ return IsStyleXF() && (mpItemSet == &const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet());
+}
+
+void XclExpXF::SetFinalColors()
+{
+ maBorder.SetFinalColors( GetPalette() );
+ maArea.SetFinalColors( GetPalette() );
+}
+
+bool XclExpXF::Equals( const XclExpXF& rCmpXF ) const
+{
+ return XclXFBase::Equals( rCmpXF ) &&
+ (maProtection == rCmpXF.maProtection) && (maAlignment == rCmpXF.maAlignment) &&
+ (maBorder == rCmpXF.maBorder) && (maArea == rCmpXF.maArea) &&
+ (mnXclFont == rCmpXF.mnXclFont) && (mnXclNumFmt == rCmpXF.mnXclNumFmt) &&
+ (mnParentXFId == rCmpXF.mnParentXFId);
+}
+
+void XclExpXF::InitDefault()
+{
+ SetRecHeader( EXC_ID5_XF, (GetBiff() == EXC_BIFF8) ? 20 : 16 );
+ mpItemSet = 0;
+ mnScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ mnXclFont = mnXclNumFmt = 0;
+}
+
+void XclExpXF::Init( const SfxItemSet& rItemSet, sal_Int16 nScript,
+ sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak, bool bDefStyle )
+{
+ InitDefault();
+ mpItemSet = &rItemSet;
+
+ // cell protection
+ mbProtUsed = maProtection.FillFromItemSet( rItemSet, IsStyleXF() );
+
+ // font
+ if( nForceXclFont == EXC_FONT_NOTFOUND )
+ {
+ mnXclFont = GetFontBuffer().Insert( rItemSet, nScript, EXC_COLOR_CELLTEXT, bDefStyle );
+ mbFontUsed = XclExpFontHelper::CheckItems( GetRoot(), rItemSet, nScript, IsStyleXF() );
+ }
+ else
+ {
+ mnXclFont = nForceXclFont;
+ mbFontUsed = true;
+ }
+
+ // number format
+ mnScNumFmt = (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) ?
+ GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong ) : nForceScNumFmt;
+ mnXclNumFmt = GetNumFmtBuffer().Insert( mnScNumFmt );
+ mbFmtUsed = ScfTools::CheckItem( rItemSet, ATTR_VALUE_FORMAT, IsStyleXF() );
+
+ // alignment
+ mbAlignUsed = maAlignment.FillFromItemSet( rItemSet, bForceLineBreak, GetBiff(), IsStyleXF() );
+
+ // cell border
+ mbBorderUsed = maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff(), IsStyleXF() );
+
+ // background area
+ mbAreaUsed = maArea.FillFromItemSet( rItemSet, GetPalette(), IsStyleXF() );
+
+ // set all b***Used flags to true in "Default"/"Normal" style
+ if( bDefStyle )
+ SetAllUsedFlags( true );
+}
+
+sal_uInt8 XclExpXF::GetUsedFlags() const
+{
+ sal_uInt8 nUsedFlags = 0;
+ /* In cell XFs a set bit means a used attribute, in style XFs a cleared bit.
+ "mbCellXF == mb***Used" evaluates to correct value in cell and style XFs. */
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_PROT, mbCellXF == mbProtUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_FONT, mbCellXF == mbFontUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_VALFMT, mbCellXF == mbFmtUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_ALIGN, mbCellXF == mbAlignUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_BORDER, mbCellXF == mbBorderUsed );
+ ::set_flag( nUsedFlags, EXC_XF_DIFF_AREA, mbCellXF == mbAreaUsed );
+ return nUsedFlags;
+}
+
+void XclExpXF::WriteBody5( XclExpStream& rStrm )
+{
+ sal_uInt16 nTypeProt = 0, nAlign = 0;
+ sal_uInt32 nArea = 0, nBorder = 0;
+
+ ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
+ ::insert_value( nTypeProt, mnParent, 4, 12 );
+ ::insert_value( nAlign, GetUsedFlags(), 10, 6 );
+
+ maProtection.FillToXF3( nTypeProt );
+ maAlignment.FillToXF5( nAlign );
+ maBorder.FillToXF5( nBorder, nArea );
+ maArea.FillToXF5( nArea );
+
+ rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nArea << nBorder;
+}
+
+void XclExpXF::WriteBody8( XclExpStream& rStrm )
+{
+ sal_uInt16 nTypeProt = 0, nAlign = 0, nMiscAttrib = 0, nArea = 0;
+ sal_uInt32 nBorder1 = 0, nBorder2 = 0;
+
+ ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
+ ::insert_value( nTypeProt, mnParent, 4, 12 );
+ ::insert_value( nMiscAttrib, GetUsedFlags(), 10, 6 );
+
+ maProtection.FillToXF3( nTypeProt );
+ maAlignment.FillToXF8( nAlign, nMiscAttrib );
+ maBorder.FillToXF8( nBorder1, nBorder2 );
+ maArea.FillToXF8( nBorder2, nArea );
+
+ rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nMiscAttrib << nBorder1 << nBorder2 << nArea;
+}
+
+void XclExpXF::WriteBody( XclExpStream& rStrm )
+{
+ XclExpXFId aParentId( mnParentXFId );
+ aParentId.ConvertXFIndex( GetRoot() );
+ mnParent = aParentId.mnXFIndex;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5: WriteBody5( rStrm ); break;
+ case EXC_BIFF8: WriteBody8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpXF::SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId )
+{
+ mnBorderId = nBorderId;
+ mnFillId = nFillId;
+}
+
+void XclExpXF::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ sal_Int32 nXfId = 0;
+ if( IsCellXF() )
+ {
+ sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( mnParentXFId );
+ nXfId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFIndex );
+ }
+
+ rStyleSheet->startElement( XML_xf,
+ XML_numFmtId, OString::valueOf( (sal_Int32) mnXclNumFmt ).getStr(),
+ XML_fontId, OString::valueOf( (sal_Int32) mnXclFont ).getStr(),
+ XML_fillId, OString::valueOf( (sal_Int32) mnFillId ).getStr(),
+ XML_borderId, OString::valueOf( (sal_Int32) mnBorderId ).getStr(),
+ XML_xfId, IsStyleXF() ? NULL : OString::valueOf( nXfId ).getStr(),
+ // OOXTODO: XML_quotePrefix,
+ // OOXTODO: XML_pivotButton,
+ // OOXTODO: XML_applyNumberFormat, ;
+ XML_applyFont, XclXmlUtils::ToPsz( mbFontUsed ),
+ // OOXTODO: XML_applyFill,
+ XML_applyBorder, XclXmlUtils::ToPsz( mbBorderUsed ),
+ XML_applyAlignment, XclXmlUtils::ToPsz( mbAlignUsed ),
+ XML_applyProtection, XclXmlUtils::ToPsz( mbProtUsed ),
+ FSEND );
+ if( mbAlignUsed )
+ maAlignment.SaveXml( rStrm );
+ if( mbProtUsed )
+ maProtection.SaveXml( rStrm );
+ // OOXTODO: XML_extLst
+ rStyleSheet->endElement( XML_xf );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDefaultXF::XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF ) :
+ XclExpXF( rRoot, bCellXF )
+{
+}
+
+void XclExpDefaultXF::SetFont( sal_uInt16 nXclFont )
+{
+ mnXclFont = nXclFont;
+ mbFontUsed = true;
+}
+
+void XclExpDefaultXF::SetNumFmt( sal_uInt16 nXclNumFmt )
+{
+ mnXclNumFmt = nXclNumFmt;
+ mbFmtUsed = true;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpStyle::XclExpStyle( sal_uInt32 nXFId, const String& rStyleName ) :
+ XclExpRecord( EXC_ID_STYLE, 4 ),
+ maName( rStyleName ),
+ maXFId( nXFId ),
+ mnStyleId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL )
+{
+ DBG_ASSERT( maName.Len(), "XclExpStyle::XclExpStyle - empty style name" );
+#ifdef DBG_UTIL
+ sal_uInt8 nStyleId, nLevel; // do not use members for debug tests
+ DBG_ASSERT( !XclTools::GetBuiltInStyleId( nStyleId, nLevel, maName ),
+ "XclExpStyle::XclExpStyle - this is a built-in style" );
+#endif
+}
+
+XclExpStyle::XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel ) :
+ XclExpRecord( EXC_ID_STYLE, 4 ),
+ maXFId( nXFId ),
+ mnStyleId( nStyleId ),
+ mnLevel( nLevel )
+{
+}
+
+void XclExpStyle::WriteBody( XclExpStream& rStrm )
+{
+ maXFId.ConvertXFIndex( rStrm.GetRoot() );
+ ::set_flag( maXFId.mnXFIndex, EXC_STYLE_BUILTIN, IsBuiltIn() );
+ rStrm << maXFId.mnXFIndex;
+
+ if( IsBuiltIn() )
+ {
+ rStrm << mnStyleId << mnLevel;
+ }
+ else
+ {
+ XclExpString aNameEx;
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ aNameEx.Assign( maName );
+ else
+ aNameEx.AssignByte( maName, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
+ rStrm << aNameEx;
+ }
+}
+
+static const char* lcl_StyleNameFromId( sal_Int32 nStyleId )
+{
+ switch( nStyleId )
+ {
+ case 0: return "Normal";
+ case 3: return "Comma";
+ case 4: return "Currency";
+ case 5: return "Percent";
+ case 6: return "Comma [0]";
+ case 7: return "Currency [0]";
+ }
+ return "*unknown*";
+}
+
+void XclExpStyle::SaveXml( XclExpXmlStream& rStrm )
+{
+ OString sName;
+ if( IsBuiltIn() )
+ {
+ sName = OString( lcl_StyleNameFromId( mnStyleId ) );
+ }
+ else
+ sName = XclXmlUtils::ToOString( maName );
+ sal_Int32 nXFId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( maXFId.mnXFId );
+ rStrm.GetCurrentStream()->singleElement( XML_cellStyle,
+ XML_name, sName.getStr(),
+ XML_xfId, OString::valueOf( nXFId ).getStr(),
+/* mso-excel 2007 complains when it finds builtinId >= 55, it is not
+ * bothered by multiple 54 values. */
+#define CELL_STYLE_MAX_BUILTIN_ID 55
+ XML_builtinId, OString::valueOf( std::min( static_cast<sal_Int32>( CELL_STYLE_MAX_BUILTIN_ID - 1 ), static_cast <sal_Int32>( mnStyleId ) ) ).getStr(),
+ // OOXTODO: XML_iLevel,
+ // OOXTODO: XML_hidden,
+ XML_customBuiltin, XclXmlUtils::ToPsz( ! IsBuiltIn() ),
+ FSEND );
+ // OOXTODO: XML_extLst
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+const sal_uInt32 EXC_XFLIST_INDEXBASE = 0xFFFE0000;
+/** Maximum count of XF records to store in the XF list (performance). */
+const sal_uInt32 EXC_XFLIST_HARDLIMIT = 256 * 1024;
+
+bool lclIsBuiltInStyle( const String& rStyleName )
+{
+ return
+ XclTools::IsBuiltInStyleName( rStyleName ) ||
+ XclTools::IsCondFormatStyleName( rStyleName );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpXFBuffer::XclExpBuiltInInfo::XclExpBuiltInInfo() :
+ mnStyleId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL ),
+ mbPredefined( true ),
+ mbHasStyleRec( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+/** Predicate for search algorithm. */
+struct XclExpBorderPred
+{
+ const XclExpCellBorder&
+ mrBorder;
+ inline explicit XclExpBorderPred( const XclExpCellBorder& rBorder ) : mrBorder( rBorder ) {}
+ bool operator()( const XclExpCellBorder& rBorder ) const;
+};
+
+bool XclExpBorderPred::operator()( const XclExpCellBorder& rBorder ) const
+{
+ return
+ mrBorder.mnLeftColor == rBorder.mnLeftColor &&
+ mrBorder.mnRightColor == rBorder.mnRightColor &&
+ mrBorder.mnTopColor == rBorder.mnTopColor &&
+ mrBorder.mnBottomColor == rBorder.mnBottomColor &&
+ mrBorder.mnDiagColor == rBorder.mnDiagColor &&
+ mrBorder.mnLeftLine == rBorder.mnLeftLine &&
+ mrBorder.mnRightLine == rBorder.mnRightLine &&
+ mrBorder.mnTopLine == rBorder.mnTopLine &&
+ mrBorder.mnBottomLine == rBorder.mnBottomLine &&
+ mrBorder.mnDiagLine == rBorder.mnDiagLine &&
+ mrBorder.mbDiagTLtoBR == rBorder.mbDiagTLtoBR &&
+ mrBorder.mbDiagBLtoTR == rBorder.mbDiagBLtoTR &&
+ mrBorder.mnLeftColorId == rBorder.mnLeftColorId &&
+ mrBorder.mnRightColorId == rBorder.mnRightColorId &&
+ mrBorder.mnTopColorId == rBorder.mnTopColorId &&
+ mrBorder.mnBottomColorId == rBorder.mnBottomColorId &&
+ mrBorder.mnDiagColorId == rBorder.mnDiagColorId;
+}
+
+struct XclExpFillPred
+{
+ const XclExpCellArea&
+ mrFill;
+ inline explicit XclExpFillPred( const XclExpCellArea& rFill ) : mrFill( rFill ) {}
+ bool operator()( const XclExpCellArea& rFill ) const;
+};
+
+bool XclExpFillPred::operator()( const XclExpCellArea& rFill ) const
+{
+ return
+ mrFill.mnForeColor == rFill.mnForeColor &&
+ mrFill.mnBackColor == rFill.mnBackColor &&
+ mrFill.mnPattern == rFill.mnPattern &&
+ mrFill.mnForeColorId == rFill.mnForeColorId &&
+ mrFill.mnBackColorId == rFill.mnBackColorId;
+}
+
+XclExpXFBuffer::XclExpXFBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+void XclExpXFBuffer::Initialize()
+{
+ InsertDefaultRecords();
+ InsertUserStyles();
+}
+
+sal_uInt32 XclExpXFBuffer::Insert( const ScPatternAttr* pPattern, sal_Int16 nScript )
+{
+ return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertWithFont( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak )
+{
+ return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, nForceXclFont, bForceLineBreak );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertWithNumFmt( const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uLong nForceScNumFmt, bool bForceLineBreak )
+{
+ return InsertCellXF( pPattern, nScript, nForceScNumFmt, EXC_FONT_NOTFOUND, bForceLineBreak );
+}
+
+sal_uInt32 XclExpXFBuffer::InsertStyle( const SfxStyleSheetBase* pStyleSheet )
+{
+ return pStyleSheet ? InsertStyleXF( *pStyleSheet ) : GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
+}
+
+sal_uInt32 XclExpXFBuffer::GetXFIdFromIndex( sal_uInt16 nXFIndex )
+{
+ return EXC_XFLIST_INDEXBASE | nXFIndex;
+}
+
+sal_uInt32 XclExpXFBuffer::GetDefCellXFId()
+{
+ return GetXFIdFromIndex( EXC_XF_DEFAULTCELL );
+}
+
+const XclExpXF* XclExpXFBuffer::GetXFById( sal_uInt32 nXFId ) const
+{
+ return maXFList.GetRecord( nXFId ).get();
+}
+
+void XclExpXFBuffer::Finalize()
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ maXFList.GetRecord( nPos )->SetFinalColors();
+
+ sal_uInt32 nTotalCount = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ sal_uInt32 nId;
+ maXFIndexVec.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+ maStyleIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+ maCellIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
+
+ XclExpBuiltInMap::const_iterator aBuiltInEnd = maBuiltInMap.end();
+ /* nMaxBuiltInXFId used to decide faster whether an XF record is
+ user-defined. If the current XF ID is greater than this value,
+ maBuiltInMap doesn't need to be searched. */
+ sal_uInt32 nMaxBuiltInXFId = maBuiltInMap.empty() ? 0 : maBuiltInMap.rbegin()->first;
+
+ // *** map all built-in XF records (cell and style) *** -------------------
+
+ // do not change XF order -> std::map<> iterates elements in ascending order
+ for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(); aIt != aBuiltInEnd; ++aIt )
+ AppendXFIndex( aIt->first );
+
+ // *** insert all user-defined style XF records, without reduce *** -------
+
+ sal_uInt32 nStyleXFCount = 0; // counts up to EXC_XF_MAXSTYLECOUNT limit
+
+ for( nId = 0; nId < nTotalCount; ++nId )
+ {
+ XclExpXFRef xXF = maXFList.GetRecord( nId );
+ if( xXF->IsStyleXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
+ {
+ if( nStyleXFCount < EXC_XF_MAXSTYLECOUNT )
+ {
+ // maximum count of styles not reached
+ AppendXFIndex( nId );
+ ++nStyleXFCount;
+ }
+ else
+ {
+ /* Maximum count of styles reached - do not append more
+ pointers to XFs; use default style XF instead; do not break
+ the loop to initialize all maXFIndexVec elements. */
+ maXFIndexVec[ nId ] = EXC_XF_DEFAULTSTYLE;
+ }
+ }
+ }
+
+ // *** insert all cell XF records *** -------------------------------------
+
+ // start position to search for equal inserted XF records
+ size_t nSearchStart = maSortedXFList.GetSize();
+
+ // break the loop if XF limit reached - maXFIndexVec is already initialized with default index
+ XclExpXFRef xDefCellXF = maXFList.GetRecord( EXC_XF_DEFAULTCELL );
+ for( nId = 0; (nId < nTotalCount) && (maSortedXFList.GetSize() < EXC_XF_MAXCOUNT); ++nId )
+ {
+ XclExpXFRef xXF = maXFList.GetRecord( nId );
+ if( xXF->IsCellXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
+ {
+ // try to find an XF record equal to *xXF, which is already inserted
+ sal_uInt16 nFoundIndex = EXC_XF_NOTFOUND;
+
+ // first try if it is equal to the default cell XF
+ if( xDefCellXF->Equals( *xXF ) )
+ {
+ nFoundIndex = EXC_XF_DEFAULTCELL;
+ }
+ else for( size_t nSearchPos = nSearchStart, nSearchEnd = maSortedXFList.GetSize();
+ (nSearchPos < nSearchEnd) && (nFoundIndex == EXC_XF_NOTFOUND); ++nSearchPos )
+ {
+ if( maSortedXFList.GetRecord( nSearchPos )->Equals( *xXF ) )
+ nFoundIndex = static_cast< sal_uInt16 >( nSearchPos );
+ }
+
+ if( nFoundIndex != EXC_XF_NOTFOUND )
+ // equal XF already in the list, use its resulting XF index
+ maXFIndexVec[ nId ] = nFoundIndex;
+ else
+ AppendXFIndex( nId );
+ }
+ }
+
+ sal_uInt16 nXmlStyleIndex = 0;
+ sal_uInt16 nXmlCellIndex = 0;
+
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( xXF->IsStyleXF() )
+ maStyleIndexes[ i ] = nXmlStyleIndex++;
+ else
+ maCellIndexes[ i ] = nXmlCellIndex++;
+ }
+}
+
+sal_uInt16 XclExpXFBuffer::GetXFIndex( sal_uInt32 nXFId ) const
+{
+ sal_uInt16 nXFIndex = EXC_XF_DEFAULTSTYLE;
+ if( nXFId >= EXC_XFLIST_INDEXBASE )
+ nXFIndex = static_cast< sal_uInt16 >( nXFId & ~EXC_XFLIST_INDEXBASE );
+ else if( nXFId < maXFIndexVec.size() )
+ nXFIndex = maXFIndexVec[ nXFId ];
+ return nXFIndex;
+}
+
+sal_Int32 XclExpXFBuffer::GetXmlStyleIndex( sal_uInt32 nXFIndex ) const
+{
+ DBG_ASSERT( nXFIndex < maStyleIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
+ if( nXFIndex > maStyleIndexes.size() )
+ return 0; // should be caught/debugged via above assert; return "valid" index.
+ return maStyleIndexes[ nXFIndex ];
+}
+
+sal_Int32 XclExpXFBuffer::GetXmlCellIndex( sal_uInt32 nXFIndex ) const
+{
+ DBG_ASSERT( nXFIndex < maCellIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
+ if( nXFIndex > maCellIndexes.size() )
+ return 0; // should be caught/debugged via above assert; return "valid" index.
+ return maCellIndexes[ nXFIndex ];
+}
+
+void XclExpXFBuffer::Save( XclExpStream& rStrm )
+{
+ // save all XF records contained in the maSortedXFList vector (sorted by XF index)
+ maSortedXFList.Save( rStrm );
+ // save all STYLE records
+ maStyleList.Save( rStrm );
+}
+
+static void lcl_GetCellCounts( const XclExpRecordList< XclExpXF >& rXFList, sal_Int32& rCells, sal_Int32& rStyles )
+{
+ rCells = 0;
+ rStyles = 0;
+ size_t nXFCount = rXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpRecordList< XclExpXF >::RecordRefType xXF = rXFList.GetRecord( i );
+ if( xXF->IsCellXF() )
+ ++rCells;
+ else if( xXF->IsStyleXF() )
+ ++rStyles;
+ }
+}
+
+void XclExpXFBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
+
+ rStyleSheet->startElement( XML_fills,
+ XML_count, OString::valueOf( (sal_Int32) maFills.size() ).getStr(),
+ FSEND );
+ for( XclExpFillList::iterator aIt = maFills.begin(), aEnd = maFills.end();
+ aIt != aEnd; ++aIt )
+ {
+ aIt->SaveXml( rStrm );
+ }
+ rStyleSheet->endElement( XML_fills );
+
+ rStyleSheet->startElement( XML_borders,
+ XML_count, OString::valueOf( (sal_Int32) maBorders.size() ).getStr(),
+ FSEND );
+ for( XclExpBorderList::iterator aIt = maBorders.begin(), aEnd = maBorders.end();
+ aIt != aEnd; ++aIt )
+ {
+ aIt->SaveXml( rStrm );
+ }
+ rStyleSheet->endElement( XML_borders );
+
+ // save all XF records contained in the maSortedXFList vector (sorted by XF index)
+ sal_Int32 nCells, nStyles;
+ lcl_GetCellCounts( maSortedXFList, nCells, nStyles );
+
+ if( nStyles > 0 )
+ {
+ rStyleSheet->startElement( XML_cellStyleXfs,
+ XML_count, OString::valueOf( nStyles ).getStr(),
+ FSEND );
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( ! xXF->IsStyleXF() )
+ continue;
+ SaveXFXml( rStrm, *xXF );
+ }
+ rStyleSheet->endElement( XML_cellStyleXfs );
+ }
+
+ if( nCells > 0 )
+ {
+ rStyleSheet->startElement( XML_cellXfs,
+ XML_count, OString::valueOf( nCells ).getStr(),
+ FSEND );
+ size_t nXFCount = maSortedXFList.GetSize();
+ for( size_t i = 0; i < nXFCount; ++i )
+ {
+ XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
+ if( ! xXF->IsCellXF() )
+ continue;
+ SaveXFXml( rStrm, *xXF );
+ }
+ rStyleSheet->endElement( XML_cellXfs );
+ }
+
+ // save all STYLE records
+ rStyleSheet->startElement( XML_cellStyles,
+ XML_count, OString::valueOf( (sal_Int32) maStyleList.GetSize() ).getStr(),
+ FSEND );
+ maStyleList.SaveXml( rStrm );
+ rStyleSheet->endElement( XML_cellStyles );
+}
+
+void XclExpXFBuffer::SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF )
+{
+ XclExpBorderList::iterator aBorderPos =
+ std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) );
+ DBG_ASSERT( aBorderPos != maBorders.end(), "XclExpXFBuffer::SaveXml - Invalid @borderId!" );
+ XclExpFillList::iterator aFillPos =
+ std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) );
+ DBG_ASSERT( aFillPos != maFills.end(), "XclExpXFBuffer::SaveXml - Invalid @fillId!" );
+
+ sal_Int32 nBorderId = 0, nFillId = 0;
+ if( aBorderPos != maBorders.end() )
+ nBorderId = std::distance( maBorders.begin(), aBorderPos );
+ if( aFillPos != maFills.end() )
+ nFillId = std::distance( maFills.begin(), aFillPos );
+
+ rXF.SetXmlIds( nBorderId, nFillId );
+ rXF.SaveXml( rStrm );
+}
+
+sal_uInt32 XclExpXFBuffer::FindXF( const ScPatternAttr& rPattern,
+ sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ if( maXFList.GetRecord( nPos )->Equals( rPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak ) )
+ return static_cast< sal_uInt32 >( nPos );
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::FindXF( const SfxStyleSheetBase& rStyleSheet ) const
+{
+ for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
+ if( maXFList.GetRecord( nPos )->Equals( rStyleSheet ) )
+ return static_cast< sal_uInt32 >( nPos );
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel ) const
+{
+ for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(), aEnd = maBuiltInMap.end(); aIt != aEnd; ++aIt )
+ if( (aIt->second.mnStyleId == nStyleId) && (aIt->second.mnLevel == nLevel) )
+ return aIt->first;
+ return EXC_XFID_NOTFOUND;
+}
+
+sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak )
+{
+ const ScPatternAttr* pDefPattern = GetDoc().GetDefPattern();
+ if( !pPattern )
+ pPattern = pDefPattern;
+
+ // special handling for default cell formatting
+ if( (pPattern == pDefPattern) && !bForceLineBreak &&
+ (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) &&
+ (nForceXclFont == EXC_FONT_NOTFOUND) )
+ {
+ // Is it the first try to insert the default cell format?
+ bool& rbPredefined = maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined;
+ if( rbPredefined )
+ {
+ // replace default cell pattern
+ XclExpXFRef xNewXF( new XclExpXF( GetRoot(), *pPattern, nScript ) );
+ maXFList.ReplaceRecord( xNewXF, EXC_XF_DEFAULTCELL );
+ rbPredefined = false;
+ }
+ return GetDefCellXFId();
+ }
+
+ sal_uInt32 nXFId = FindXF( *pPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // not found - insert new cell XF
+ if( maXFList.GetSize() < EXC_XFLIST_HARDLIMIT )
+ {
+ maXFList.AppendNewRecord( new XclExpXF(
+ GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ) );
+ // do not set nXFId before the AppendNewRecord() call - it may insert 2 XFs (style+cell)
+ nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() - 1 );
+ }
+ else
+ {
+ // list full - fall back to default cell XF
+ nXFId = GetDefCellXFId();
+ }
+ }
+ return nXFId;
+}
+
+sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet )
+{
+ // *** try, if it is a built-in style - create new XF or replace existing predefined XF ***
+
+ sal_uInt8 nStyleId, nLevel;
+ if( XclTools::GetBuiltInStyleId( nStyleId, nLevel, rStyleSheet.GetName() ) )
+ {
+ // try to find the built-in XF record (if already created in InsertDefaultRecords())
+ sal_uInt32 nXFId = FindBuiltInXF( nStyleId, nLevel );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // built-in style XF not yet created - do it now
+ XclExpXFRef xXF( new XclExpXF( GetRoot(), rStyleSheet ) );
+ nXFId = AppendBuiltInXFWithStyle( xXF, nStyleId, nLevel );
+ // this new XF record is not predefined
+ maBuiltInMap[ nXFId ].mbPredefined = false;
+ }
+ else
+ {
+ DBG_ASSERT( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::InsertStyleXF - built-in XF not found" );
+ // XF record still predefined? -> Replace with real XF
+ bool& rbPredefined = maBuiltInMap[ nXFId ].mbPredefined;
+ if( rbPredefined )
+ {
+ // replace predefined built-in style (ReplaceRecord() deletes old record)
+ maXFList.ReplaceRecord( XclExpXFRef( new XclExpXF( GetRoot(), rStyleSheet ) ), nXFId );
+ rbPredefined = false;
+ }
+ }
+
+ // STYLE already inserted? (may be not, i.e. for RowLevel/ColLevel or Hyperlink styles)
+ bool& rbHasStyleRec = maBuiltInMap[ nXFId ].mbHasStyleRec;
+ if( !rbHasStyleRec )
+ {
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
+ rbHasStyleRec = true;
+ }
+
+ return nXFId;
+ }
+
+ // *** try to find the XF record of a user-defined style ***
+
+ sal_uInt32 nXFId = FindXF( rStyleSheet );
+ if( nXFId == EXC_XFID_NOTFOUND )
+ {
+ // not found - insert new style XF and STYLE
+ nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ if( nXFId < EXC_XFLIST_HARDLIMIT )
+ {
+ maXFList.AppendNewRecord( new XclExpXF( GetRoot(), rStyleSheet ) );
+ // create the STYLE record
+ if( rStyleSheet.GetName().Len() )
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, rStyleSheet.GetName() ) );
+ }
+ else
+ // list full - fall back to default style XF
+ nXFId = GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
+ }
+ return nXFId;
+}
+
+void XclExpXFBuffer::InsertUserStyles()
+{
+ SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
+ if( pStyleSheet->IsUserDefined() && !lclIsBuiltInStyle( pStyleSheet->GetName() ) )
+ InsertStyleXF( *pStyleSheet );
+}
+
+sal_uInt32 XclExpXFBuffer::AppendBuiltInXF( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
+{
+ sal_uInt32 nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
+ maXFList.AppendRecord( xXF );
+ XclExpBuiltInInfo& rInfo = maBuiltInMap[ nXFId ];
+ rInfo.mnStyleId = nStyleId;
+ rInfo.mnLevel = nLevel;
+ rInfo.mbPredefined = true;
+ return nXFId;
+}
+
+sal_uInt32 XclExpXFBuffer::AppendBuiltInXFWithStyle( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
+{
+ sal_uInt32 nXFId = AppendBuiltInXF( xXF, nStyleId, nLevel );
+ maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
+ maBuiltInMap[ nXFId ].mbHasStyleRec = true; // mark existing STYLE record
+ return nXFId;
+}
+
+static XclExpCellArea lcl_GetPatternFill_None()
+{
+ XclExpCellArea aFill;
+ aFill.mnPattern = EXC_PATT_NONE;
+ return aFill;
+}
+
+static XclExpCellArea lcl_GetPatternFill_Gray125()
+{
+ XclExpCellArea aFill;
+ aFill.mnPattern = EXC_PATT_12_5_PERC;
+ aFill.mnForeColor = 0;
+ aFill.mnBackColor = 0;
+ return aFill;
+}
+
+void XclExpXFBuffer::InsertDefaultRecords()
+{
+ maFills.push_back( lcl_GetPatternFill_None() );
+ maFills.push_back( lcl_GetPatternFill_Gray125() );
+
+ // index 0: default style
+ if( SfxStyleSheetBase* pDefStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) )
+ {
+ XclExpXFRef xDefStyle( new XclExpXF( GetRoot(), *pDefStyleSheet ) );
+ sal_uInt32 nXFId = AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
+ // mark this XF as not predefined, prevents overwriting
+ maBuiltInMap[ nXFId ].mbPredefined = false;
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclExpXFBuffer::InsertDefaultRecords - default style not found" );
+ XclExpXFRef xDefStyle( new XclExpDefaultXF( GetRoot(), false ) );
+ xDefStyle->SetAllUsedFlags( true );
+ AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
+ }
+
+ // index 1-14: RowLevel and ColLevel styles (without STYLE records)
+ XclExpDefaultXF aLevelStyle( GetRoot(), false );
+ // RowLevel_1, ColLevel_1
+ aLevelStyle.SetFont( 1 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 0 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 0 );
+ // RowLevel_2, ColLevel_2
+ aLevelStyle.SetFont( 2 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 1 );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 1 );
+ // RowLevel_3, ColLevel_3 ... RowLevel_7, ColLevel_7
+ aLevelStyle.SetFont( 0 );
+ for( sal_uInt8 nLevel = 2; nLevel < EXC_STYLE_LEVELCOUNT; ++nLevel )
+ {
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, nLevel );
+ AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, nLevel );
+ }
+
+ // index 15: default hard cell format, placeholder to be able to add more built-in styles
+ maXFList.AppendNewRecord( new XclExpDefaultXF( GetRoot(), true ) );
+ maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined = true;
+
+ // index 16-20: other built-in styles
+ XclExpDefaultXF aFormatStyle( GetRoot(), false );
+ aFormatStyle.SetFont( 1 );
+ aFormatStyle.SetNumFmt( 43 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA );
+ aFormatStyle.SetNumFmt( 41 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA_0 );
+ aFormatStyle.SetNumFmt( 44 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY );
+ aFormatStyle.SetNumFmt( 42 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY_0 );
+ aFormatStyle.SetNumFmt( 9 );
+ AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_PERCENT );
+
+ // other built-in style XF records (i.e. Hyperlink styles) are created on demand
+
+ /* Insert the real default hard cell format -> 0 is document default pattern.
+ Do it here (and not already above) to really have all built-in styles. */
+ Insert( 0, GetDefApiScript() );
+}
+
+void XclExpXFBuffer::AppendXFIndex( sal_uInt32 nXFId )
+{
+ DBG_ASSERT( nXFId < maXFIndexVec.size(), "XclExpXFBuffer::AppendXFIndex - XF ID out of range" );
+ maXFIndexVec[ nXFId ] = static_cast< sal_uInt16 >( maSortedXFList.GetSize() );
+ XclExpXFRef xXF = maXFList.GetRecord( nXFId );
+ AddBorderAndFill( *xXF );
+ maSortedXFList.AppendRecord( xXF );
+ DBG_ASSERT( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::AppendXFIndex - XF not found" );
+}
+
+void XclExpXFBuffer::AddBorderAndFill( const XclExpXF& rXF )
+{
+ if( std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) ) == maBorders.end() )
+ {
+ maBorders.push_back( rXF.GetBorderData() );
+ }
+
+ if( std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) ) == maFills.end() )
+ {
+ maFills.push_back( rXF.GetAreaData() );
+ }
+}
+
+// ============================================================================
+
+XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot )
+ : XclExpRoot( rRoot )
+{
+}
+
+void XclExpXmlStyleSheet::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr aStyleSheet = rStrm.CreateOutputStream(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/styles.xml") ),
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "styles.xml" )),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" );
+ rStrm.PushStream( aStyleSheet );
+
+ aStyleSheet->startElement( XML_styleSheet,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSEND );
+
+ CreateRecord( EXC_ID_FORMATLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_FONTLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_XFLIST )->SaveXml( rStrm );
+ CreateRecord( EXC_ID_PALETTE )->SaveXml( rStrm );
+
+ aStyleSheet->endElement( XML_styleSheet );
+
+ rStrm.PopStream();
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
new file mode 100644
index 000000000000..09f9752caea2
--- /dev/null
+++ b/sc/source/filter/excel/xetable.cxx
@@ -0,0 +1,2443 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xetable.hxx"
+
+#include <map>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include "scitems.hxx"
+#include <svl/intitem.hxx>
+#include "document.hxx"
+#include "dociter.hxx"
+#include "olinetab.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "xehelper.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+
+using namespace ::oox;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+// ============================================================================
+// Helper records for cell records
+// ============================================================================
+
+XclExpStringRec::XclExpStringRec( const XclExpRoot& rRoot, const String& rResult ) :
+ XclExpRecord( EXC_ID3_STRING ),
+ mxResult( XclExpStringHelper::CreateString( rRoot, rResult ) )
+{
+ DBG_ASSERT( (rRoot.GetBiff() <= EXC_BIFF5) || (mxResult->Len() > 0),
+ "XclExpStringRec::XclExpStringRec - empty result not allowed in BIFF8+" );
+ SetRecSize( mxResult->GetSize() );
+}
+
+void XclExpStringRec::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << *mxResult;
+}
+
+// Additional records for special formula ranges ==============================
+
+XclExpRangeFmlaBase::XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScAddress& rScPos ) :
+ XclExpRecord( nRecId, nRecSize ),
+ maXclRange( ScAddress::UNINITIALIZED ),
+ maBaseXclPos( ScAddress::UNINITIALIZED )
+{
+ maBaseXclPos.Set( static_cast< sal_uInt16 >( rScPos.Col() ), static_cast< sal_uInt16 >( rScPos.Row() ) );
+ maXclRange.maFirst = maXclRange.maLast = maBaseXclPos;
+}
+
+XclExpRangeFmlaBase::XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScRange& rScRange ) :
+ XclExpRecord( nRecId, nRecSize ),
+ maXclRange( ScAddress::UNINITIALIZED ),
+ maBaseXclPos( ScAddress::UNINITIALIZED )
+{
+ maXclRange.Set(
+ static_cast< sal_uInt16 >( rScRange.aStart.Col() ),
+ static_cast< sal_uInt16 >( rScRange.aStart.Row() ),
+ static_cast< sal_uInt16 >( rScRange.aEnd.Col() ),
+ static_cast< sal_uInt16 >( rScRange.aEnd.Row() ) );
+ maBaseXclPos = maXclRange.maFirst;
+}
+
+bool XclExpRangeFmlaBase::IsBasePos( sal_uInt16 nXclCol, sal_uInt32 nXclRow ) const
+{
+ return (maBaseXclPos.mnCol == nXclCol) && (maBaseXclPos.mnRow == nXclRow);
+}
+
+void XclExpRangeFmlaBase::Extend( const ScAddress& rScPos )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
+ sal_uInt32 nXclRow = static_cast< sal_uInt32 >( rScPos.Row() );
+ maXclRange.maFirst.mnCol = ::std::min( maXclRange.maFirst.mnCol, nXclCol );
+ maXclRange.maFirst.mnRow = ::std::min( maXclRange.maFirst.mnRow, nXclRow );
+ maXclRange.maLast.mnCol = ::std::max( maXclRange.maLast.mnCol, nXclCol );
+ maXclRange.maLast.mnRow = ::std::max( maXclRange.maLast.mnRow, nXclRow );
+}
+
+void XclExpRangeFmlaBase::WriteRangeAddress( XclExpStream& rStrm ) const
+{
+ maXclRange.Write( rStrm, false );
+}
+
+// Array formulas =============================================================
+
+XclExpArray::XclExpArray( XclTokenArrayRef xTokArr, const ScRange& rScRange ) :
+ XclExpRangeFmlaBase( EXC_ID3_ARRAY, 14 + xTokArr->GetSize(), rScRange ),
+ mxTokArr( xTokArr )
+{
+}
+
+XclTokenArrayRef XclExpArray::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
+}
+
+bool XclExpArray::IsVolatile() const
+{
+ return mxTokArr->IsVolatile();
+}
+
+void XclExpArray::WriteBody( XclExpStream& rStrm )
+{
+ WriteRangeAddress( rStrm );
+ sal_uInt16 nFlags = EXC_ARRAY_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_ARRAY_RECALC_ALWAYS, IsVolatile() );
+ rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpArrayBuffer::XclExpArrayBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpArrayRef XclExpArrayBuffer::CreateArray( const ScTokenArray& rScTokArr, const ScRange& rScRange )
+{
+ const ScAddress& rScPos = rScRange.aStart;
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_MATRIX, rScTokArr, &rScPos );
+
+ DBG_ASSERT( maRecMap.find( rScPos ) == maRecMap.end(), "XclExpArrayBuffer::CreateArray - array exists already" );
+ XclExpArrayRef& rxRec = maRecMap[ rScPos ];
+ rxRec.reset( new XclExpArray( xTokArr, rScRange ) );
+ return rxRec;
+}
+
+XclExpArrayRef XclExpArrayBuffer::FindArray( const ScTokenArray& rScTokArr ) const
+{
+ XclExpArrayRef xRec;
+ // try to extract a matrix reference token
+ if( rScTokArr.GetLen() == 1 )
+ {
+ const formula::FormulaToken* pToken = rScTokArr.GetArray()[ 0 ];
+ if( pToken && (pToken->GetOpCode() == ocMatRef) )
+ {
+ const ScSingleRefData& rRef = static_cast<const ScToken*>(pToken)->GetSingleRef();
+ ScAddress aBasePos( rRef.nCol, rRef.nRow, GetCurrScTab() );
+ XclExpArrayMap::const_iterator aIt = maRecMap.find( aBasePos );
+ if( aIt != maRecMap.end() )
+ xRec = aIt->second;
+ }
+ }
+ return xRec;
+}
+
+// Shared formulas ============================================================
+
+XclExpShrfmla::XclExpShrfmla( XclTokenArrayRef xTokArr, const ScAddress& rScPos ) :
+ XclExpRangeFmlaBase( EXC_ID_SHRFMLA, 10 + xTokArr->GetSize(), rScPos ),
+ mxTokArr( xTokArr ),
+ mnUsedCount( 1 )
+{
+}
+
+void XclExpShrfmla::ExtendRange( const ScAddress& rScPos )
+{
+ Extend( rScPos );
+ ++mnUsedCount;
+}
+
+XclTokenArrayRef XclExpShrfmla::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
+}
+
+bool XclExpShrfmla::IsVolatile() const
+{
+ return mxTokArr->IsVolatile();
+}
+
+void XclExpShrfmla::WriteBody( XclExpStream& rStrm )
+{
+ WriteRangeAddress( rStrm );
+ rStrm << sal_uInt8( 0 ) << mnUsedCount << *mxTokArr;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpShrfmlaBuffer::XclExpShrfmlaBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpShrfmlaRef XclExpShrfmlaBuffer::CreateOrExtendShrfmla(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos )
+{
+ XclExpShrfmlaRef xRec;
+ if( const ScTokenArray* pShrdScTokArr = XclTokenArrayHelper::GetSharedFormula( GetRoot(), rScTokArr ) )
+ {
+ XclExpShrfmlaMap::iterator aIt = maRecMap.find( pShrdScTokArr );
+ if( aIt == maRecMap.end() )
+ {
+ // create a new record
+ XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_SHARED, *pShrdScTokArr, &rScPos );
+ xRec.reset( new XclExpShrfmla( xTokArr, rScPos ) );
+ maRecMap[ pShrdScTokArr ] = xRec;
+ }
+ else
+ {
+ // extend existing record
+ DBG_ASSERT( aIt->second, "XclExpShrfmlaBuffer::CreateOrExtendShrfmla - missing record" );
+ xRec = aIt->second;
+ xRec->ExtendRange( rScPos );
+ }
+ }
+ return xRec;
+}
+
+// Multiple operations ========================================================
+
+XclExpTableop::XclExpTableop( const ScAddress& rScPos,
+ const XclMultipleOpRefs& rRefs, sal_uInt8 nScMode ) :
+ XclExpRangeFmlaBase( EXC_ID3_TABLEOP, 16, rScPos ),
+ mnLastAppXclCol( static_cast< sal_uInt16 >( rScPos.Col() ) ),
+ mnColInpXclCol( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Col() ) ),
+ mnColInpXclRow( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Row() ) ),
+ mnRowInpXclCol( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Col() ) ),
+ mnRowInpXclRow( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Row() ) ),
+ mnScMode( nScMode ),
+ mbValid( false )
+{
+}
+
+bool XclExpTableop::TryExtend( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
+{
+ sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
+ sal_uInt16 nXclRow = static_cast< sal_uInt16 >( rScPos.Row() );
+
+ bool bOk = IsAppendable( nXclCol, nXclRow );
+ if( bOk )
+ {
+ SCCOL nFirstScCol = static_cast< SCCOL >( maXclRange.maFirst.mnCol );
+ SCROW nFirstScRow = static_cast< SCROW >( maXclRange.maFirst.mnRow );
+ SCCOL nColInpScCol = static_cast< SCCOL >( mnColInpXclCol );
+ SCROW nColInpScRow = static_cast< SCROW >( mnColInpXclRow );
+ SCCOL nRowInpScCol = static_cast< SCCOL >( mnRowInpXclCol );
+ SCROW nRowInpScRow = static_cast< SCROW >( mnRowInpXclRow );
+
+ bOk = ((mnScMode == 2) == rRefs.mbDblRefMode) &&
+ (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
+ (nColInpScCol == rRefs.maColFirstScPos.Col()) &&
+ (nColInpScRow == rRefs.maColFirstScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColRelScPos.Tab());
+
+ if( bOk ) switch( mnScMode )
+ {
+ case 0:
+ bOk = (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
+ (nFirstScRow == rRefs.maFmlaScPos.Row() + 1) &&
+ (nFirstScCol == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row());
+ break;
+ case 1:
+ bOk = (nFirstScCol == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
+ (nFirstScRow == rRefs.maColRelScPos.Row() + 1);
+ break;
+ case 2:
+ bOk = (nFirstScCol == rRefs.maFmlaScPos.Col() + 1) &&
+ (nFirstScRow == rRefs.maFmlaScPos.Row() + 1) &&
+ (nFirstScCol == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
+ (nRowInpScCol == rRefs.maRowFirstScPos.Col()) &&
+ (nRowInpScRow == rRefs.maRowFirstScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
+ (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
+ (nFirstScRow == rRefs.maRowRelScPos.Row() + 1) &&
+ (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
+ break;
+ default:
+ bOk = false;
+ }
+
+ if( bOk )
+ {
+ // extend the cell range
+ DBG_ASSERT( IsAppendable( nXclCol, nXclRow ), "XclExpTableop::TryExtend - wrong cell address" );
+ Extend( rScPos );
+ mnLastAppXclCol = nXclCol;
+ }
+ }
+
+ return bOk;
+}
+
+void XclExpTableop::Finalize()
+{
+ // is the range complete? (last appended cell is in last column)
+ mbValid = maXclRange.maLast.mnCol == mnLastAppXclCol;
+ // if last row is incomplete, try to shorten the used range
+ if( !mbValid && (maXclRange.maFirst.mnRow < maXclRange.maLast.mnRow) )
+ {
+ --maXclRange.maLast.mnRow;
+ mbValid = true;
+ }
+
+ // check if referred cells are outside of own range
+ if( mbValid ) switch( mnScMode )
+ {
+ case 0:
+ mbValid = (mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
+ break;
+ case 1:
+ mbValid = (mnColInpXclCol < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
+ break;
+ case 2:
+ mbValid = ((mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow)) &&
+ ((mnRowInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnRowInpXclCol > maXclRange.maLast.mnCol) ||
+ (mnRowInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnRowInpXclRow > maXclRange.maLast.mnRow));
+ break;
+ }
+}
+
+XclTokenArrayRef XclExpTableop::CreateCellTokenArray( const XclExpRoot& rRoot ) const
+{
+ XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
+ return mbValid ?
+ rFmlaComp.CreateSpecialRefFormula( EXC_TOKID_TBL, maBaseXclPos ) :
+ rFmlaComp.CreateErrorFormula( EXC_ERR_NA );
+}
+
+bool XclExpTableop::IsVolatile() const
+{
+ return true;
+}
+
+void XclExpTableop::Save( XclExpStream& rStrm )
+{
+ if( mbValid )
+ XclExpRangeFmlaBase::Save( rStrm );
+}
+
+bool XclExpTableop::IsAppendable( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const
+{
+ return ((nXclCol == mnLastAppXclCol + 1) && (nXclRow == maXclRange.maFirst.mnRow)) ||
+ ((nXclCol == mnLastAppXclCol + 1) && (nXclCol <= maXclRange.maLast.mnCol) && (nXclRow == maXclRange.maLast.mnRow)) ||
+ ((mnLastAppXclCol == maXclRange.maLast.mnCol) && (nXclCol == maXclRange.maFirst.mnCol) && (nXclRow == maXclRange.maLast.mnRow + 1));
+}
+
+void XclExpTableop::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nFlags = EXC_TABLEOP_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_TABLEOP_RECALC_ALWAYS, IsVolatile() );
+ switch( mnScMode )
+ {
+ case 1: ::set_flag( nFlags, EXC_TABLEOP_ROW ); break;
+ case 2: ::set_flag( nFlags, EXC_TABLEOP_BOTH ); break;
+ }
+
+ WriteRangeAddress( rStrm );
+ rStrm << nFlags;
+ if( mnScMode == 2 )
+ rStrm << mnRowInpXclRow << mnRowInpXclCol << mnColInpXclRow << mnColInpXclCol;
+ else
+ rStrm << mnColInpXclRow << mnColInpXclCol << sal_uInt32( 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpTableopBuffer::XclExpTableopBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+XclExpTableopRef XclExpTableopBuffer::CreateOrExtendTableop(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos )
+{
+ XclExpTableopRef xRec;
+
+ // try to extract cell references of a multiple operations formula
+ XclMultipleOpRefs aRefs;
+ if( XclTokenArrayHelper::GetMultipleOpRefs( aRefs, rScTokArr ) )
+ {
+ // try to find an existing TABLEOP record for this cell position
+ for( size_t nPos = 0, nSize = maTableopList.GetSize(); !xRec && (nPos < nSize); ++nPos )
+ {
+ XclExpTableopRef xTempRec = maTableopList.GetRecord( nPos );
+ if( xTempRec->TryExtend( rScPos, aRefs ) )
+ xRec = xTempRec;
+ }
+
+ // no record found, or found record not extensible
+ if( !xRec )
+ xRec = TryCreate( rScPos, aRefs );
+ }
+
+ return xRec;
+}
+
+void XclExpTableopBuffer::Finalize()
+{
+ for( size_t nPos = 0, nSize = maTableopList.GetSize(); nPos < nSize; ++nPos )
+ maTableopList.GetRecord( nPos )->Finalize();
+}
+
+XclExpTableopRef XclExpTableopBuffer::TryCreate( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
+{
+ sal_uInt8 nScMode = 0;
+ bool bOk = (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
+ (rScPos.Tab() == rRefs.maColRelScPos.Tab());
+
+ if( bOk )
+ {
+ if( rRefs.mbDblRefMode )
+ {
+ nScMode = 2;
+ bOk = (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
+ (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
+ (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
+ (rScPos.Row() == rRefs.maRowRelScPos.Row() + 1) &&
+ (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
+ }
+ else if( (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row()) )
+ {
+ nScMode = 0;
+ }
+ else if( (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
+ (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
+ (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
+ (rScPos.Row() == rRefs.maColRelScPos.Row() + 1) )
+ {
+ nScMode = 1;
+ }
+ else
+ {
+ bOk = false;
+ }
+ }
+
+ XclExpTableopRef xRec;
+ if( bOk )
+ {
+ xRec.reset( new XclExpTableop( rScPos, rRefs, nScMode ) );
+ maTableopList.AppendRecord( xRec );
+ }
+
+ return xRec;
+}
+
+// ============================================================================
+// Cell records
+// ============================================================================
+
+XclExpCellBase::XclExpCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
+ XclExpRecord( nRecId, nContSize + 4 ),
+ maXclPos( rXclPos )
+{
+}
+
+bool XclExpCellBase::IsMultiLineText() const
+{
+ return false;
+}
+
+bool XclExpCellBase::TryMerge( const XclExpCellBase& /*rCell*/ )
+{
+ return false;
+}
+
+void XclExpCellBase::GetBlankXFIndexes( ScfUInt16Vec& /*rXFIndexes*/ ) const
+{
+ // default: do nothing
+}
+
+void XclExpCellBase::RemoveUnusedBlankCells( const ScfUInt16Vec& /*rXFIndexes*/ )
+{
+ // default: do nothing
+}
+
+// Single cell records ========================================================
+
+XclExpSingleCellBase::XclExpSingleCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos, sal_uInt32 nXFId ) :
+ XclExpCellBase( nRecId, 2, rXclPos ),
+ maXFId( nXFId ),
+ mnContSize( nContSize )
+{
+}
+
+XclExpSingleCellBase::XclExpSingleCellBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uInt32 nForcedXFId ) :
+ XclExpCellBase( nRecId, 2, rXclPos ),
+ maXFId( nForcedXFId ),
+ mnContSize( nContSize )
+{
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ SetXFId( rRoot.GetXFBuffer().Insert( pPattern, nScript ) );
+}
+
+sal_uInt16 XclExpSingleCellBase::GetLastXclCol() const
+{
+ return GetXclCol();
+}
+
+sal_uInt32 XclExpSingleCellBase::GetFirstXFId() const
+{
+ return GetXFId();
+}
+
+bool XclExpSingleCellBase::IsEmpty() const
+{
+ return false;
+}
+
+void XclExpSingleCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
+{
+ maXFId.ConvertXFIndex( rRoot );
+}
+
+void XclExpSingleCellBase::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+ AddRecSize( mnContSize );
+ XclExpCellBase::Save( rStrm );
+}
+
+void XclExpSingleCellBase::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16> (GetXclRow()) << GetXclCol() << maXFId.mnXFIndex;
+ WriteContents( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpNumberCell, 256, 256 )
+
+XclExpNumberCell::XclExpNumberCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, double fValue ) :
+ // #i41210# always use latin script for number cells - may look wrong for special number formats...
+ XclExpSingleCellBase( rRoot, EXC_ID3_NUMBER, 8, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
+ mfValue( fValue )
+{
+}
+
+static OString lcl_GetStyleId( XclExpXmlStream& rStrm, sal_uInt32 nXFIndex )
+{
+ return OString::valueOf( rStrm.GetRoot().GetXFBuffer()
+ .GetXmlCellIndex( nXFIndex ) );
+}
+
+static OString lcl_GetStyleId( XclExpXmlStream& rStrm, const XclExpCellBase& rCell )
+{
+ sal_uInt32 nXFId = rCell.GetFirstXFId();
+ sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( nXFId );
+ return lcl_GetStyleId( rStrm, nXFIndex );
+}
+
+void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "n",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( mfValue );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpNumberCell::WriteContents( XclExpStream& rStrm )
+{
+ rStrm << mfValue;
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBooleanCell, 256, 256 )
+
+XclExpBooleanCell::XclExpBooleanCell(
+ const XclExpRoot rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, bool bValue ) :
+ // #i41210# always use latin script for boolean cells
+ XclExpSingleCellBase( rRoot, EXC_ID3_BOOLERR, 2, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
+ mbValue( bValue )
+{
+}
+
+void XclExpBooleanCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "b",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( mbValue ? "1" : "0" );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpBooleanCell::WriteContents( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( mbValue ? 1 : 0 ) << EXC_BOOLERR_BOOL;
+}
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpLabelCell, 256, 256 )
+
+XclExpLabelCell::XclExpLabelCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, const ScStringCell& rCell ) :
+ XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
+{
+ sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
+ XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, EXC_STR_DEFAULT, nMaxLen );
+ Init( rRoot, pPattern, xText );
+}
+
+XclExpLabelCell::XclExpLabelCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScEditCell& rCell, XclExpHyperlinkHelper& rLinkHelper ) :
+ XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
+{
+ sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
+ XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, rLinkHelper, EXC_STR_DEFAULT, nMaxLen );
+ Init( rRoot, pPattern, xText );
+}
+
+bool XclExpLabelCell::IsMultiLineText() const
+{
+ return mbLineBreak || mxText->IsWrapped();
+}
+
+void XclExpLabelCell::Init( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, XclExpStringRef xText )
+{
+ DBG_ASSERT( xText && xText->Len(), "XclExpLabelCell::XclExpLabelCell - empty string passed" );
+ mxText = xText;
+ mnSstIndex = 0;
+
+ // create the cell format
+ sal_uInt16 nXclFont = mxText->RemoveLeadingFont();
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ {
+ DBG_ASSERT( nXclFont != EXC_FONT_NOTFOUND, "XclExpLabelCell::Init - leading font not found" );
+ bool bForceLineBreak = mxText->IsWrapped();
+ SetXFId( rRoot.GetXFBuffer().InsertWithFont( pPattern, ApiScriptType::WEAK, nXclFont, bForceLineBreak ) );
+ }
+
+ // get auto-wrap attribute from cell format
+ const XclExpXF* pXF = rRoot.GetXFBuffer().GetXFById( GetXFId() );
+ mbLineBreak = pXF && pXF->GetAlignmentData().mbLineBreak;
+
+ // initialize the record contents
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF5:
+ // BIFF5-BIFF7: create a LABEL or RSTRING record
+ DBG_ASSERT( mxText->Len() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::XclExpLabelCell - string too long" );
+ SetContSize( mxText->GetSize() );
+ // formatted string is exported in an RSTRING record
+ if( mxText->IsRich() )
+ {
+ DBG_ASSERT( mxText->GetFormatsCount() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::WriteContents - too many formats" );
+ mxText->LimitFormatCount( EXC_LABEL_MAXLEN );
+ SetRecId( EXC_ID_RSTRING );
+ SetContSize( GetContSize() + 1 + 2 * mxText->GetFormatsCount() );
+ }
+ break;
+ case EXC_BIFF8:
+ // BIFF8+: create a LABELSST record
+ mnSstIndex = rRoot.GetSst().Insert( xText );
+ SetRecId( EXC_ID_LABELSST );
+ SetContSize( 4 );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpLabelCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, "s",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( (sal_Int32) mnSstIndex );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpLabelCell::WriteContents( XclExpStream& rStrm )
+{
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF5:
+ rStrm << *mxText;
+ if( mxText->IsRich() )
+ {
+ rStrm << static_cast< sal_uInt8 >( mxText->GetFormatsCount() );
+ mxText->WriteFormats( rStrm );
+ }
+ break;
+ case EXC_BIFF8:
+ rStrm << mnSstIndex;
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpFormulaCell, 256, 256 )
+
+XclExpFormulaCell::XclExpFormulaCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScFormulaCell& rScFmlaCell,
+ XclExpArrayBuffer& rArrayBfr,
+ XclExpShrfmlaBuffer& rShrfmlaBfr,
+ XclExpTableopBuffer& rTableopBfr ) :
+ XclExpSingleCellBase( EXC_ID2_FORMULA, 0, rXclPos, nForcedXFId ),
+ mrScFmlaCell( const_cast< ScFormulaCell& >( rScFmlaCell ) )
+{
+ // *** Find result number format overwriting cell number format *** -------
+
+ if( GetXFId() == EXC_XFID_NOTFOUND )
+ {
+ SvNumberFormatter& rFormatter = rRoot.GetFormatter();
+ XclExpNumFmtBuffer& rNumFmtBfr = rRoot.GetNumFmtBuffer();
+
+ // current cell number format
+ sal_uLong nScNumFmt = pPattern ?
+ GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong ) :
+ rNumFmtBfr.GetStandardFormat();
+
+ // alternative number format passed to XF buffer
+ sal_uLong nAltScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ /* Xcl doesn't know Boolean number formats, we write
+ "TRUE";"FALSE" (language dependent). Don't do it for automatic
+ formula formats, because Excel gets them right. */
+ /* #i8640# Don't set text format, if we have string results. */
+ short nFormatType = mrScFmlaCell.GetFormatType();
+ if( ((nScNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0) &&
+ (nFormatType != NUMBERFORMAT_LOGICAL) &&
+ (nFormatType != NUMBERFORMAT_TEXT) )
+ nAltScNumFmt = mrScFmlaCell.GetStandardFormat( rFormatter, nScNumFmt );
+ /* If cell number format is Boolean and automatic formula
+ format is Boolean don't write that ugly special format. */
+ else if( (nFormatType == NUMBERFORMAT_LOGICAL) &&
+ (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) )
+ nAltScNumFmt = rNumFmtBfr.GetStandardFormat();
+
+ // #i41420# find script type according to result type (always latin for numeric results)
+ sal_Int16 nScript = ApiScriptType::LATIN;
+ bool bForceLineBreak = false;
+ if( nFormatType == NUMBERFORMAT_TEXT )
+ {
+ String aResult;
+ mrScFmlaCell.GetString( aResult );
+ bForceLineBreak = mrScFmlaCell.IsMultilineResult();
+ nScript = XclExpStringHelper::GetLeadingScriptType( rRoot, aResult );
+ }
+ SetXFId( rRoot.GetXFBuffer().InsertWithNumFmt( pPattern, nScript, nAltScNumFmt, bForceLineBreak ) );
+ }
+
+ // *** Convert the formula token array *** --------------------------------
+
+ ScAddress aScPos( static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), rRoot.GetCurrScTab() );
+ const ScTokenArray& rScTokArr = *mrScFmlaCell.GetCode();
+
+ // first try to create multiple operations
+ mxAddRec = rTableopBfr.CreateOrExtendTableop( rScTokArr, aScPos );
+
+ // no multiple operation found - try to create matrix formula
+ if( !mxAddRec ) switch( static_cast< ScMatrixMode >( mrScFmlaCell.GetMatrixFlag() ) )
+ {
+ case MM_FORMULA:
+ {
+ // origin of the matrix - find the used matrix range
+ SCCOL nMatWidth;
+ SCROW nMatHeight;
+ mrScFmlaCell.GetMatColsRows( nMatWidth, nMatHeight );
+ DBG_ASSERT( nMatWidth && nMatHeight, "XclExpFormulaCell::XclExpFormulaCell - empty matrix" );
+ ScRange aMatScRange( aScPos );
+ ScAddress& rMatEnd = aMatScRange.aEnd;
+ rMatEnd.IncCol( static_cast< SCsCOL >( nMatWidth - 1 ) );
+ rMatEnd.IncRow( static_cast< SCsROW >( nMatHeight - 1 ) );
+ // reduce to valid range (range keeps valid, because start position IS valid)
+ rRoot.GetAddressConverter().ValidateRange( aMatScRange, true );
+ // create the ARRAY record
+ mxAddRec = rArrayBfr.CreateArray( rScTokArr, aMatScRange );
+ }
+ break;
+ case MM_REFERENCE:
+ {
+ // other formula cell covered by a matrix - find the ARRAY record
+ mxAddRec = rArrayBfr.FindArray( rScTokArr );
+ // should always be found, if Calc document is not broken
+ DBG_ASSERT( mxAddRec, "XclExpFormulaCell::XclExpFormulaCell - no matrix found" );
+ }
+ break;
+ default:;
+ }
+
+ // no matrix found - try to create shared formula
+ if( !mxAddRec )
+ mxAddRec = rShrfmlaBfr.CreateOrExtendShrfmla( rScTokArr, aScPos );
+
+ // no shared formula found - create a simple cell formula
+ if( !mxAddRec )
+ mxTokArr = rRoot.GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CELL, rScTokArr, &aScPos );
+}
+
+void XclExpFormulaCell::Save( XclExpStream& rStrm )
+{
+ // create token array for FORMULA cells with additional record
+ if( mxAddRec )
+ mxTokArr = mxAddRec->CreateCellTokenArray( rStrm.GetRoot() );
+
+ // FORMULA record itself
+ DBG_ASSERT( mxTokArr, "XclExpFormulaCell::Save - missing token array" );
+ if( !mxTokArr )
+ mxTokArr = rStrm.GetRoot().GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NA );
+ SetContSize( 16 + mxTokArr->GetSize() );
+ XclExpSingleCellBase::Save( rStrm );
+
+ // additional record (ARRAY, SHRFMLA, or TABLEOP), only for first FORMULA record
+ if( mxAddRec && mxAddRec->IsBasePos( GetXclCol(), GetXclRow() ) )
+ mxAddRec->Save( rStrm );
+
+ // STRING record for string result
+ if( mxStringRec )
+ mxStringRec->Save( rStrm );
+}
+
+void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ const char* sType = NULL;
+ OUString sValue;
+
+ XclXmlUtils::GetFormulaTypeAndValue( mrScFmlaCell, sType, sValue );
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, *this ).getStr(),
+ XML_t, sType,
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+
+ rWorksheet->startElement( XML_f,
+ // OOXTODO: XML_t, ST_CellFormulaType
+ XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ),
+ // OOXTODO: XML_ref, ST_Ref
+ // OOXTODO: XML_dt2D, bool
+ // OOXTODO: XML_dtr, bool
+ // OOXTODO: XML_del1, bool
+ // OOXTODO: XML_del2, bool
+ // OOXTODO: XML_r1, ST_CellRef
+ // OOXTODO: XML_r2, ST_CellRef
+ // OOXTODO: XML_ca, bool
+ // OOXTODO: XML_si, uint
+ // OOXTODO: XML_bx bool
+ FSEND );
+ rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *mrScFmlaCell.GetDocument(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode() ) );
+ rWorksheet->endElement( XML_f );
+ if( strcmp( sType, "inlineStr" ) == 0 )
+ {
+ rWorksheet->startElement( XML_is, FSEND );
+ rWorksheet->startElement( XML_t, FSEND );
+ rWorksheet->writeEscaped( sValue );
+ rWorksheet->endElement( XML_t );
+ rWorksheet->endElement( XML_is );
+ }
+ else
+ {
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->writeEscaped( sValue );
+ rWorksheet->endElement( XML_v );
+ }
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpFormulaCell::WriteContents( XclExpStream& rStrm )
+{
+ // result of the formula
+ switch( mrScFmlaCell.GetFormatType() )
+ {
+ case NUMBERFORMAT_NUMBER:
+ {
+ // either value or error code
+ sal_uInt16 nScErrCode = mrScFmlaCell.GetErrCode();
+ if( nScErrCode )
+ rStrm << EXC_FORMULA_RES_ERROR << sal_uInt8( 0 )
+ << XclTools::GetXclErrorCode( nScErrCode )
+ << sal_uInt8( 0 ) << sal_uInt16( 0 )
+ << sal_uInt16( 0xFFFF );
+ else
+ rStrm << mrScFmlaCell.GetValue();
+ }
+ break;
+
+ case NUMBERFORMAT_TEXT:
+ {
+ String aResult;
+ mrScFmlaCell.GetString( aResult );
+ if( aResult.Len() || (rStrm.GetRoot().GetBiff() <= EXC_BIFF5) )
+ {
+ rStrm << EXC_FORMULA_RES_STRING;
+ mxStringRec.reset( new XclExpStringRec( rStrm.GetRoot(), aResult ) );
+ }
+ else
+ rStrm << EXC_FORMULA_RES_EMPTY; // BIFF8 only
+ rStrm << sal_uInt8( 0 ) << sal_uInt32( 0 ) << sal_uInt16( 0xFFFF );
+ }
+ break;
+
+ case NUMBERFORMAT_LOGICAL:
+ {
+ sal_uInt8 nXclValue = (mrScFmlaCell.GetValue() == 0.0) ? 0 : 1;
+ rStrm << EXC_FORMULA_RES_BOOL << sal_uInt8( 0 )
+ << nXclValue << sal_uInt8( 0 ) << sal_uInt16( 0 )
+ << sal_uInt16( 0xFFFF );
+ }
+ break;
+
+ default:
+ rStrm << mrScFmlaCell.GetValue();
+ }
+
+ // flags and formula token array
+ sal_uInt16 nFlags = EXC_FORMULA_DEFAULTFLAGS;
+ ::set_flag( nFlags, EXC_FORMULA_RECALC_ALWAYS, mxTokArr->IsVolatile() || (mxAddRec && mxAddRec->IsVolatile()) );
+ ::set_flag( nFlags, EXC_FORMULA_SHARED, mxAddRec && (mxAddRec->GetRecId() == EXC_ID_SHRFMLA) );
+ rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
+}
+
+// Multiple cell records ======================================================
+
+XclExpMultiCellBase::XclExpMultiCellBase(
+ sal_uInt16 nRecId, sal_uInt16 nMulRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
+ XclExpCellBase( nRecId, 0, rXclPos ),
+ mnMulRecId( nMulRecId ),
+ mnContSize( nContSize )
+{
+}
+
+sal_uInt16 XclExpMultiCellBase::GetLastXclCol() const
+{
+ return GetXclCol() + GetCellCount() - 1;
+}
+
+sal_uInt32 XclExpMultiCellBase::GetFirstXFId() const
+{
+ return maXFIds.empty() ? XclExpXFBuffer::GetDefCellXFId() : maXFIds.front().mnXFId;
+}
+
+bool XclExpMultiCellBase::IsEmpty() const
+{
+ return maXFIds.empty();
+}
+
+void XclExpMultiCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
+{
+ for( XclExpMultiXFIdDeq::iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ aIt->ConvertXFIndex( rRoot );
+}
+
+void XclExpMultiCellBase::Save( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+
+ XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
+ XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
+ XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
+ sal_uInt16 nBegXclCol = GetXclCol();
+ sal_uInt16 nEndXclCol = nBegXclCol;
+
+ while( aRangeEnd != aEnd )
+ {
+ // find begin of next used XF range
+ aRangeBeg = aRangeEnd;
+ nBegXclCol = nEndXclCol;
+ while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
+ ++aRangeBeg;
+ }
+ // find end of next used XF range
+ aRangeEnd = aRangeBeg;
+ nEndXclCol = nBegXclCol;
+ while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
+ {
+ nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
+ ++aRangeEnd;
+ }
+
+ // export this range as a record
+ if( aRangeBeg != aRangeEnd )
+ {
+ sal_uInt16 nCount = nEndXclCol - nBegXclCol;
+ bool bIsMulti = nCount > 1;
+ sal_Size nTotalSize = GetRecSize() + (2 + mnContSize) * nCount;
+ if( bIsMulti ) nTotalSize += 2;
+
+ rStrm.StartRecord( bIsMulti ? mnMulRecId : GetRecId(), nTotalSize );
+ rStrm << static_cast<sal_uInt16> (GetXclRow()) << nBegXclCol;
+
+ sal_uInt16 nRelCol = nBegXclCol - GetXclCol();
+ for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
+ {
+ rStrm << aIt->mnXFIndex;
+ WriteContents( rStrm, nRelCol );
+ ++nRelCol;
+ }
+ }
+ if( bIsMulti )
+ rStrm << static_cast< sal_uInt16 >( nEndXclCol - 1 );
+ rStrm.EndRecord();
+ }
+ }
+}
+
+void XclExpMultiCellBase::SaveXml( XclExpXmlStream& rStrm )
+{
+ XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
+ XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
+ XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
+ sal_uInt16 nBegXclCol = GetXclCol();
+ sal_uInt16 nEndXclCol = nBegXclCol;
+
+ while( aRangeEnd != aEnd )
+ {
+ // find begin of next used XF range
+ aRangeBeg = aRangeEnd;
+ nBegXclCol = nEndXclCol;
+ while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
+ ++aRangeBeg;
+ }
+ // find end of next used XF range
+ aRangeEnd = aRangeBeg;
+ nEndXclCol = nBegXclCol;
+ while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
+ {
+ nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
+ ++aRangeEnd;
+ }
+
+ // export this range as a record
+ if( aRangeBeg != aRangeEnd )
+ {
+ sal_uInt16 nRelColIdx = nBegXclCol - GetXclCol();
+ sal_Int32 nRelCol = 0;
+ for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
+ {
+ WriteXmlContents(
+ rStrm,
+ XclAddress( static_cast<sal_uInt16>(nBegXclCol + nRelCol), GetXclRow() ),
+ aIt->mnXFIndex,
+ nRelColIdx );
+ ++nRelCol;
+ ++nRelColIdx;
+ }
+ }
+ }
+ }
+}
+
+sal_uInt16 XclExpMultiCellBase::GetCellCount() const
+{
+ sal_uInt16 nCount = 0;
+ for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ nCount = nCount + aIt->mnCount;
+ return nCount;
+}
+
+void XclExpMultiCellBase::AppendXFId( const XclExpMultiXFId& rXFId )
+{
+ if( maXFIds.empty() || (maXFIds.back().mnXFId != rXFId.mnXFId) )
+ maXFIds.push_back( rXFId );
+ else
+ maXFIds.back().mnCount = maXFIds.back().mnCount + rXFId.mnCount;
+}
+
+void XclExpMultiCellBase::AppendXFId( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, sal_uInt16 nScript, sal_uInt32 nForcedXFId, sal_uInt16 nCount )
+{
+ sal_uInt32 nXFId = (nForcedXFId == EXC_XFID_NOTFOUND) ?
+ rRoot.GetXFBuffer().Insert( pPattern, nScript ) : nForcedXFId;
+ AppendXFId( XclExpMultiXFId( nXFId, nCount ) );
+}
+
+bool XclExpMultiCellBase::TryMergeXFIds( const XclExpMultiCellBase& rCell )
+{
+ if( GetLastXclCol() + 1 == rCell.GetXclCol() )
+ {
+ maXFIds.insert( maXFIds.end(), rCell.maXFIds.begin(), rCell.maXFIds.end() );
+ return true;
+ }
+ return false;
+}
+
+void XclExpMultiCellBase::GetXFIndexes( ScfUInt16Vec& rXFIndexes ) const
+{
+ DBG_ASSERT( GetLastXclCol() < rXFIndexes.size(), "XclExpMultiCellBase::GetXFIndexes - vector too small" );
+ ScfUInt16Vec::iterator aDestIt = rXFIndexes.begin() + GetXclCol();
+ for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
+ {
+ ::std::fill( aDestIt, aDestIt + aIt->mnCount, aIt->mnXFIndex );
+ aDestIt += aIt->mnCount;
+ }
+}
+
+void XclExpMultiCellBase::RemoveUnusedXFIndexes( const ScfUInt16Vec& rXFIndexes )
+{
+ // save last column before calling maXFIds.clear()
+ sal_uInt16 nLastXclCol = GetLastXclCol();
+ DBG_ASSERT( nLastXclCol < rXFIndexes.size(), "XclExpMultiCellBase::RemoveUnusedXFIndexes - XF index vector too small" );
+
+ // build new XF index vector, containing passed XF indexes
+ maXFIds.clear();
+ XclExpMultiXFId aXFId( 0 );
+ for( ScfUInt16Vec::const_iterator aIt = rXFIndexes.begin() + GetXclCol(), aEnd = rXFIndexes.begin() + nLastXclCol + 1; aIt != aEnd; ++aIt )
+ {
+ // AppendXFId() tests XclExpXFIndex::mnXFId, set it too
+ aXFId.mnXFId = aXFId.mnXFIndex = *aIt;
+ AppendXFId( aXFId );
+ }
+
+ // remove leading and trailing unused XF indexes
+ if( !maXFIds.empty() && (maXFIds.front().mnXFIndex == EXC_XF_NOTFOUND) )
+ {
+ SetXclCol( GetXclCol() + maXFIds.front().mnCount );
+ maXFIds.pop_front();
+ }
+ if( !maXFIds.empty() && (maXFIds.back().mnXFIndex == EXC_XF_NOTFOUND) )
+ maXFIds.pop_back();
+
+ // The Save() function will skip all XF indexes equal to EXC_XF_NOTFOUND.
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBlankCell, 256, 256 )
+
+XclExpBlankCell::XclExpBlankCell( const XclAddress& rXclPos, const XclExpMultiXFId& rXFId ) :
+ XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
+{
+ DBG_ASSERT( rXFId.mnCount > 0, "XclExpBlankCell::XclExpBlankCell - invalid count" );
+ AppendXFId( rXFId );
+}
+
+XclExpBlankCell::XclExpBlankCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos, sal_uInt16 nLastXclCol,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId ) :
+ XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
+{
+ DBG_ASSERT( rXclPos.mnCol <= nLastXclCol, "XclExpBlankCell::XclExpBlankCell - invalid column range" );
+ // #i46627# use default script type instead of ApiScriptType::WEAK
+ AppendXFId( rRoot, pPattern, rRoot.GetDefApiScript(), nForcedXFId, nLastXclCol - rXclPos.mnCol + 1 );
+}
+
+bool XclExpBlankCell::TryMerge( const XclExpCellBase& rCell )
+{
+ const XclExpBlankCell* pBlankCell = dynamic_cast< const XclExpBlankCell* >( &rCell );
+ return pBlankCell && TryMergeXFIds( *pBlankCell );
+}
+
+void XclExpBlankCell::GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const
+{
+ GetXFIndexes( rXFIndexes );
+}
+
+void XclExpBlankCell::RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes )
+{
+ RemoveUnusedXFIndexes( rXFIndexes );
+}
+
+void XclExpBlankCell::WriteContents( XclExpStream& /*rStrm*/, sal_uInt16 /*nRelCol*/ )
+{
+}
+
+void XclExpBlankCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 /* nRelCol */ )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->singleElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( rAddress ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, nXFId ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclExpRkCell, 256, 256 )
+
+XclExpRkCell::XclExpRkCell(
+ const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, sal_Int32 nRkValue ) :
+ XclExpMultiCellBase( EXC_ID_RK, EXC_ID_MULRK, 4, rXclPos )
+{
+ // #i41210# always use latin script for number cells - may look wrong for special number formats...
+ AppendXFId( rRoot, pPattern, ApiScriptType::LATIN, nForcedXFId );
+ maRkValues.push_back( nRkValue );
+}
+
+bool XclExpRkCell::TryMerge( const XclExpCellBase& rCell )
+{
+ const XclExpRkCell* pRkCell = dynamic_cast< const XclExpRkCell* >( &rCell );
+ if( pRkCell && TryMergeXFIds( *pRkCell ) )
+ {
+ maRkValues.insert( maRkValues.end(), pRkCell->maRkValues.begin(), pRkCell->maRkValues.end() );
+ return true;
+ }
+ return false;
+}
+
+void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_c,
+ XML_r, XclXmlUtils::ToOString( rAddress ).getStr(),
+ XML_s, lcl_GetStyleId( rStrm, nXFId ).getStr(),
+ XML_t, "n",
+ // OOXTODO: XML_cm, XML_vm, XML_ph
+ FSEND );
+ rWorksheet->startElement( XML_v, FSEND );
+ rWorksheet->write( XclTools::GetDoubleFromRK( maRkValues[ nRelCol ] ) );
+ rWorksheet->endElement( XML_v );
+ rWorksheet->endElement( XML_c );
+}
+
+void XclExpRkCell::WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol )
+{
+ DBG_ASSERT( nRelCol < maRkValues.size(), "XclExpRkCell::WriteContents - overflow error" );
+ rStrm << maRkValues[ nRelCol ];
+}
+
+// ============================================================================
+// Rows and Columns
+// ============================================================================
+
+XclExpOutlineBuffer::XclExpOutlineBuffer( const XclExpRoot& rRoot, bool bRows ) :
+ mpScOLArray( 0 ),
+ maLevelInfos( SC_OL_MAXDEPTH ),
+ mnCurrLevel( 0 ),
+ mbCurrCollapse( false )
+{
+ if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
+ mpScOLArray = bRows ? pOutlineTable->GetRowArray() : pOutlineTable->GetColArray();
+
+ if( mpScOLArray )
+ for( sal_uInt16 nLevel = 0; nLevel < SC_OL_MAXDEPTH; ++nLevel )
+ if( ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nLevel, 0 ) )
+ maLevelInfos[ nLevel ].mnScEndPos = pEntry->GetEnd();
+}
+
+void XclExpOutlineBuffer::UpdateColRow( SCCOLROW nScPos )
+{
+ if( mpScOLArray )
+ {
+ // find open level index for passed position
+ sal_uInt16 nNewOpenScLevel = 0; // new open level (0-based Calc index)
+ sal_uInt8 nNewLevel = 0; // new open level (1-based Excel index)
+
+ if( mpScOLArray->FindTouchedLevel( nScPos, nScPos, nNewOpenScLevel ) )
+ nNewLevel = static_cast< sal_uInt8 >( nNewOpenScLevel + 1 );
+ // else nNewLevel keeps 0 to show that there are no groups
+
+ mbCurrCollapse = false;
+ if( nNewLevel >= mnCurrLevel )
+ {
+ // new level(s) opened, or no level closed - update all level infos
+ for( sal_uInt16 nScLevel = 0; nScLevel <= nNewOpenScLevel; ++nScLevel )
+ {
+ /* In each level: check if a new group is started (there may be
+ neighbored groups without gap - therefore check ALL levels). */
+ if( maLevelInfos[ nScLevel ].mnScEndPos < nScPos )
+ {
+ if( ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nScLevel, nScPos ) )
+ {
+ maLevelInfos[ nScLevel ].mnScEndPos = pEntry->GetEnd();
+ maLevelInfos[ nScLevel ].mbHidden = pEntry->IsHidden();
+ }
+ }
+ }
+ }
+ else
+ {
+ // level(s) closed - check if any of the closed levels are collapsed
+ // Calc uses 0-based level indexes
+ sal_uInt16 nOldOpenScLevel = mnCurrLevel - 1;
+ for( sal_uInt16 nScLevel = nNewOpenScLevel + 1; !mbCurrCollapse && (nScLevel <= nOldOpenScLevel); ++nScLevel )
+ mbCurrCollapse = maLevelInfos[ nScLevel ].mbHidden;
+ }
+
+ // cache new opened level
+ mnCurrLevel = nNewLevel;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpGuts::XclExpGuts( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_GUTS, 8 ),
+ mnColLevels( 0 ),
+ mnColWidth( 0 ),
+ mnRowLevels( 0 ),
+ mnRowWidth( 0 )
+{
+ if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
+ {
+ // column outline groups
+ if( const ScOutlineArray* pColArray = pOutlineTable->GetColArray() )
+ mnColLevels = ulimit_cast< sal_uInt16 >( pColArray->GetDepth(), EXC_OUTLINE_MAX );
+ if( mnColLevels )
+ {
+ ++mnColLevels;
+ mnColWidth = 12 * mnColLevels + 5;
+ }
+
+ // row outline groups
+ if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
+ mnRowLevels = ulimit_cast< sal_uInt16 >( pRowArray->GetDepth(), EXC_OUTLINE_MAX );
+ if( mnRowLevels )
+ {
+ ++mnRowLevels;
+ mnRowWidth = 12 * mnRowLevels + 5;
+ }
+ }
+}
+
+void XclExpGuts::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnRowWidth << mnColWidth << mnRowLevels << mnColLevels;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDimensions::XclExpDimensions( const XclExpRoot& rRoot ) :
+ mnFirstUsedXclRow( 0 ),
+ mnFirstFreeXclRow( 0 ),
+ mnFirstUsedXclCol( 0 ),
+ mnFirstFreeXclCol( 0 )
+{
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF2: SetRecHeader( EXC_ID2_DIMENSIONS, 8 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5: SetRecHeader( EXC_ID3_DIMENSIONS, 10 ); break;
+ case EXC_BIFF8: SetRecHeader( EXC_ID3_DIMENSIONS, 14 ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+void XclExpDimensions::SetDimensions(
+ sal_uInt16 nFirstUsedXclCol, sal_uInt32 nFirstUsedXclRow,
+ sal_uInt16 nFirstFreeXclCol, sal_uInt32 nFirstFreeXclRow )
+{
+ mnFirstUsedXclRow = nFirstUsedXclRow;
+ mnFirstFreeXclRow = nFirstFreeXclRow;
+ mnFirstUsedXclCol = nFirstUsedXclCol;
+ mnFirstFreeXclCol = nFirstFreeXclCol;
+}
+
+void XclExpDimensions::SaveXml( XclExpXmlStream& rStrm )
+{
+ ScRange aRange;
+ aRange.aStart.SetRow( (SCROW) mnFirstUsedXclRow );
+ aRange.aStart.SetCol( (SCCOL) mnFirstUsedXclCol );
+
+ if( mnFirstFreeXclRow != mnFirstUsedXclRow && mnFirstFreeXclCol != mnFirstUsedXclCol )
+ {
+ aRange.aEnd.SetRow( (SCROW) (mnFirstFreeXclRow-1) );
+ aRange.aEnd.SetCol( (SCCOL) (mnFirstFreeXclCol-1) );
+ }
+
+ rStrm.GetCurrentStream()->singleElement( XML_dimension,
+ XML_ref, XclXmlUtils::ToOString( aRange ).getStr(),
+ FSEND );
+}
+
+void XclExpDimensions::WriteBody( XclExpStream& rStrm )
+{
+ XclBiff eBiff = rStrm.GetRoot().GetBiff();
+ if( eBiff == EXC_BIFF8 )
+ rStrm << mnFirstUsedXclRow << mnFirstFreeXclRow;
+ else
+ rStrm << static_cast< sal_uInt16 >( mnFirstUsedXclRow ) << static_cast< sal_uInt16 >( mnFirstFreeXclRow );
+ rStrm << mnFirstUsedXclCol << mnFirstFreeXclCol;
+ if( eBiff >= EXC_BIFF3 )
+ rStrm << sal_uInt16( 0 );
+}
+
+// ============================================================================
+
+namespace {
+
+double lclGetCorrectedColWidth( const XclExpRoot& rRoot, sal_uInt16 nXclColWidth )
+{
+ long nFontHt = rRoot.GetFontBuffer().GetAppFontData().mnHeight;
+ return nXclColWidth - XclTools::GetXclDefColWidthCorrection( nFontHt );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpDefcolwidth::XclExpDefcolwidth( const XclExpRoot& rRoot ) :
+ XclExpUInt16Record( EXC_ID_DEFCOLWIDTH, EXC_DEFCOLWIDTH_DEF ),
+ XclExpRoot( rRoot )
+{
+}
+
+bool XclExpDefcolwidth::IsDefWidth( sal_uInt16 nXclColWidth ) const
+{
+ double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
+ // exactly matched, if difference is less than 1/16 of a character to the left or to the right
+ return Abs( static_cast< long >( GetValue() * 256.0 - fNewColWidth + 0.5 ) ) < 16;
+}
+
+void XclExpDefcolwidth::SetDefWidth( sal_uInt16 nXclColWidth )
+{
+ double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
+ SetValue( limit_cast< sal_uInt16 >( fNewColWidth / 256.0 + 0.5 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot,
+ SCCOL nScCol, SCROW nLastScRow, XclExpColOutlineBuffer& rOutlineBfr ) :
+ XclExpRecord( EXC_ID_COLINFO, 12 ),
+ XclExpRoot( rRoot ),
+ mnWidth( 0 ),
+ mnFlags( 0 ),
+ mnFirstXclCol( static_cast< sal_uInt16 >( nScCol ) ),
+ mnLastXclCol( static_cast< sal_uInt16 >( nScCol ) )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // column default format
+ maXFId.mnXFId = GetXFBuffer().Insert(
+ rDoc.GetMostUsedPattern( nScCol, 0, nLastScRow, nScTab ), GetDefApiScript() );
+
+ // column width
+ sal_uInt16 nScWidth = rDoc.GetColWidth( nScCol, nScTab );
+ mnWidth = XclTools::GetXclColumnWidth( nScWidth, GetCharWidth() );
+
+ // column flags
+ ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, rDoc.ColHidden(nScCol, nScTab) );
+
+ // outline data
+ rOutlineBfr.Update( nScCol );
+ ::set_flag( mnFlags, EXC_COLINFO_COLLAPSED, rOutlineBfr.IsCollapsed() );
+ ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 8, 3 );
+}
+
+sal_uInt16 XclExpColinfo::ConvertXFIndexes()
+{
+ maXFId.ConvertXFIndex( GetRoot() );
+ return maXFId.mnXFIndex;
+}
+
+bool XclExpColinfo::IsDefault( const XclExpDefcolwidth& rDefColWidth ) const
+{
+ return (maXFId.mnXFIndex == EXC_XF_DEFAULTCELL) && (mnFlags == 0) && rDefColWidth.IsDefWidth( mnWidth );
+}
+
+bool XclExpColinfo::TryMerge( const XclExpColinfo& rColInfo )
+{
+ if( (maXFId.mnXFIndex == rColInfo.maXFId.mnXFIndex) &&
+ (mnWidth == rColInfo.mnWidth) &&
+ (mnFlags == rColInfo.mnFlags) &&
+ (mnLastXclCol + 1 == rColInfo.mnFirstXclCol) )
+ {
+ mnLastXclCol = rColInfo.mnLastXclCol;
+ return true;
+ }
+ return false;
+}
+
+void XclExpColinfo::WriteBody( XclExpStream& rStrm )
+{
+ // if last column is equal to last possible column, Excel adds one more
+ sal_uInt16 nLastXclCol = mnLastXclCol;
+ if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
+ ++nLastXclCol;
+
+ rStrm << mnFirstXclCol
+ << nLastXclCol
+ << mnWidth
+ << maXFId.mnXFIndex
+ << mnFlags
+ << sal_uInt16( 0 );
+}
+
+void XclExpColinfo::SaveXml( XclExpXmlStream& rStrm )
+{
+ // if last column is equal to last possible column, Excel adds one more
+ sal_uInt16 nLastXclCol = mnLastXclCol;
+ if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
+ ++nLastXclCol;
+
+ rStrm.GetCurrentStream()->singleElement( XML_col,
+ // OOXTODO: XML_bestFit,
+ XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_COLLAPSED ) ),
+ // OOXTODO: XML_customWidth,
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_HIDDEN ) ),
+ XML_max, OString::valueOf( (sal_Int32) (nLastXclCol+1) ).getStr(),
+ XML_min, OString::valueOf( (sal_Int32) (mnFirstXclCol+1) ).getStr(),
+ // OOXTODO: XML_outlineLevel,
+ // OOXTODO: XML_phonetic,
+ XML_style, lcl_GetStyleId( rStrm, maXFId.mnXFIndex ).getStr(),
+ XML_width, OString::valueOf( (double) (mnWidth / 255.0) ).getStr(),
+ FSEND );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpColinfoBuffer::XclExpColinfoBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maDefcolwidth( rRoot ),
+ maOutlineBfr( rRoot )
+{
+}
+
+void XclExpColinfoBuffer::Initialize( SCROW nLastScRow )
+{
+
+ for( sal_uInt16 nScCol = 0, nLastScCol = GetMaxPos().Col(); nScCol <= nLastScCol; ++nScCol )
+ maColInfos.AppendNewRecord( new XclExpColinfo( GetRoot(), nScCol, nLastScRow, maOutlineBfr ) );
+}
+
+void XclExpColinfoBuffer::Finalize( ScfUInt16Vec& rXFIndexes )
+{
+ rXFIndexes.clear();
+ rXFIndexes.reserve( maColInfos.GetSize() );
+
+ size_t nPos, nSize;
+
+ // do not cache the record list size, it may change in the loop
+ for( nPos = 0; nPos < maColInfos.GetSize(); ++nPos )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ xRec->ConvertXFIndexes();
+
+ // try to merge with previous record
+ if( nPos > 0 )
+ {
+ XclExpColinfoRef xPrevRec = maColInfos.GetRecord( nPos - 1 );
+ if( xPrevRec->TryMerge( *xRec ) )
+ // adjust nPos to get the next COLINFO record at the same position
+ maColInfos.RemoveRecord( nPos-- );
+ }
+ }
+
+ // put XF indexes into passed vector, collect use count of all different widths
+ typedef ::std::map< sal_uInt16, sal_uInt16 > XclExpWidthMap;
+ XclExpWidthMap aWidthMap;
+ sal_uInt16 nMaxColCount = 0;
+ sal_uInt16 nMaxUsedWidth = 0;
+ for( nPos = 0, nSize = maColInfos.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ sal_uInt16 nColCount = xRec->GetColCount();
+
+ // add XF index to passed vector
+ rXFIndexes.resize( rXFIndexes.size() + nColCount, xRec->GetXFIndex() );
+
+ // collect use count of column width
+ sal_uInt16 nWidth = xRec->GetColWidth();
+ sal_uInt16& rnMapCount = aWidthMap[ nWidth ];
+ rnMapCount = rnMapCount + nColCount;
+ if( rnMapCount > nMaxColCount )
+ {
+ nMaxColCount = rnMapCount;
+ nMaxUsedWidth = nWidth;
+ }
+ }
+ maDefcolwidth.SetDefWidth( nMaxUsedWidth );
+
+ // remove all default COLINFO records
+ nPos = 0;
+ while( nPos < maColInfos.GetSize() )
+ {
+ XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
+ if( xRec->IsDefault( maDefcolwidth ) )
+ maColInfos.RemoveRecord( nPos );
+ else
+ ++nPos;
+ }
+}
+
+void XclExpColinfoBuffer::Save( XclExpStream& rStrm )
+{
+ // DEFCOLWIDTH
+ maDefcolwidth.Save( rStrm );
+ // COLINFO records
+ maColInfos.Save( rStrm );
+}
+
+void XclExpColinfoBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( maColInfos.IsEmpty() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_cols,
+ FSEND );
+ maColInfos.SaveXml( rStrm );
+ rWorksheet->endElement( XML_cols );
+}
+
+// ============================================================================
+
+XclExpDefaultRowData::XclExpDefaultRowData() :
+ mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mnHeight( EXC_DEFROW_DEFAULTHEIGHT )
+{
+}
+
+XclExpDefaultRowData::XclExpDefaultRowData( const XclExpRow& rRow ) :
+ mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
+ mnHeight( rRow.GetHeight() )
+{
+ ::set_flag( mnFlags, EXC_DEFROW_HIDDEN, rRow.IsHidden() );
+ ::set_flag( mnFlags, EXC_DEFROW_UNSYNCED, rRow.IsUnsynced() );
+}
+
+bool operator<( const XclExpDefaultRowData& rLeft, const XclExpDefaultRowData& rRight )
+{
+ return (rLeft.mnHeight < rRight.mnHeight) ||
+ ((rLeft.mnHeight == rRight.mnHeight) && (rLeft.mnFlags < rRight.mnFlags));
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpDefrowheight::XclExpDefrowheight() :
+ XclExpRecord( EXC_ID3_DEFROWHEIGHT, 4 )
+{
+}
+
+void XclExpDefrowheight::SetDefaultData( const XclExpDefaultRowData& rDefData )
+{
+ maDefData = rDefData;
+}
+
+void XclExpDefrowheight::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
+ rStrm << maDefData.mnFlags << maDefData.mnHeight;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRow::XclExpRow( const XclExpRoot& rRoot, sal_uInt32 nXclRow,
+ XclExpRowOutlineBuffer& rOutlineBfr, bool bAlwaysEmpty ) :
+ XclExpRecord( EXC_ID3_ROW, 16 ),
+ XclExpRoot( rRoot ),
+ mnXclRow( nXclRow ),
+ mnHeight( 0 ),
+ mnFlags( EXC_ROW_DEFAULTFLAGS ),
+ mnXFIndex( EXC_XF_DEFAULTCELL ),
+ mnOutlineLevel( 0 ),
+ mbAlwaysEmpty( bAlwaysEmpty ),
+ mbEnabled( true )
+{
+ SCTAB nScTab = GetCurrScTab();
+ SCROW nScRow = static_cast< SCROW >( mnXclRow );
+
+ // *** Row flags *** ------------------------------------------------------
+
+ sal_uInt8 nRowFlags = GetDoc().GetRowFlags( nScRow, nScTab );
+ bool bUserHeight = ::get_flag< sal_uInt8 >( nRowFlags, CR_MANUALSIZE );
+ bool bHidden = GetDoc().RowHidden(nScRow, nScTab);
+ ::set_flag( mnFlags, EXC_ROW_UNSYNCED, bUserHeight );
+ ::set_flag( mnFlags, EXC_ROW_HIDDEN, bHidden );
+
+ // *** Row height *** -----------------------------------------------------
+
+ // Always get the actual row height even if the manual size flag is not set,
+ // to correctly export the heights of rows with wrapped texts.
+
+ mnHeight = GetDoc().GetRowHeight(nScRow, nScTab, false);
+
+ // *** Outline data *** ---------------------------------------------------
+
+ rOutlineBfr.Update( nScRow );
+ ::set_flag( mnFlags, EXC_ROW_COLLAPSED, rOutlineBfr.IsCollapsed() );
+ ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 0, 3 );
+ mnOutlineLevel = rOutlineBfr.GetLevel();
+
+ // *** Progress bar *** ---------------------------------------------------
+
+ XclExpProgressBar& rProgress = GetProgressBar();
+ rProgress.IncRowRecordCount();
+ rProgress.Progress();
+}
+
+void XclExpRow::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
+{
+ DBG_ASSERT( !mbAlwaysEmpty, "XclExpRow::AppendCell - row is marked to be always empty" );
+ // try to merge with last existing cell
+ InsertCell( xCell, maCellList.GetSize(), bIsMergedBase );
+}
+
+void XclExpRow::Finalize( const ScfUInt16Vec& rColXFIndexes )
+{
+ size_t nPos, nSize;
+
+ // *** Convert XF identifiers *** -----------------------------------------
+
+ // additionally collect the blank XF indexes
+ size_t nColCount = GetMaxPos().Col() + 1;
+ DBG_ASSERT( rColXFIndexes.size() == nColCount, "XclExpRow::Finalize - wrong column XF index count" );
+
+ ScfUInt16Vec aXFIndexes( nColCount, EXC_XF_NOTFOUND );
+ for( nPos = 0, nSize = maCellList.GetSize(); nPos < nSize; ++nPos )
+ {
+ XclExpCellRef xCell = maCellList.GetRecord( nPos );
+ xCell->ConvertXFIndexes( GetRoot() );
+ xCell->GetBlankXFIndexes( aXFIndexes );
+ }
+
+ // *** Fill gaps with BLANK/MULBLANK cell records *** ---------------------
+
+ /* This is needed because nonexistant cells in Calc are not formatted at all,
+ but in Excel they would have the column default format. Blank cells that
+ are equal to the respective column default are removed later in this function. */
+ if( !mbAlwaysEmpty )
+ {
+ // XF identifier representing default cell XF
+ XclExpMultiXFId aXFId( XclExpXFBuffer::GetDefCellXFId() );
+ aXFId.ConvertXFIndex( GetRoot() );
+
+ nPos = 0;
+ while( nPos <= maCellList.GetSize() ) // don't cache list size, may change in the loop
+ {
+ // get column index that follows previous cell
+ sal_uInt16 nFirstFreeXclCol = (nPos > 0) ? (maCellList.GetRecord( nPos - 1 )->GetLastXclCol() + 1) : 0;
+ // get own column index
+ sal_uInt16 nNextUsedXclCol = (nPos < maCellList.GetSize()) ? maCellList.GetRecord( nPos )->GetXclCol() : (GetMaxPos().Col() + 1);
+
+ // is there a gap?
+ if( nFirstFreeXclCol < nNextUsedXclCol )
+ {
+ aXFId.mnCount = nNextUsedXclCol - nFirstFreeXclCol;
+ XclExpCellRef xNewCell( new XclExpBlankCell( XclAddress( nFirstFreeXclCol, mnXclRow ), aXFId ) );
+ // insert the cell, InsertCell() may merge it with existing BLANK records
+ InsertCell( xNewCell, nPos, false );
+ // insert default XF indexes into aXFIndexes
+ ::std::fill( aXFIndexes.begin() + nFirstFreeXclCol,
+ aXFIndexes.begin() + nNextUsedXclCol, aXFId.mnXFIndex );
+ // don't step forward with nPos, InsertCell() may remove records
+ }
+ else
+ ++nPos;
+ }
+ }
+
+ // *** Find default row format *** ----------------------------------------
+
+ ScfUInt16Vec::iterator aCellBeg = aXFIndexes.begin(), aCellEnd = aXFIndexes.end(), aCellIt;
+ ScfUInt16Vec::const_iterator aColBeg = rColXFIndexes.begin(), aColIt;
+
+ // find most used XF index in the row
+ typedef ::std::map< sal_uInt16, size_t > XclExpXFIndexMap;
+ XclExpXFIndexMap aIndexMap;
+ sal_uInt16 nRowXFIndex = EXC_XF_DEFAULTCELL;
+ size_t nMaxXFCount = 0;
+ for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
+ {
+ if( *aCellIt != EXC_XF_NOTFOUND )
+ {
+ size_t& rnCount = aIndexMap[ *aCellIt ];
+ ++rnCount;
+ if( rnCount > nMaxXFCount )
+ {
+ nRowXFIndex = *aCellIt;
+ nMaxXFCount = rnCount;
+ }
+ }
+ }
+
+ // decide whether to use the row default XF index or column default XF indexes
+ bool bUseColDefXFs = nRowXFIndex == EXC_XF_DEFAULTCELL;
+ if( !bUseColDefXFs )
+ {
+ // count needed XF indexes for blank cells with and without row default XF index
+ size_t nXFCountWithRowDefXF = 0;
+ size_t nXFCountWithoutRowDefXF = 0;
+ for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
+ {
+ sal_uInt16 nXFIndex = *aCellIt;
+ if( nXFIndex != EXC_XF_NOTFOUND )
+ {
+ if( nXFIndex != nRowXFIndex )
+ ++nXFCountWithRowDefXF; // with row default XF index
+ if( nXFIndex != *aColIt )
+ ++nXFCountWithoutRowDefXF; // without row default XF index
+ }
+ }
+
+ // use column XF indexes if this would cause less or equal number of BLANK records
+ bUseColDefXFs = nXFCountWithoutRowDefXF <= nXFCountWithRowDefXF;
+ }
+
+ // *** Remove unused BLANK cell records *** -------------------------------
+
+ if( bUseColDefXFs )
+ {
+ // use column default XF indexes
+ // #i194#: remove cell XF indexes equal to column default XF indexes
+ for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
+ if( *aCellIt == *aColIt )
+ *aCellIt = EXC_XF_NOTFOUND;
+ }
+ else
+ {
+ // use row default XF index
+ mnXFIndex = nRowXFIndex;
+ ::set_flag( mnFlags, EXC_ROW_USEDEFXF );
+ // #98133#, #i194#, #i27407#: remove cell XF indexes equal to row default XF index
+ for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
+ if( *aCellIt == nRowXFIndex )
+ *aCellIt = EXC_XF_NOTFOUND;
+ }
+
+ // remove unused parts of BLANK/MULBLANK cell records
+ nPos = 0;
+ while( nPos < maCellList.GetSize() ) // do not cache list size, may change in the loop
+ {
+ XclExpCellRef xCell = maCellList.GetRecord( nPos );
+ xCell->RemoveUnusedBlankCells( aXFIndexes );
+ if( xCell->IsEmpty() )
+ maCellList.RemoveRecord( nPos );
+ else
+ ++nPos;
+ }
+
+ // progress bar includes disabled rows
+ GetProgressBar().Progress();
+}
+
+sal_uInt16 XclExpRow::GetFirstUsedXclCol() const
+{
+ return maCellList.IsEmpty() ? 0 : maCellList.GetFirstRecord()->GetXclCol();
+}
+
+sal_uInt16 XclExpRow::GetFirstFreeXclCol() const
+{
+ return maCellList.IsEmpty() ? 0 : (maCellList.GetLastRecord()->GetLastXclCol() + 1);
+}
+
+bool XclExpRow::IsDefaultable() const
+{
+ const sal_uInt16 nAllowedFlags = EXC_ROW_DEFAULTFLAGS | EXC_ROW_HIDDEN | EXC_ROW_UNSYNCED;
+ return !::get_flag( mnFlags, static_cast< sal_uInt16 >( ~nAllowedFlags ) ) && IsEmpty();
+}
+
+void XclExpRow::DisableIfDefault( const XclExpDefaultRowData& rDefRowData )
+{
+ mbEnabled = !IsDefaultable() ||
+ (mnHeight != rDefRowData.mnHeight) ||
+ (IsHidden() != rDefRowData.IsHidden()) ||
+ (IsUnsynced() != rDefRowData.IsUnsynced());
+}
+
+void XclExpRow::WriteCellList( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mbEnabled || maCellList.IsEmpty(), "XclExpRow::WriteCellList - cells in disabled row" );
+ maCellList.Save( rStrm );
+}
+
+void XclExpRow::Save( XclExpStream& rStrm )
+{
+ if( mbEnabled )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpRow::InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase )
+{
+ DBG_ASSERT( xCell, "XclExpRow::InsertCell - missing cell" );
+
+ /* If we have a multi-line text in a merged cell, and the resulting
+ row height has not been confirmed, we need to force the EXC_ROW_UNSYNCED
+ flag to be true to ensure Excel works correctly. */
+ if( bIsMergedBase && xCell->IsMultiLineText() )
+ ::set_flag( mnFlags, EXC_ROW_UNSYNCED );
+
+ // try to merge with previous cell, insert the new cell if not successful
+ XclExpCellRef xPrevCell = maCellList.GetRecord( nPos - 1 );
+ if( xPrevCell && xPrevCell->TryMerge( *xCell ) )
+ xCell = xPrevCell;
+ else
+ maCellList.InsertRecord( xCell, nPos++ );
+ // nPos points now to following cell
+
+ // try to merge with following cell, remove it if successful
+ XclExpCellRef xNextCell = maCellList.GetRecord( nPos );
+ if( xNextCell && xCell->TryMerge( *xNextCell ) )
+ maCellList.RemoveRecord( nPos );
+}
+
+void XclExpRow::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast< sal_uInt16 >(mnXclRow)
+ << GetFirstUsedXclCol()
+ << GetFirstFreeXclCol()
+ << mnHeight
+ << sal_uInt32( 0 )
+ << mnFlags
+ << mnXFIndex;
+}
+
+void XclExpRow::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mbEnabled )
+ return;
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ bool haveFormat = ::get_flag( mnFlags, EXC_ROW_USEDEFXF );
+ rWorksheet->startElement( XML_row,
+ XML_r, OString::valueOf( (sal_Int32) (mnXclRow+1) ).getStr(),
+ // OOXTODO: XML_spans, optional
+ XML_s, haveFormat ? lcl_GetStyleId( rStrm, mnXFIndex ).getStr() : NULL,
+ XML_customFormat, XclXmlUtils::ToPsz( haveFormat ),
+ XML_ht, OString::valueOf( (double) mnHeight / 20.0 ).getStr(),
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_HIDDEN ) ),
+ XML_customHeight, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_UNSYNCED ) ),
+ XML_outlineLevel, OString::valueOf( (sal_Int32) mnOutlineLevel ).getStr(),
+ XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_COLLAPSED ) ),
+ // OOXTODO: XML_thickTop, bool
+ // OOXTODO: XML_thickBot, bool
+ // OOXTODO: XML_ph, bool
+ FSEND );
+ // OOXTODO: XML_extLst
+ maCellList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_row );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpRowBuffer::XclExpRowBuffer( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maOutlineBfr( rRoot ),
+ maDimensions( rRoot )
+{
+}
+
+void XclExpRowBuffer::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
+{
+ DBG_ASSERT( xCell, "XclExpRowBuffer::AppendCell - missing cell" );
+ GetOrCreateRow( xCell->GetXclRow(), false ).AppendCell( xCell, bIsMergedBase );
+}
+
+void XclExpRowBuffer::CreateRows( SCROW nFirstFreeScRow )
+{
+ if( nFirstFreeScRow > 0 )
+ GetOrCreateRow( static_cast< sal_uInt16 >( nFirstFreeScRow - 1 ), true );
+}
+
+void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes )
+{
+ // *** Finalize all rows *** ----------------------------------------------
+
+ GetProgressBar().ActivateFinalRowsSegment();
+
+ RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ itr->second->Finalize(rColXFIndexes);
+
+ // *** Default row format *** ---------------------------------------------
+
+ typedef ::std::map< XclExpDefaultRowData, size_t > XclExpDefRowDataMap;
+ XclExpDefRowDataMap aDefRowMap;
+
+ XclExpDefaultRowData aMaxDefData;
+ size_t nMaxDefCount = 0;
+ // only look for default format in existing rows, if there are more than unused
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ const RowRef& rRow = itr->second;
+ if (rRow->IsDefaultable())
+ {
+ XclExpDefaultRowData aDefData( *rRow );
+ size_t& rnDefCount = aDefRowMap[ aDefData ];
+ ++rnDefCount;
+ if( rnDefCount > nMaxDefCount )
+ {
+ nMaxDefCount = rnDefCount;
+ aMaxDefData = aDefData;
+ }
+ }
+ }
+
+ // return the default row format to caller
+ rDefRowData = aMaxDefData;
+
+ // *** Disable unused ROW records, find used area *** ---------------------
+
+ sal_uInt16 nFirstUsedXclCol = SAL_MAX_UINT16;
+ sal_uInt16 nFirstFreeXclCol = 0;
+ sal_uInt32 nFirstUsedXclRow = SAL_MAX_UINT32;
+ sal_uInt32 nFirstFreeXclRow = 0;
+
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ const RowRef& rRow = itr->second;
+ // disable unused rows
+ rRow->DisableIfDefault( aMaxDefData );
+
+ // find used column range
+ if( !rRow->IsEmpty() ) // empty rows return (0...0) as used range
+ {
+ nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, rRow->GetFirstUsedXclCol() );
+ nFirstFreeXclCol = ::std::max( nFirstFreeXclCol, rRow->GetFirstFreeXclCol() );
+ }
+
+ // find used row range
+ if( rRow->IsEnabled() )
+ {
+ sal_uInt16 nXclRow = rRow->GetXclRow();
+ nFirstUsedXclRow = ::std::min< sal_uInt32 >( nFirstUsedXclRow, nXclRow );
+ nFirstFreeXclRow = ::std::max< sal_uInt32 >( nFirstFreeXclRow, nXclRow + 1 );
+ }
+ }
+
+ // adjust start position, if there are no or only empty/disabled ROW records
+ nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, nFirstFreeXclCol );
+ nFirstUsedXclRow = ::std::min( nFirstUsedXclRow, nFirstFreeXclRow );
+
+ // initialize the DIMENSIONS record
+ maDimensions.SetDimensions(
+ nFirstUsedXclCol, nFirstUsedXclRow, nFirstFreeXclCol, nFirstFreeXclRow );
+}
+
+void XclExpRowBuffer::Save( XclExpStream& rStrm )
+{
+ // DIMENSIONS record
+ maDimensions.Save( rStrm );
+
+ // save in blocks of 32 rows, each block contains first all ROWs, then all cells
+ size_t nSize = maRowMap.size();
+ RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
+ RowMap::iterator itrBlkStart = maRowMap.begin(), itrBlkEnd = maRowMap.begin();
+ sal_uInt16 nStartXclRow = (nSize == 0) ? 0 : itrBeg->second->GetXclRow();
+
+
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ // find end of row block
+ while( (itrBlkEnd != itrEnd) && (itrBlkEnd->second->GetXclRow() - nStartXclRow < EXC_ROW_ROWBLOCKSIZE) )
+ ++itrBlkEnd;
+
+ // write the ROW records
+ RowMap::iterator itRow;
+ for( itRow = itrBlkStart; itRow != itrBlkEnd; ++itRow )
+ itRow->second->Save( rStrm );
+
+ // write the cell records
+ for( itRow = itrBlkStart; itRow != itrBlkEnd; ++itRow )
+ itRow->second->WriteCellList( rStrm );
+
+ itrBlkStart = (itrBlkEnd == itrEnd) ? itrBlkEnd : itrBlkEnd++;
+ nStartXclRow += EXC_ROW_ROWBLOCKSIZE;
+ }
+}
+
+void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
+{
+ sal_Int32 nNonEmpty = 0;
+ RowMap::iterator itr = maRowMap.begin(), itrEnd = maRowMap.end();
+ for (; itr != itrEnd; ++itr)
+ if (itr->second->IsEnabled())
+ ++nNonEmpty;
+
+ if (nNonEmpty == 0)
+ {
+ rStrm.GetCurrentStream()->singleElement( XML_sheetData, FSEND );
+ return;
+ }
+
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetData, FSEND );
+ for (itr = maRowMap.begin(); itr != itrEnd; ++itr)
+ itr->second->SaveXml(rStrm);
+ rWorksheet->endElement( XML_sheetData );
+}
+
+XclExpDimensions* XclExpRowBuffer::GetDimensions()
+{
+ return &maDimensions;
+}
+
+XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty )
+{
+ RowMap::iterator itr = maRowMap.find(nXclRow);
+ if (itr == maRowMap.end())
+ {
+ RowRef p(new XclExpRow(GetRoot(), nXclRow, maOutlineBfr, bRowAlwaysEmpty));
+ ::std::pair<RowMap::iterator, bool> r = maRowMap.insert(RowMap::value_type(nXclRow, p));
+ itr = r.first;
+ }
+ return *itr->second;
+}
+
+// ============================================================================
+// Cell Table
+// ============================================================================
+
+XclExpCellTable::XclExpCellTable( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ maColInfoBfr( rRoot ),
+ maRowBfr( rRoot ),
+ maArrayBfr( rRoot ),
+ maShrfmlaBfr( rRoot ),
+ maTableopBfr( rRoot ),
+ mxDefrowheight( new XclExpDefrowheight ),
+ mxGuts( new XclExpGuts( rRoot ) ),
+ mxNoteList( new XclExpNoteList ),
+ mxMergedcells( new XclExpMergedcells( rRoot ) ),
+ mxHyperlinkList( new XclExpHyperlinkList ),
+ mxDval( new XclExpDval( rRoot ) )
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+ SvNumberFormatter& rFormatter = GetFormatter();
+
+ // maximum sheet limits
+ SCCOL nMaxScCol = GetMaxPos().Col();
+ SCROW nMaxScRow = GetMaxPos().Row();
+
+ // find used area (non-empty cells)
+ SCCOL nLastUsedScCol;
+ SCROW nLastUsedScRow;
+ rDoc.GetTableArea( nScTab, nLastUsedScCol, nLastUsedScRow );
+
+ ScRange aUsedRange( 0, 0, nScTab, nLastUsedScCol, nLastUsedScRow, nScTab );
+ GetAddressConverter().ValidateRange( aUsedRange, true );
+ nLastUsedScCol = aUsedRange.aEnd.Col();
+ nLastUsedScRow = aUsedRange.aEnd.Row();
+
+ // first row without any set attributes (height/hidden/...)
+ SCROW nFirstUnflaggedScRow = rDoc.GetLastFlaggedRow( nScTab ) + 1;
+
+ // find range of outlines
+ SCROW nFirstUngroupedScRow = 0;
+ if( const ScOutlineTable* pOutlineTable = rDoc.GetOutlineTable( nScTab ) )
+ {
+ SCCOLROW nScStartPos, nScEndPos;
+ if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
+ {
+ pRowArray->GetRange( nScStartPos, nScEndPos );
+ // +1 because open/close button is in next row in Excel, +1 for "end->first unused"
+ nFirstUngroupedScRow = static_cast< SCROW >( nScEndPos + 2 );
+ }
+ }
+
+ // column settings
+ /* #i30411# Files saved with SO7/OOo1.x with nonstandard default column
+ formatting cause big Excel files, because all rows from row 1 to row
+ 32000 are exported. Now, if the used area goes exactly to row 32000,
+ use this row as default and ignore all rows >32000.
+ #i59220# Tolerance of +-128 rows for inserted/removed rows. */
+ if( (31871 <= nLastUsedScRow) && (nLastUsedScRow <= 32127) && (nFirstUnflaggedScRow < nLastUsedScRow) && (nFirstUngroupedScRow <= nLastUsedScRow) )
+ nMaxScRow = nLastUsedScRow;
+ maColInfoBfr.Initialize( nMaxScRow );
+
+ // range for cell iterator
+ SCCOL nLastIterScCol = nMaxScCol;
+ SCROW nLastIterScRow = ulimit_cast< SCROW >( nLastUsedScRow, nMaxScRow );
+ ScUsedAreaIterator aIt( &rDoc, nScTab, 0, 0, nLastIterScCol, nLastIterScRow );
+
+ // activate the correct segment and sub segment at the progress bar
+ GetProgressBar().ActivateCreateRowsSegment();
+
+ for( bool bIt = aIt.GetNext(); bIt; bIt = aIt.GetNext() )
+ {
+ SCCOL nScCol = aIt.GetStartCol();
+ SCROW nScRow = aIt.GetRow();
+ SCCOL nLastScCol = aIt.GetEndCol();
+ ScAddress aScPos( nScCol, nScRow, nScTab );
+
+ XclAddress aXclPos( static_cast< sal_uInt16 >( nScCol ), static_cast< sal_uInt32 >( nScRow ) );
+ sal_uInt16 nLastXclCol = static_cast< sal_uInt16 >( nLastScCol );
+
+ const ScBaseCell* pScCell = aIt.GetCell();
+ XclExpCellRef xCell;
+
+ const ScPatternAttr* pPattern = aIt.GetPattern();
+
+ // handle overlapped merged cells before creating the cell record
+ sal_uInt32 nMergeBaseXFId = EXC_XFID_NOTFOUND;
+ bool bIsMergedBase = false;
+ if( pPattern )
+ {
+ const SfxItemSet& rItemSet = pPattern->GetItemSet();
+ // base cell in a merged range
+ const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
+ bIsMergedBase = rMergeItem.IsMerged();
+ /* overlapped cell in a merged range; in Excel all merged cells
+ must contain same XF index, for correct border */
+ const ScMergeFlagAttr& rMergeFlagItem = GETITEM( rItemSet, ScMergeFlagAttr, ATTR_MERGE_FLAG );
+ if( rMergeFlagItem.IsOverlapped() )
+ nMergeBaseXFId = mxMergedcells->GetBaseXFId( aScPos );
+ }
+
+ String aAddNoteText; // additional text to be appended to a note
+
+ CellType eCellType = pScCell ? pScCell->GetCellType() : CELLTYPE_NONE;
+ switch( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ {
+ double fValue = static_cast< const ScValueCell* >( pScCell )->GetValue();
+
+ // try to create a Boolean cell
+ if( pPattern && ((fValue == 0.0) || (fValue == 1.0)) )
+ {
+ sal_uLong nScNumFmt = GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong );
+ if( rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL )
+ xCell.reset( new XclExpBooleanCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue != 0.0 ) );
+ }
+
+ // try to create an RK value (compressed floating-point number)
+ sal_Int32 nRkValue;
+ if( !xCell && XclTools::GetRKFromDouble( nRkValue, fValue ) )
+ xCell.reset( new XclExpRkCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, nRkValue ) );
+
+ // else: simple floating-point number cell
+ if( !xCell )
+ xCell.reset( new XclExpNumberCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue ) );
+ }
+ break;
+
+ case CELLTYPE_STRING:
+ {
+ const ScStringCell& rScStrCell = *static_cast< const ScStringCell* >( pScCell );
+ xCell.reset( new XclExpLabelCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScStrCell ) );
+ }
+ break;
+
+ case CELLTYPE_EDIT:
+ {
+ const ScEditCell& rScEditCell = *static_cast< const ScEditCell* >( pScCell );
+ XclExpHyperlinkHelper aLinkHelper( GetRoot(), aScPos );
+ xCell.reset( new XclExpLabelCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScEditCell, aLinkHelper ) );
+
+ // add a single created HLINK record to the record list
+ if( aLinkHelper.HasLinkRecord() )
+ mxHyperlinkList->AppendRecord( aLinkHelper.GetLinkRecord() );
+ // add list of multiple URLs to the additional cell note text
+ if( aLinkHelper.HasMultipleUrls() )
+ ScGlobal::AddToken( aAddNoteText, aLinkHelper.GetUrlList(), '\n', 2 );
+ }
+ break;
+
+ case CELLTYPE_FORMULA:
+ {
+ const ScFormulaCell& rScFmlaCell = *static_cast< const ScFormulaCell* >( pScCell );
+ xCell.reset( new XclExpFormulaCell(
+ GetRoot(), aXclPos, pPattern, nMergeBaseXFId,
+ rScFmlaCell, maArrayBfr, maShrfmlaBfr, maTableopBfr ) );
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclExpCellTable::XclExpCellTable - unknown cell type" );
+ // run-through!
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ {
+ xCell.reset( new XclExpBlankCell(
+ GetRoot(), aXclPos, nLastXclCol, pPattern, nMergeBaseXFId ) );
+ }
+ break;
+ }
+
+ // insert the cell into the current row
+ if( xCell )
+ maRowBfr.AppendCell( xCell, bIsMergedBase );
+
+ // notes
+ const ScPostIt* pScNote = pScCell ? pScCell->GetNote() : 0;
+ if( pScNote || (aAddNoteText.Len() > 0) )
+ mxNoteList->AppendNewRecord( new XclExpNote( GetRoot(), aScPos, pScNote, aAddNoteText ) );
+
+ // other sheet contents
+ if( pPattern )
+ {
+ const SfxItemSet& rItemSet = pPattern->GetItemSet();
+
+ // base cell in a merged range
+ if( bIsMergedBase )
+ {
+ const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
+ ScRange aScRange( aScPos );
+ aScRange.aEnd.IncCol( rMergeItem.GetColMerge() - 1 );
+ aScRange.aEnd.IncRow( rMergeItem.GetRowMerge() - 1 );
+ sal_uInt32 nXFId = xCell ? xCell->GetFirstXFId() : EXC_XFID_NOTFOUND;
+ // blank cells merged vertically may occur repeatedly
+ DBG_ASSERT( (aScRange.aStart.Col() == aScRange.aEnd.Col()) || (nScCol == nLastScCol),
+ "XclExpCellTable::XclExpCellTable - invalid repeated blank merged cell" );
+ for( SCCOL nIndex = nScCol; nIndex <= nLastScCol; ++nIndex )
+ {
+ mxMergedcells->AppendRange( aScRange, nXFId );
+ aScRange.aStart.IncCol();
+ aScRange.aEnd.IncCol();
+ }
+ }
+
+ // data validation
+ if( ScfTools::CheckItem( rItemSet, ATTR_VALIDDATA, false ) )
+ {
+ sal_uLong nScHandle = GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALIDDATA, sal_uLong );
+ ScRange aScRange( aScPos );
+ aScRange.aEnd.SetCol( nLastScCol );
+ mxDval->InsertCellRange( aScRange, nScHandle );
+ }
+ }
+ }
+
+ // create missing row settings for rows anyhow flagged or with outlines
+ maRowBfr.CreateRows( ::std::max( nFirstUnflaggedScRow, nFirstUngroupedScRow ) );
+}
+
+void XclExpCellTable::Finalize()
+{
+ // Finalize multiple operations.
+ maTableopBfr.Finalize();
+
+ /* Finalize column buffer. This calculates column default XF indexes from
+ the XF identifiers and fills a vector with these XF indexes. */
+ ScfUInt16Vec aColXFIndexes;
+ maColInfoBfr.Finalize( aColXFIndexes );
+
+ /* Finalize row buffer. This calculates all cell XF indexes from the XF
+ identifiers. Then the XF index vector aColXFIndexes (filled above) is
+ used to calculate the row default formats. With this, all unneeded blank
+ cell records (equal to row default or column default) will be removed.
+ The function returns the (most used) default row format in aDefRowData. */
+ XclExpDefaultRowData aDefRowData;
+ maRowBfr.Finalize( aDefRowData, aColXFIndexes );
+
+ // Initialize the DEFROWHEIGHT record.
+ mxDefrowheight->SetDefaultData( aDefRowData );
+}
+
+XclExpRecordRef XclExpCellTable::CreateRecord( sal_uInt16 nRecId ) const
+{
+ XclExpRecordRef xRec;
+ switch( nRecId )
+ {
+ case EXC_ID3_DIMENSIONS: xRec.reset( new XclExpDelegatingRecord( const_cast<XclExpRowBuffer*>(&maRowBfr)->GetDimensions() ) ); break;
+ case EXC_ID2_DEFROWHEIGHT: xRec = mxDefrowheight; break;
+ case EXC_ID_GUTS: xRec = mxGuts; break;
+ case EXC_ID_NOTE: xRec = mxNoteList; break;
+ case EXC_ID_MERGEDCELLS: xRec = mxMergedcells; break;
+ case EXC_ID_HLINK: xRec = mxHyperlinkList; break;
+ case EXC_ID_DVAL: xRec = mxDval; break;
+ default: DBG_ERRORFILE( "XclExpCellTable::CreateRecord - unknown record id" );
+ }
+ return xRec;
+}
+
+void XclExpCellTable::Save( XclExpStream& rStrm )
+{
+ // DEFCOLWIDTH and COLINFOs
+ maColInfoBfr.Save( rStrm );
+ // ROWs and cell records
+ maRowBfr.Save( rStrm );
+}
+
+void XclExpCellTable::SaveXml( XclExpXmlStream& rStrm )
+{
+ maColInfoBfr.SaveXml( rStrm );
+ maRowBfr.SaveXml( rStrm );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xeview.cxx b/sc/source/filter/excel/xeview.cxx
new file mode 100644
index 000000000000..31c149135f49
--- /dev/null
+++ b/sc/source/filter/excel/xeview.cxx
@@ -0,0 +1,540 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xeview.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "viewopti.hxx"
+#include "xelink.hxx"
+#include "xestyle.hxx"
+
+using namespace ::oox;
+
+using ::rtl::OString;
+
+// Workbook view settings records =============================================
+
+XclExpWindow1::XclExpWindow1( const XclExpRoot& rRoot ) :
+ XclExpRecord( EXC_ID_WINDOW1, 18 ),
+ mnFlags( 0 ),
+ mnTabBarSize( 600 )
+{
+ const ScViewOptions& rViewOpt = rRoot.GetDoc().GetViewOptions();
+ ::set_flag( mnFlags, EXC_WIN1_HOR_SCROLLBAR, rViewOpt.GetOption( VOPT_HSCROLL ) );
+ ::set_flag( mnFlags, EXC_WIN1_VER_SCROLLBAR, rViewOpt.GetOption( VOPT_VSCROLL ) );
+ ::set_flag( mnFlags, EXC_WIN1_TABBAR, rViewOpt.GetOption( VOPT_TABCONTROLS ) );
+
+ double fTabBarWidth = rRoot.GetExtDocOptions().GetDocSettings().mfTabBarWidth;
+ if( (0.0 <= fTabBarWidth) && (fTabBarWidth <= 1.0) )
+ mnTabBarSize = static_cast< sal_uInt16 >( fTabBarWidth * 1000.0 + 0.5 );
+}
+
+void XclExpWindow1::SaveXml( XclExpXmlStream& rStrm )
+{
+ const XclExpTabInfo& rTabInfo = rStrm.GetRoot().GetTabInfo();
+
+ rStrm.GetCurrentStream()->singleElement( XML_workbookView,
+ // OOXTODO: XML_visibility, // ST_visibilty
+ // OOXTODO: XML_minimized, // bool
+ XML_showHorizontalScroll, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_HOR_SCROLLBAR ) ),
+ XML_showVerticalScroll, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_VER_SCROLLBAR ) ),
+ XML_showSheetTabs, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_WIN1_TABBAR ) ),
+ XML_xWindow, "0",
+ XML_yWindow, "0",
+ XML_windowWidth, OString::valueOf( (sal_Int32)0x4000 ).getStr(),
+ XML_windowHeight, OString::valueOf( (sal_Int32)0x2000 ).getStr(),
+ XML_tabRatio, OString::valueOf( (sal_Int32)mnTabBarSize ).getStr(),
+ XML_firstSheet, OString::valueOf( (sal_Int32)rTabInfo.GetFirstVisXclTab() ).getStr(),
+ XML_activeTab, OString::valueOf( (sal_Int32)rTabInfo.GetDisplayedXclTab() ).getStr(),
+ // OOXTODO: XML_autoFilterDateGrouping, // bool; AUTOFILTER12? 87Eh
+ FSEND );
+}
+
+void XclExpWindow1::WriteBody( XclExpStream& rStrm )
+{
+ const XclExpTabInfo& rTabInfo = rStrm.GetRoot().GetTabInfo();
+
+ rStrm << sal_uInt16( 0 ) // X position of the window
+ << sal_uInt16( 0 ) // Y position of the window
+ << sal_uInt16( 0x4000 ) // width of the window
+ << sal_uInt16( 0x2000 ) // height of the window
+ << mnFlags
+ << rTabInfo.GetDisplayedXclTab()
+ << rTabInfo.GetFirstVisXclTab()
+ << rTabInfo.GetXclSelectedCount()
+ << mnTabBarSize;
+}
+
+// Sheet view settings records ================================================
+
+XclExpWindow2::XclExpWindow2( const XclExpRoot& rRoot,
+ const XclTabViewData& rData, sal_uInt32 nGridColorId ) :
+ XclExpRecord( EXC_ID_WINDOW2, (rRoot.GetBiff() == EXC_BIFF8) ? 18 : 10 ),
+ maGridColor( rData.maGridColor ),
+ mnGridColorId( nGridColorId ),
+ mnFlags( 0 ),
+ maFirstXclPos( rData.maFirstXclPos ),
+ mnNormalZoom( rData.mnNormalZoom ),
+ mnPageZoom( rData.mnPageZoom )
+{
+ ::set_flag( mnFlags, EXC_WIN2_SHOWFORMULAS, rData.mbShowFormulas );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWGRID, rData.mbShowGrid );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWHEADINGS, rData.mbShowHeadings );
+ ::set_flag( mnFlags, EXC_WIN2_FROZEN, rData.mbFrozenPanes );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWZEROS, rData.mbShowZeros );
+ ::set_flag( mnFlags, EXC_WIN2_DEFGRIDCOLOR, rData.mbDefGridColor );
+ ::set_flag( mnFlags, EXC_WIN2_MIRRORED, rData.mbMirrored );
+ ::set_flag( mnFlags, EXC_WIN2_SHOWOUTLINE, rData.mbShowOutline );
+ ::set_flag( mnFlags, EXC_WIN2_FROZENNOSPLIT, rData.mbFrozenPanes );
+ ::set_flag( mnFlags, EXC_WIN2_SELECTED, rData.mbSelected );
+ ::set_flag( mnFlags, EXC_WIN2_DISPLAYED, rData.mbDisplayed );
+ ::set_flag( mnFlags, EXC_WIN2_PAGEBREAKMODE, rData.mbPageMode );
+}
+
+void XclExpWindow2::WriteBody( XclExpStream& rStrm )
+{
+ const XclExpRoot& rRoot = rStrm.GetRoot();
+
+ rStrm << mnFlags
+ << maFirstXclPos;
+
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ rStrm << maGridColor;
+ break;
+ case EXC_BIFF8:
+ rStrm << rRoot.GetPalette().GetColorIndex( mnGridColorId )
+ << sal_uInt16( 0 )
+ << mnPageZoom
+ << mnNormalZoom
+ << sal_uInt32( 0 );
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpScl::XclExpScl( sal_uInt16 nZoom ) :
+ XclExpRecord( EXC_ID_SCL, 4 ),
+ mnNum( nZoom ),
+ mnDenom( 100 )
+{
+ Shorten( 2 );
+ Shorten( 5 );
+}
+
+void XclExpScl::Shorten( sal_uInt16 nFactor )
+{
+ while( (mnNum % nFactor == 0) && (mnDenom % nFactor == 0) )
+ {
+ mnNum = mnNum / nFactor;
+ mnDenom = mnDenom / nFactor;
+ }
+}
+
+void XclExpScl::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF4 );
+ rStrm << mnNum << mnDenom;
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpPane::XclExpPane( const XclTabViewData& rData ) :
+ XclExpRecord( EXC_ID_PANE, 10 ),
+ mnSplitX( rData.mnSplitX ),
+ mnSplitY( rData.mnSplitY ),
+ maSecondXclPos( rData.maSecondXclPos ),
+ mnActivePane( rData.mnActivePane )
+{
+ DBG_ASSERT( rData.IsSplit(), "XclExpPane::XclExpPane - no PANE record for unsplit view" );
+}
+
+static const char* lcl_GetActivePane( sal_uInt8 nActivePane )
+{
+ switch( nActivePane )
+ {
+ case EXC_PANE_TOPLEFT: return "topLeft"; //break;
+ case EXC_PANE_TOPRIGHT: return "topRight"; //break;
+ case EXC_PANE_BOTTOMLEFT: return "bottomLeft"; //break;
+ case EXC_PANE_BOTTOMRIGHT: return "bottomRight"; //break;
+ }
+ return "**error: lcl_GetActivePane";
+}
+
+void XclExpPane::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_pane,
+ XML_xSplit, OString::valueOf( (sal_Int32)mnSplitX ).getStr(),
+ XML_ySplit, OString::valueOf( (sal_Int32)mnSplitY ).getStr(),
+ XML_topLeftCell, XclXmlUtils::ToOString( maSecondXclPos ).getStr(),
+ XML_activePane, lcl_GetActivePane( mnActivePane ),
+ // OOXTODO: XML_state,
+ FSEND );
+}
+
+void XclExpPane::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnSplitX
+ << static_cast<sal_uInt16>( mnSplitY )
+ << maSecondXclPos
+ << mnActivePane;
+ if( rStrm.GetRoot().GetBiff() >= EXC_BIFF5 )
+ rStrm << sal_uInt8( 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpSelection::XclExpSelection( const XclTabViewData& rData, sal_uInt8 nPane ) :
+ XclExpRecord( EXC_ID_SELECTION, 15 ),
+ mnPane( nPane )
+{
+ if( const XclSelectionData* pSelData = rData.GetSelectionData( nPane ) )
+ maSelData = *pSelData;
+
+ // find the cursor position in the selection list (or add it)
+ XclRangeList& rXclSel = maSelData.maXclSelection;
+ bool bFound = false;
+ for( XclRangeList::const_iterator aIt = rXclSel.begin(), aEnd = rXclSel.end(); !bFound && (aIt != aEnd); ++aIt )
+ if( (bFound = aIt->Contains( maSelData.maXclCursor )) == true )
+ maSelData.mnCursorIdx = static_cast< sal_uInt16 >( aIt - rXclSel.begin() );
+ /* Cursor cell not found in list? (e.g. inactive pane, or removed in
+ ConvertRangeList(), because Calc cursor on invalid pos)
+ -> insert the valid Excel cursor. */
+ if( !bFound )
+ {
+ maSelData.mnCursorIdx = static_cast< sal_uInt16 >( rXclSel.size() );
+ rXclSel.push_back( XclRange( maSelData.maXclCursor ) );
+ }
+}
+
+void XclExpSelection::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_selection,
+ XML_pane, lcl_GetActivePane( mnPane ),
+ XML_activeCell, XclXmlUtils::ToOString( maSelData.maXclCursor ).getStr(),
+ XML_activeCellId, OString::valueOf( (sal_Int32) maSelData.mnCursorIdx ).getStr(),
+ XML_sqref, XclXmlUtils::ToOString( maSelData.maXclSelection ).getStr(),
+ FSEND );
+}
+
+void XclExpSelection::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << mnPane // pane for this selection
+ << maSelData.maXclCursor // cell cursor
+ << maSelData.mnCursorIdx; // index to range containing cursor
+ maSelData.maXclSelection.Write( rStrm, false );
+}
+
+// ----------------------------------------------------------------------------
+
+XclExpTabBgColor::XclExpTabBgColor( const XclTabViewData& rTabViewData ) :
+ XclExpRecord( EXC_ID_SHEETEXT, 18 ),
+ mrTabViewData( rTabViewData )
+{
+}
+//TODO Fix savexml...
+/*void XclExpTabBgColor::SaveXml( XclExpXmlStream& rStrm )
+{
+}*/
+
+void XclExpTabBgColor::WriteBody( XclExpStream& rStrm )
+{
+ if ( mrTabViewData.IsDefaultTabBgColor() )
+ return;
+ sal_uInt16 rt = 0x0862; //rt
+ sal_uInt16 grbitFrt = 0x0000; //grbit must be set to 0
+ sal_uInt32 unused = 0x00000000; //Use twice...
+ sal_uInt32 cb = 0x00000014; // Record Size, may be larger in future...
+ sal_uInt16 reserved = 0x0000; //trailing bits are 0
+ sal_uInt16 TabBgColorIndex;
+ XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
+ TabBgColorIndex = rPal.GetColorIndex(mrTabViewData.mnTabBgColorId);
+ if (TabBgColorIndex < 8 || TabBgColorIndex > 63 ) // only numbers 8 - 63 are valid numbers
+ TabBgColorIndex = 127; //Excel specs: 127 makes excel ignore tab color information.
+ rStrm << rt << grbitFrt << unused << unused << cb << TabBgColorIndex << reserved;
+}
+
+// Sheet view settings ========================================================
+
+namespace {
+
+/** Converts a Calc zoom factor into an Excel zoom factor. Returns 0 for a default zoom value. */
+sal_uInt16 lclGetXclZoom( long nScZoom, sal_uInt16 nDefXclZoom )
+{
+ sal_uInt16 nXclZoom = limit_cast< sal_uInt16 >( nScZoom, EXC_ZOOM_MIN, EXC_ZOOM_MAX );
+ return (nXclZoom == nDefXclZoom) ? 0 : nXclZoom;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclExpTabViewSettings::XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nScTab ) :
+ XclExpRoot( rRoot ),
+ mnGridColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT ) )
+{
+ // *** sheet flags ***
+
+ const XclExpTabInfo& rTabInfo = GetTabInfo();
+ maData.mbSelected = rTabInfo.IsSelectedTab( nScTab );
+ maData.mbDisplayed = rTabInfo.IsDisplayedTab( nScTab );
+ maData.mbMirrored = rTabInfo.IsMirroredTab( nScTab );
+
+ const ScViewOptions& rViewOpt = GetDoc().GetViewOptions();
+ maData.mbShowFormulas = rViewOpt.GetOption( VOPT_FORMULAS );
+ maData.mbShowHeadings = rViewOpt.GetOption( VOPT_HEADER );
+ maData.mbShowZeros = rViewOpt.GetOption( VOPT_NULLVALS );
+ maData.mbShowOutline = rViewOpt.GetOption( VOPT_OUTLINER );
+
+ // *** sheet options: cursor, selection, splits, grid color, zoom ***
+
+ if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nScTab ) )
+ {
+ const ScExtTabSettings& rTabSett = *pTabSett;
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+
+ // first visible cell in top-left pane
+ if( (rTabSett.maFirstVis.Col() >= 0) && (rTabSett.maFirstVis.Row() >= 0) )
+ maData.maFirstXclPos = rAddrConv.CreateValidAddress( rTabSett.maFirstVis, false );
+
+ // first visible cell in additional pane(s)
+ if( (rTabSett.maSecondVis.Col() >= 0) && (rTabSett.maSecondVis.Row() >= 0) )
+ maData.maSecondXclPos = rAddrConv.CreateValidAddress( rTabSett.maSecondVis, false );
+
+ // active pane
+ switch( rTabSett.meActivePane )
+ {
+ case SCEXT_PANE_TOPLEFT: maData.mnActivePane = EXC_PANE_TOPLEFT; break;
+ case SCEXT_PANE_TOPRIGHT: maData.mnActivePane = EXC_PANE_TOPRIGHT; break;
+ case SCEXT_PANE_BOTTOMLEFT: maData.mnActivePane = EXC_PANE_BOTTOMLEFT; break;
+ case SCEXT_PANE_BOTTOMRIGHT: maData.mnActivePane = EXC_PANE_BOTTOMRIGHT; break;
+ }
+
+ // freeze/split position
+ maData.mbFrozenPanes = rTabSett.mbFrozenPanes;
+ if( maData.mbFrozenPanes )
+ {
+ /* Frozen panes: handle split position as row/column positions.
+ #i35812# Excel uses number of visible rows/columns, Calc uses position of freeze. */
+ SCCOL nFreezeScCol = rTabSett.maFreezePos.Col();
+ if( (0 < nFreezeScCol) && (nFreezeScCol <= GetXclMaxPos().Col()) )
+ maData.mnSplitX = static_cast< sal_uInt16 >( nFreezeScCol ) - maData.maFirstXclPos.mnCol;
+ SCROW nFreezeScRow = rTabSett.maFreezePos.Row();
+ if( (0 < nFreezeScRow) && (nFreezeScRow <= GetXclMaxPos().Row()) )
+ maData.mnSplitY = static_cast< sal_uInt32 >( nFreezeScRow ) - maData.maFirstXclPos.mnRow;
+ // if both splits are left out (address overflow), remove the frozen flag
+ maData.mbFrozenPanes = maData.IsSplit();
+
+ // #i20671# frozen panes: mostright/mostbottom pane is active regardless of cursor position
+ if( maData.HasPane( EXC_PANE_BOTTOMRIGHT ) )
+ maData.mnActivePane = EXC_PANE_BOTTOMRIGHT;
+ else if( maData.HasPane( EXC_PANE_TOPRIGHT ) )
+ maData.mnActivePane = EXC_PANE_TOPRIGHT;
+ else if( maData.HasPane( EXC_PANE_BOTTOMLEFT ) )
+ maData.mnActivePane = EXC_PANE_BOTTOMLEFT;
+ }
+ else
+ {
+ // split window: position is in twips
+ maData.mnSplitX = ulimit_cast< sal_uInt16 >( rTabSett.maSplitPos.X() );
+ maData.mnSplitY = ulimit_cast< sal_uInt32 >( rTabSett.maSplitPos.Y() );
+ }
+
+ // selection
+ CreateSelectionData( EXC_PANE_TOPLEFT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_TOPRIGHT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_BOTTOMLEFT, rTabSett.maCursor, rTabSett.maSelection );
+ CreateSelectionData( EXC_PANE_BOTTOMRIGHT, rTabSett.maCursor, rTabSett.maSelection );
+
+ // grid color
+ const Color& rGridColor = rTabSett.maGridColor;
+ maData.mbDefGridColor = rGridColor.GetColor() == COL_AUTO;
+ if( !maData.mbDefGridColor )
+ {
+ if( GetBiff() == EXC_BIFF8 )
+ mnGridColorId = GetPalette().InsertColor( rGridColor, EXC_COLOR_GRID );
+ else
+ maData.maGridColor = rGridColor;
+ }
+ maData.mbShowGrid = rTabSett.mbShowGrid;
+
+ // view mode and zoom
+ maData.mbPageMode = (GetBiff() == EXC_BIFF8) && rTabSett.mbPageMode;
+ maData.mnNormalZoom = lclGetXclZoom( rTabSett.mnNormalZoom, EXC_WIN2_NORMALZOOM_DEF );
+ maData.mnPageZoom = lclGetXclZoom( rTabSett.mnPageZoom, EXC_WIN2_PAGEZOOM_DEF );
+ maData.mnCurrentZoom = maData.mbPageMode ? maData.mnPageZoom : maData.mnNormalZoom;
+ }
+
+ // Tab Bg Color
+ if ( GetBiff() == EXC_BIFF8 && !GetDoc().IsDefaultTabBgColor(nScTab) )
+ {
+ XclExpPalette& rPal = GetPalette();
+ maData.maTabBgColor = GetDoc().GetTabBgColor(nScTab);
+ maData.mnTabBgColorId = rPal.InsertColor(maData.maTabBgColor, EXC_COLOR_TABBG, EXC_COLOR_NOTABBG );
+ }
+}
+
+void XclExpTabViewSettings::Save( XclExpStream& rStrm )
+{
+ WriteWindow2( rStrm );
+ WriteScl( rStrm );
+ WritePane( rStrm );
+ WriteSelection( rStrm, EXC_PANE_TOPLEFT );
+ WriteSelection( rStrm, EXC_PANE_TOPRIGHT );
+ WriteSelection( rStrm, EXC_PANE_BOTTOMLEFT );
+ WriteSelection( rStrm, EXC_PANE_BOTTOMRIGHT );
+ WriteTabBgColor( rStrm );
+}
+
+static void lcl_WriteSelection( XclExpXmlStream& rStrm, const XclTabViewData& rData, sal_uInt8 nPane )
+{
+ if( rData.HasPane( nPane ) )
+ XclExpSelection( rData, nPane ).SaveXml( rStrm );
+}
+
+OString lcl_GetZoom( sal_uInt16 nZoom )
+{
+ if( nZoom )
+ return OString::valueOf( (sal_Int32)nZoom );
+ return OString( "100" );
+}
+
+void XclExpTabViewSettings::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+ rWorksheet->startElement( XML_sheetViews, FSEND );
+ rWorksheet->startElement( XML_sheetView,
+ XML_windowProtection, XclXmlUtils::ToPsz( maData.mbFrozenPanes ),
+ XML_showFormulas, XclXmlUtils::ToPsz( maData.mbShowFormulas ),
+ XML_showGridLines, XclXmlUtils::ToPsz( maData.mbShowGrid ),
+ XML_showRowColHeaders, XclXmlUtils::ToPsz( maData.mbShowHeadings ),
+ XML_showZeros, XclXmlUtils::ToPsz( maData.mbShowZeros ),
+ XML_rightToLeft, XclXmlUtils::ToPsz( maData.mbMirrored ),
+ XML_tabSelected, XclXmlUtils::ToPsz( maData.mbSelected ),
+ // OOXTODO: XML_showRuler,
+ XML_showOutlineSymbols, XclXmlUtils::ToPsz( maData.mbShowOutline ),
+ XML_defaultGridColor, mnGridColorId == XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT ) ? "true" : "false",
+ // OOXTODO: XML_showWhiteSpace,
+ XML_view, maData.mbPageMode ? "pageBreakPreview" : "normal", // OOXTODO: pageLayout
+ XML_topLeftCell, XclXmlUtils::ToOString( maData.maFirstXclPos ).getStr(),
+ XML_colorId, OString::valueOf( (sal_Int32) rStrm.GetRoot().GetPalette().GetColorIndex( mnGridColorId ) ).getStr(),
+ XML_zoomScale, lcl_GetZoom( maData.mnCurrentZoom ).getStr(),
+ XML_zoomScaleNormal, lcl_GetZoom( maData.mnNormalZoom ).getStr(),
+ // OOXTODO: XML_zoomScaleSheetLayoutView,
+ XML_zoomScalePageLayoutView, lcl_GetZoom( maData.mnPageZoom ).getStr(),
+ XML_workbookViewId, "0", // OOXTODO? 0-based index of document(xl/workbook.xml)/workbook/bookviews/workbookView
+ // should always be 0, as we only generate 1 such element.
+ FSEND );
+ if( maData.IsSplit() )
+ {
+ XclExpPane aPane( maData );
+ aPane.SaveXml( rStrm );
+ }
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_TOPLEFT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_TOPRIGHT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_BOTTOMLEFT );
+ lcl_WriteSelection( rStrm, maData, EXC_PANE_BOTTOMRIGHT );
+ rWorksheet->endElement( XML_sheetView );
+ // OOXTODO: XML_extLst
+ rWorksheet->endElement( XML_sheetViews );
+}
+
+// private --------------------------------------------------------------------
+
+void XclExpTabViewSettings::CreateSelectionData( sal_uInt8 nPane,
+ const ScAddress& rCursor, const ScRangeList& rSelection )
+{
+ if( maData.HasPane( nPane ) )
+ {
+ XclSelectionData& rSelData = maData.CreateSelectionData( nPane );
+
+ // first step: use top-left visible cell as cursor
+ rSelData.maXclCursor.mnCol = ((nPane == EXC_PANE_TOPLEFT) || (nPane == EXC_PANE_BOTTOMLEFT)) ?
+ maData.maFirstXclPos.mnCol : maData.maSecondXclPos.mnCol;
+ rSelData.maXclCursor.mnRow = ((nPane == EXC_PANE_TOPLEFT) || (nPane == EXC_PANE_TOPRIGHT)) ?
+ maData.maFirstXclPos.mnRow : maData.maSecondXclPos.mnRow;
+
+ // second step, active pane: create actual selection data with current cursor position
+ if( nPane == maData.mnActivePane )
+ {
+ XclExpAddressConverter& rAddrConv = GetAddressConverter();
+ // cursor position (keep top-left pane position from above, if rCursor is invalid)
+ if( (rCursor.Col() >= 0) && (rCursor.Row() >= 0) )
+ rSelData.maXclCursor = rAddrConv.CreateValidAddress( rCursor, false );
+ // selection
+ rAddrConv.ConvertRangeList( rSelData.maXclSelection, rSelection, false );
+ }
+ }
+}
+
+void XclExpTabViewSettings::WriteWindow2( XclExpStream& rStrm ) const
+{
+// #i43553# GCC 3.3 parse error
+// XclExpWindow2( GetRoot(), maData, mnGridColorId ).Save( rStrm );
+ XclExpWindow2 aWindow2( GetRoot(), maData, mnGridColorId );
+ aWindow2.Save( rStrm );
+}
+
+void XclExpTabViewSettings::WriteScl( XclExpStream& rStrm ) const
+{
+ if( maData.mnCurrentZoom != 0 )
+ XclExpScl( maData.mnCurrentZoom ).Save( rStrm );
+}
+
+void XclExpTabViewSettings::WritePane( XclExpStream& rStrm ) const
+{
+ if( maData.IsSplit() )
+// #i43553# GCC 3.3 parse error
+// XclExpPane( GetRoot(), maData ).Save( rStrm );
+ {
+ XclExpPane aPane( maData );
+ aPane.Save( rStrm );
+ }
+}
+
+void XclExpTabViewSettings::WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane ) const
+{
+ if( maData.HasPane( nPane ) )
+ XclExpSelection( maData, nPane ).Save( rStrm );
+}
+
+void XclExpTabViewSettings::WriteTabBgColor( XclExpStream& rStrm ) const
+{
+ if ( !maData.IsDefaultTabBgColor() )
+ XclExpTabBgColor( maData ).Save( rStrm );
+}
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx
new file mode 100644
index 000000000000..0393ad2d45bf
--- /dev/null
+++ b/sc/source/filter/excel/xichart.cxx
@@ -0,0 +1,4332 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xichart.hxx"
+
+#include <algorithm>
+#include <memory>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#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/ChartLegendExpansion.hpp>
+#include <com/sun/star/chart/TimeInterval.hpp>
+#include <com/sun/star/chart/TimeUnit.hpp>
+#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/XDiagram.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/TickmarkStyle.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/RelativeSize.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+
+#include <sfx2/objsh.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/unoapi.hxx>
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "rangeutl.hxx"
+#include "tokenarray.hxx"
+#include "token.hxx"
+#include "compiler.hxx"
+#include "reftokenhelper.hxx"
+#include "chartlis.hxx"
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xiformula.hxx"
+#include "xistyle.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::drawing::XDrawPage;
+using ::com::sun::star::drawing::XDrawPageSupplier;
+using ::com::sun::star::drawing::XShape;
+
+using ::com::sun::star::chart2::IncrementData;
+using ::com::sun::star::chart2::RelativePosition;
+using ::com::sun::star::chart2::RelativeSize;
+using ::com::sun::star::chart2::ScaleData;
+using ::com::sun::star::chart2::SubIncrement;
+using ::com::sun::star::chart2::XAxis;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::chart2::XChartType;
+using ::com::sun::star::chart2::XChartTypeContainer;
+using ::com::sun::star::chart2::XCoordinateSystem;
+using ::com::sun::star::chart2::XCoordinateSystemContainer;
+using ::com::sun::star::chart2::XDataSeries;
+using ::com::sun::star::chart2::XDataSeriesContainer;
+using ::com::sun::star::chart2::XDiagram;
+using ::com::sun::star::chart2::XFormattedString;
+using ::com::sun::star::chart2::XLegend;
+using ::com::sun::star::chart2::XRegressionCurve;
+using ::com::sun::star::chart2::XRegressionCurveContainer;
+using ::com::sun::star::chart2::XScaling;
+using ::com::sun::star::chart2::XTitle;
+using ::com::sun::star::chart2::XTitled;
+
+using ::com::sun::star::chart2::data::XDataProvider;
+using ::com::sun::star::chart2::data::XDataReceiver;
+using ::com::sun::star::chart2::data::XDataSequence;
+using ::com::sun::star::chart2::data::XDataSink;
+using ::com::sun::star::chart2::data::XLabeledDataSequence;
+
+using ::formula::FormulaToken;
+using ::formula::StackVar;
+using ::boost::shared_ptr;
+using ::std::pair;
+using ::std::auto_ptr;
+
+namespace cssc = ::com::sun::star::chart;
+namespace cssc2 = ::com::sun::star::chart2;
+
+// Helpers ====================================================================
+
+namespace {
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclChRectangle& rRect )
+{
+ return rStrm >> rRect.mnX >> rRect.mnY >> rRect.mnWidth >> rRect.mnHeight;
+}
+
+inline void lclSetValueOrClearAny( Any& rAny, double fValue, bool bClear )
+{
+ if( bClear )
+ rAny.clear();
+ else
+ rAny <<= fValue;
+}
+
+void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bClear )
+{
+ if( !bClear && bLogScale )
+ fValue = pow( 10.0, fValue );
+ lclSetValueOrClearAny( rAny, fValue, bClear );
+}
+
+double lclGetSerialDay( const XclImpRoot& rRoot, sal_uInt16 nValue, sal_uInt16 nTimeUnit )
+{
+ switch( nTimeUnit )
+ {
+ case EXC_CHDATERANGE_DAYS:
+ return nValue;
+ case EXC_CHDATERANGE_MONTHS:
+ return rRoot.GetDoubleFromDateTime( Date( 1, static_cast< sal_uInt16 >( 1 + nValue % 12 ), static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue / 12 ) ) );
+ case EXC_CHDATERANGE_YEARS:
+ return rRoot.GetDoubleFromDateTime( Date( 1, 1, static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue ) ) );
+ default:
+ OSL_ENSURE( false, "lclGetSerialDay - unexpected time unit" );
+ }
+ return nValue;
+}
+
+void lclConvertTimeValue( const XclImpRoot& rRoot, Any& rAny, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
+{
+ if( bAuto )
+ rAny.clear();
+ else
+ rAny <<= lclGetSerialDay( rRoot, nValue, nTimeUnit );
+}
+
+sal_Int32 lclGetApiTimeUnit( sal_uInt16 nTimeUnit )
+{
+ switch( nTimeUnit )
+ {
+ case EXC_CHDATERANGE_DAYS: return cssc::TimeUnit::DAY;
+ case EXC_CHDATERANGE_MONTHS: return cssc::TimeUnit::MONTH;
+ case EXC_CHDATERANGE_YEARS: return cssc::TimeUnit::YEAR;
+ default: OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
+ }
+ return cssc::TimeUnit::DAY;
+}
+
+void lclConvertTimeInterval( Any& rInterval, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
+{
+ if( bAuto || (nValue == 0) )
+ rInterval.clear();
+ else
+ rInterval <<= cssc::TimeInterval( nValue, lclGetApiTimeUnit( nTimeUnit ) );
+}
+
+} // namespace
+
+// Common =====================================================================
+
+/** Stores global data needed in various classes of the Chart import filter. */
+struct XclImpChRootData : public XclChRootData
+{
+ XclImpChChart& mrChartData; /// The chart data object.
+
+ inline explicit XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) :
+ XclImpRoot( rRoot ),
+ mxChData( new XclImpChRootData( rChartData ) )
+{
+}
+
+XclImpChRoot::~XclImpChRoot()
+{
+}
+
+XclImpChChart& XclImpChRoot::GetChartData() const
+{
+ return mxChData->mrChartData;
+}
+
+const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
+}
+
+const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const
+{
+ return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId );
+}
+
+const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
+}
+
+Color XclImpChRoot::GetFontAutoColor() const
+{
+ return GetPalette().GetColor( EXC_COLOR_CHWINDOWTEXT );
+}
+
+Color XclImpChRoot::GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const
+{
+ return GetPalette().GetColor( XclChartHelper::GetSeriesLineAutoColorIdx( nFormatIdx ) );
+}
+
+Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const
+{
+ const XclImpPalette& rPal = GetPalette();
+ Color aColor = rPal.GetColor( XclChartHelper::GetSeriesFillAutoColorIdx( nFormatIdx ) );
+ sal_uInt8 nTrans = XclChartHelper::GetSeriesFillAutoTransp( nFormatIdx );
+ return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans );
+}
+
+void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) const
+{
+ // create formatting object tables
+ mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
+
+ // lock the model to suppress any internal updates
+ Reference< XModel > xModel( xChartDoc, UNO_QUERY );
+ if( xModel.is() )
+ xModel->lockControllers();
+
+ SfxObjectShell* pDocShell = GetDocShell();
+ Reference< XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
+ if( pDocShell && xDataRec.is() )
+ {
+ // create and register a data provider
+ Reference< XDataProvider > xDataProv(
+ ScfApiHelper::CreateInstance( pDocShell, SERVICE_CHART2_DATAPROVIDER ), UNO_QUERY );
+ if( xDataProv.is() )
+ xDataRec->attachDataProvider( xDataProv );
+ // attach the number formatter
+ Reference< XNumberFormatsSupplier > xNumFmtSupp( pDocShell->GetModel(), UNO_QUERY );
+ if( xNumFmtSupp.is() )
+ xDataRec->attachNumberFormatsSupplier( xNumFmtSupp );
+ }
+}
+
+void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
+{
+ rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
+ // unlock the model
+ Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY );
+ if( xModel.is() )
+ xModel->unlockControllers();
+ rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
+
+ mxChData->FinishConversion();
+}
+
+Reference< XDataProvider > XclImpChRoot::GetDataProvider() const
+{
+ return mxChData->mxChartDoc->getDataProvider();
+}
+
+Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const
+{
+ return mxChData->GetTitleShape( rTitleKey );
+}
+
+sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const
+{
+ return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 );
+}
+
+sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const
+{
+ return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 );
+}
+
+::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const
+{
+ return ::com::sun::star::awt::Rectangle(
+ CalcHmmFromChartX( rRect.mnX ),
+ CalcHmmFromChartY( rRect.mnY ),
+ CalcHmmFromChartX( rRect.mnWidth ),
+ CalcHmmFromChartY( rRect.mnHeight ) );
+}
+
+double XclImpChRoot::CalcRelativeFromHmmX( sal_Int32 nPosX ) const
+{
+ return static_cast< double >( nPosX ) / mxChData->maChartRect.GetWidth();
+}
+
+double XclImpChRoot::CalcRelativeFromHmmY( sal_Int32 nPosY ) const
+{
+ return static_cast< double >( nPosY ) / mxChData->maChartRect.GetHeight();
+}
+
+double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const
+{
+ return CalcRelativeFromHmmX( CalcHmmFromChartX( nPosX ) );
+}
+
+double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const
+{
+ return CalcRelativeFromHmmY( CalcHmmFromChartY( nPosY ) );
+}
+
+void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet,
+ const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteLineProperties(
+ rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteAreaProperties( rPropSet, rAreaFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet,
+ const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode ) const
+{
+ GetChartPropSetHelper().WriteEscherProperties( rPropSet,
+ *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable,
+ rEscherFmt, rPicFmt, ePropMode );
+}
+
+void XclImpChRoot::ConvertFont( ScfPropertySet& rPropSet,
+ sal_uInt16 nFontIdx, const Color* pFontColor ) const
+{
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CHART, nFontIdx, pFontColor );
+}
+
+void XclImpChRoot::ConvertPieRotation( ScfPropertySet& rPropSet, sal_uInt16 nAngle )
+{
+ sal_Int32 nApiRot = (450 - (nAngle % 360)) % 360;
+ rPropSet.SetProperty( EXC_CHPROP_STARTINGANGLE, nApiRot );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChGroupBase::~XclImpChGroupBase()
+{
+}
+
+void XclImpChGroupBase::ReadRecordGroup( XclImpStream& rStrm )
+{
+ // read contents of the header record
+ ReadHeaderRecord( rStrm );
+
+ // only read sub records, if the next record is a CHBEGIN
+ if( rStrm.GetNextRecId() == EXC_ID_CHBEGIN )
+ {
+ // read the CHBEGIN record, may be used for special initial processing
+ rStrm.StartNextRecord();
+ ReadSubRecord( rStrm );
+
+ // read the nested records
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_CHEND;
+ // skip unsupported nested blocks
+ if( nRecId == EXC_ID_CHBEGIN )
+ SkipBlock( rStrm );
+ else
+ ReadSubRecord( rStrm );
+ }
+ }
+ /* Returns with current CHEND record or unchanged stream, if no record
+ group present. In every case another call to StartNextRecord() will go
+ to next record of interest. */
+}
+
+void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecId() == EXC_ID_CHBEGIN, "XclImpChGroupBase::SkipBlock - no CHBEGIN record" );
+ // do nothing if current record is not CHBEGIN
+ bool bLoop = rStrm.GetRecId() == EXC_ID_CHBEGIN;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_CHEND;
+ // skip nested record groups
+ if( nRecId == EXC_ID_CHBEGIN )
+ SkipBlock( rStrm );
+ }
+}
+
+// Frame formatting ===========================================================
+
+void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnTLMode >> maData.mnBRMode;
+ /* According to the spec, the upper 16 bits of all members in the
+ rectangle are unused and may contain garbage. */
+ maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+ maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChLineFormat::ReadChLineFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maColor >> maData.mnPattern >> maData.mnWeight >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ // BIFF8: index into palette used instead of RGB data
+ maData.maColor = rRoot.GetPalette().GetColor( rStrm.ReaduInt16() );
+}
+
+void XclImpChLineFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( IsAuto() )
+ {
+ XclChLineFormat aLineFmt;
+ aLineFmt.maColor = (eObjType == EXC_CHOBJTYPE_LINEARSERIES) ?
+ rRoot.GetSeriesLineAutoColor( nFormatIdx ) :
+ rRoot.GetPalette().GetColor( rFmtInfo.mnAutoLineColorIdx );
+ aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ aLineFmt.mnWeight = rFmtInfo.mnAutoLineWeight;
+ rRoot.ConvertLineFormat( rPropSet, aLineFmt, rFmtInfo.mePropMode );
+ }
+ else
+ {
+ rRoot.ConvertLineFormat( rPropSet, maData, rFmtInfo.mePropMode );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChAreaFormat::ReadChAreaFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maPattColor >> maData.maBackColor >> maData.mnPattern >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ {
+ // BIFF8: index into palette used instead of RGB data
+ const XclImpPalette& rPal = rRoot.GetPalette();
+ maData.maPattColor = rPal.GetColor( rStrm.ReaduInt16() );
+ maData.maBackColor = rPal.GetColor( rStrm.ReaduInt16());
+ }
+}
+
+void XclImpChAreaFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ if( IsAuto() )
+ {
+ XclChAreaFormat aAreaFmt;
+ aAreaFmt.maPattColor = (eObjType == EXC_CHOBJTYPE_FILLEDSERIES) ?
+ rRoot.GetSeriesFillAutoColor( nFormatIdx ) :
+ rRoot.GetPalette().GetColor( rFmtInfo.mnAutoPattColorIdx );
+ aAreaFmt.mnPattern = EXC_PATT_SOLID;
+ rRoot.ConvertAreaFormat( rPropSet, aAreaFmt, rFmtInfo.mePropMode );
+ }
+ else
+ {
+ rRoot.ConvertAreaFormat( rPropSet, maData, rFmtInfo.mePropMode );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot )
+{
+ maData.mxItemSet.reset(
+ new SfxItemSet( rRoot.GetDoc().GetDrawLayer()->GetItemPool() ) );
+}
+
+void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ // read from stream - CHESCHERFORMAT uses own ID for record continuation
+ XclImpDffPropSet aPropSet( rStrm.GetRoot() );
+ rStrm.ResetRecord( true, rStrm.GetRecId() );
+ rStrm >> aPropSet;
+ // get the data
+ aPropSet.FillToItemSet( *maData.mxItemSet );
+ // get bitmap mode from DFF item set
+ sal_uInt32 nType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+ maPicFmt.mnBmpMode = (nType == mso_fillPicture) ? EXC_CHPICFORMAT_STRETCH : EXC_CHPICFORMAT_STACK;
+}
+
+void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHPICFORMAT:
+ rStrm >> maPicFmt.mnBmpMode >> maPicFmt.mnFormat >> maPicFmt.mnFlags >> maPicFmt.mfScale;
+ break;
+ }
+}
+
+void XclImpChEscherFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
+{
+ const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
+ rRoot.ConvertEscherFormat( rPropSet, maData, maPicFmt, rFmtInfo.mePropMode );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFrameBase::XclImpChFrameBase( const XclChFormatInfo& rFmtInfo )
+{
+ if( rFmtInfo.mbCreateDefFrame ) switch( rFmtInfo.meDefFrameType )
+ {
+ case EXC_CHFRAMETYPE_AUTO:
+ mxLineFmt.reset( new XclImpChLineFormat );
+ if( rFmtInfo.mbIsFrame )
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ break;
+ case EXC_CHFRAMETYPE_INVISIBLE:
+ {
+ XclChLineFormat aLineFmt;
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
+ aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
+ if( rFmtInfo.mbIsFrame )
+ {
+ XclChAreaFormat aAreaFmt;
+ ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
+ aAreaFmt.mnPattern = EXC_PATT_NONE;
+ mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpChFrameBase::XclImpChFrameBase - unknown frame type" );
+ }
+}
+
+void XclImpChFrameBase::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHLINEFORMAT:
+ mxLineFmt.reset( new XclImpChLineFormat );
+ mxLineFmt->ReadChLineFormat( rStrm );
+ break;
+ case EXC_ID_CHAREAFORMAT:
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ mxAreaFmt->ReadChAreaFormat( rStrm );
+ break;
+ case EXC_ID_CHESCHERFORMAT:
+ mxEscherFmt.reset( new XclImpChEscherFormat( rStrm.GetRoot() ) );
+ mxEscherFmt->ReadRecordGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ if( mxLineFmt )
+ mxLineFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
+}
+
+void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
+ {
+ // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto)
+ if( mxEscherFmt )
+ mxEscherFmt->Convert( rRoot, rPropSet, eObjType );
+ else if( mxAreaFmt )
+ mxAreaFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
+ }
+}
+
+void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
+{
+ ConvertLineBase( rRoot, rPropSet, eObjType, nFormatIdx );
+ ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFrame::XclImpChFrame( const XclImpChRoot& rRoot, XclChObjectType eObjType ) :
+ XclImpChFrameBase( rRoot.GetFormatInfo( eObjType ) ),
+ XclImpChRoot( rRoot ),
+ meObjType( eObjType )
+{
+}
+
+void XclImpChFrame::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnFormat >> maData.mnFlags;
+}
+
+void XclImpChFrame::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ const XclImpPalette& rPal = GetPalette();
+
+ if( rLineData.IsVisible() && (!mxLineFmt || !mxLineFmt->HasLine()) )
+ {
+ // line formatting
+ XclChLineFormat aLineFmt;
+ aLineFmt.maColor = rPal.GetColor( rLineData.mnColorIdx );
+ switch( rLineData.mnStyle )
+ {
+ case EXC_OBJ_LINE_SOLID: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; break;
+ case EXC_OBJ_LINE_DASH: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASH; break;
+ case EXC_OBJ_LINE_DOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DOT; break;
+ case EXC_OBJ_LINE_DASHDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOT; break;
+ case EXC_OBJ_LINE_DASHDOTDOT: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOTDOT; break;
+ case EXC_OBJ_LINE_MEDTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS; break;
+ case EXC_OBJ_LINE_DARKTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS; break;
+ case EXC_OBJ_LINE_LIGHTTRANS: aLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS; break;
+ case EXC_OBJ_LINE_NONE: aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE; break;
+ default: aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ }
+ switch( rLineData.mnWidth )
+ {
+ case EXC_OBJ_LINE_HAIR: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR; break;
+ case EXC_OBJ_LINE_THIN: aLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE; break;
+ case EXC_OBJ_LINE_MEDIUM: aLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE; break;
+ case EXC_OBJ_LINE_THICK: aLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE; break;
+ default: aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
+ }
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, rLineData.IsAuto() );
+ mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
+ }
+
+ if( rFillData.IsFilled() && (!mxAreaFmt || !mxAreaFmt->HasArea()) && !mxEscherFmt )
+ {
+ // area formatting
+ XclChAreaFormat aAreaFmt;
+ aAreaFmt.maPattColor = rPal.GetColor( rFillData.mnPattColorIdx );
+ aAreaFmt.maBackColor = rPal.GetColor( rFillData.mnBackColorIdx );
+ aAreaFmt.mnPattern = rFillData.mnPattern;
+ ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, rFillData.IsAuto() );
+ mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
+ }
+}
+
+void XclImpChFrame::Convert( ScfPropertySet& rPropSet ) const
+{
+ ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
+}
+
+// Source links ===============================================================
+
+namespace {
+
+/** Creates a labeled data sequence object, adds link for series title if present. */
+Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
+ XclImpChSourceLinkRef xValueLink, const OUString& rValueRole,
+ const XclImpChSourceLink* pTitleLink = 0 )
+{
+ // create data sequence for values and title
+ Reference< XDataSequence > xValueSeq;
+ if( xValueLink )
+ xValueSeq = xValueLink->CreateDataSequence( rValueRole );
+ Reference< XDataSequence > xTitleSeq;
+ if( pTitleLink )
+ xTitleSeq = pTitleLink->CreateDataSequence( EXC_CHPROP_ROLE_LABEL );
+
+ // create the labeled data sequence, if values or title are present
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ if( xValueSeq.is() || xTitleSeq.is() )
+ xLabeledSeq.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LABELEDDATASEQ ), UNO_QUERY );
+ if( xLabeledSeq.is() )
+ {
+ if( xValueSeq.is() )
+ xLabeledSeq->setValues( xValueSeq );
+ if( xTitleSeq.is() )
+ xLabeledSeq->setLabel( xTitleSeq );
+ }
+ return xLabeledSeq;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+XclImpChSourceLink::~XclImpChSourceLink()
+{
+}
+
+void XclImpChSourceLink::ReadChSourceLink( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnDestType
+ >> maData.mnLinkType
+ >> maData.mnFlags
+ >> maData.mnNumFmtIdx;
+
+ mxTokenArray.reset();
+ if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET )
+ {
+ // read token array
+ XclTokenArray aXclTokArr;
+ rStrm >> aXclTokArr;
+
+ // convert BIFF formula tokens to Calc token array
+ if( const ScTokenArray* pTokens = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aXclTokArr ) )
+ mxTokenArray.reset( pTokens->Clone() );
+ }
+
+ // try to read a following CHSTRING record
+ if( (rStrm.GetNextRecId() == EXC_ID_CHSTRING) && rStrm.StartNextRecord() )
+ {
+ mxString.reset( new XclImpString );
+ rStrm.Ignore( 2 );
+ mxString->Read( rStrm, EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
+ }
+}
+
+void XclImpChSourceLink::SetString( const String& rString )
+{
+ if( !mxString )
+ mxString.reset( new XclImpString );
+ mxString->SetText( rString );
+}
+
+void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec& rFormats )
+{
+ if( mxString )
+ mxString->SetFormats( rFormats );
+}
+
+sal_uInt16 XclImpChSourceLink::GetCellCount() const
+{
+ sal_uInt32 nCellCount = 0;
+ if( mxTokenArray )
+ {
+ mxTokenArray->Reset();
+ for( const FormulaToken* pToken = mxTokenArray->First(); pToken; pToken = mxTokenArray->Next() )
+ {
+ switch( pToken->GetType() )
+ {
+ case ::formula::svSingleRef:
+ case ::formula::svExternalSingleRef:
+ // single cell
+ ++nCellCount;
+ break;
+ case ::formula::svDoubleRef:
+ case ::formula::svExternalDoubleRef:
+ {
+ // cell range
+ const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
+ const ScSingleRefData& rRef1 = rComplexRef.Ref1;
+ const ScSingleRefData& rRef2 = rComplexRef.Ref2;
+ sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
+ sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
+ sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
+ nCellCount += nCols * nRows * nTabs;
+ }
+ break;
+ default: ;
+ }
+ }
+ }
+ return limit_cast< sal_uInt16 >( nCellCount );
+}
+
+void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
+{
+ bool bLinkToSource = ::get_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
+ sal_uInt32 nScNumFmt = bLinkToSource ? GetNumFmtBuffer().GetScFormat( maData.mnNumFmtIdx ) : NUMBERFORMAT_ENTRY_NOT_FOUND;
+ OUString aPropName = bPercent ? EXC_CHPROP_PERCENTAGENUMFMT : EXC_CHPROP_NUMBERFORMAT;
+ if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+ rPropSet.SetProperty( aPropName, static_cast< sal_Int32 >( nScNumFmt ) );
+ else
+ // restore 'link to source' at data point (series may contain manual number format)
+ rPropSet.SetAnyProperty( aPropName, Any() );
+}
+
+Reference< XDataSequence > XclImpChSourceLink::CreateDataSequence( const OUString& rRole ) const
+{
+ Reference< XDataSequence > xDataSeq;
+ Reference< XDataProvider > xDataProv = GetDataProvider();
+ if( xDataProv.is() && mxTokenArray )
+ {
+ ScCompiler aComp( GetDocPtr(), ScAddress(), *mxTokenArray );
+ aComp.SetGrammar( ::formula::FormulaGrammar::GRAM_ENGLISH );
+ OUStringBuffer aRangeRep;
+ aComp.CreateStringFromTokenArray( aRangeRep );
+ try
+ {
+ xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aRangeRep.makeStringAndClear() );
+ // set sequence role
+ ScfPropertySet aSeqProp( xDataSeq );
+ aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
+ }
+ catch( Exception& )
+ {
+// DBG_ERRORFILE( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
+ }
+ }
+ return xDataSeq;
+}
+
+Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequence(
+ const XclImpChRoot& rRoot, sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const
+{
+ ::std::vector< Reference< XFormattedString > > aStringVec;
+ if( mxString )
+ {
+ for( XclImpStringIterator aIt( *mxString ); aIt.Is(); ++aIt )
+ {
+ Reference< XFormattedString > xFmtStr(
+ ScfApiHelper::CreateInstance( SERVICE_CHART2_FORMATTEDSTRING ), UNO_QUERY );
+ if( xFmtStr.is() )
+ {
+ // set text data
+ xFmtStr->setString( aIt.GetPortionText() );
+
+ // set font formatting and font color
+ ScfPropertySet aStringProp( xFmtStr );
+ sal_uInt16 nFontIdx = aIt.GetPortionFont();
+ if( (nFontIdx == EXC_FONT_NOTFOUND) && (aIt.GetPortionIndex() == 0) )
+ // leading unformatted portion - use passed font settings
+ rRoot.ConvertFont( aStringProp, nLeadFontIdx, &rLeadFontColor );
+ else
+ rRoot.ConvertFont( aStringProp, nFontIdx );
+
+ // add string to vector of strings
+ aStringVec.push_back( xFmtStr );
+ }
+ }
+ }
+ return ScfApiHelper::VectorToSequence( aStringVec );
+}
+
+void XclImpChSourceLink::FillSourceLink( ::std::vector< ScTokenRef >& rTokens ) const
+{
+ if( !mxTokenArray )
+ // no links to fill.
+ return;
+
+ mxTokenArray->Reset();
+ for (FormulaToken* p = mxTokenArray->First(); p; p = mxTokenArray->Next())
+ {
+ ScTokenRef pToken(static_cast<ScToken*>(p->Clone()));
+ if (ScRefTokenHelper::isRef(pToken))
+ // This is a reference token. Store it.
+ ScRefTokenHelper::join(rTokens, pToken);
+ }
+}
+
+// Text =======================================================================
+
+XclImpChFontBase::~XclImpChFontBase()
+{
+}
+
+void XclImpChFontBase::ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
+{
+ Color aFontColor = GetFontColor();
+ rRoot.ConvertFont( rPropSet, GetFontIndex(), &aFontColor );
+}
+
+void XclImpChFontBase::ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const
+{
+ rRoot.GetChartPropSetHelper().WriteRotationProperties( rPropSet, GetRotation(), bSupportsStacked );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChFont::XclImpChFont() :
+ mnFontIdx( EXC_FONT_NOTFOUND )
+{
+}
+
+void XclImpChFont::ReadChFont( XclImpStream& rStrm )
+{
+ rStrm >> mnFontIdx;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChText::XclImpChText( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnHAlign
+ >> maData.mnVAlign
+ >> maData.mnBackMode
+ >> maData.maTextColor
+ >> maData.maRect
+ >> maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ // BIFF8: index into palette used instead of RGB data
+ maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+ // placement and rotation
+ rStrm >> maData.mnFlags2 >> maData.mnRotation;
+ }
+ else
+ {
+ // BIFF2-BIFF7: get rotation from text orientation
+ sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 8, 3 );
+ maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
+ }
+}
+
+void XclImpChText::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHFONT:
+ mxFont.reset( new XclImpChFont );
+ mxFont->ReadChFont( rStrm );
+ break;
+ case EXC_ID_CHFORMATRUNS:
+ if( GetBiff() == EXC_BIFF8 )
+ XclImpString::ReadFormats( rStrm, maFormats );
+ break;
+ case EXC_ID_CHSOURCELINK:
+ mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
+ mxSrcLink->ReadChSourceLink( rStrm );
+ break;
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_TEXT ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHOBJECTLINK:
+ rStrm >> maObjLink.mnTarget >> maObjLink.maPointPos.mnSeriesIdx >> maObjLink.maPointPos.mnPointIdx;
+ break;
+ case EXC_ID_CHFRLABELPROPS:
+ ReadChFrLabelProps( rStrm );
+ break;
+ case EXC_ID_CHEND:
+ if( mxSrcLink && !maFormats.empty() )
+ mxSrcLink->SetTextFormats( maFormats );
+ break;
+ }
+}
+
+sal_uInt16 XclImpChText::GetFontIndex() const
+{
+ return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+Color XclImpChText::GetFontColor() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
+}
+
+sal_uInt16 XclImpChText::GetRotation() const
+{
+ return maData.mnRotation;
+}
+
+void XclImpChText::SetString( const String& rString )
+{
+ if( !mxSrcLink )
+ mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
+ mxSrcLink->SetString( rString );
+}
+
+void XclImpChText::UpdateText( const XclImpChText* pParentText )
+{
+ if( pParentText )
+ {
+ // update missing members
+ if( !mxFrame )
+ mxFrame = pParentText->mxFrame;
+ if( !mxFont )
+ {
+ mxFont = pParentText->mxFont;
+ // text color is taken from CHTEXT record, not from font in CHFONT
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, ::get_flag( pParentText->maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) );
+ maData.maTextColor = pParentText->maData.maTextColor;
+ }
+ }
+}
+
+void XclImpChText::UpdateDataLabel( bool bCateg, bool bValue, bool bPercent )
+{
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bCateg );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bValue );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bCateg && bPercent );
+ ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bCateg && !bValue && !bPercent );
+}
+
+void XclImpChText::ConvertFont( ScfPropertySet& rPropSet ) const
+{
+ ConvertFontBase( GetChRoot(), rPropSet );
+}
+
+void XclImpChText::ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const
+{
+ ConvertRotationBase( GetChRoot(), rPropSet, bSupportsStacked );
+}
+
+void XclImpChText::ConvertFrame( ScfPropertySet& rPropSet ) const
+{
+ if( mxFrame )
+ mxFrame->Convert( rPropSet );
+}
+
+void XclImpChText::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
+{
+ if( mxSrcLink )
+ mxSrcLink->ConvertNumFmt( rPropSet, bPercent );
+}
+
+void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const
+{
+ // existing CHFRLABELPROPS record wins over flags from CHTEXT
+ sal_uInt16 nShowFlags = mxLabelProps ? mxLabelProps->mnFlags : maData.mnFlags;
+ sal_uInt16 SHOWANYCATEG = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWCATEG : (EXC_CHTEXT_SHOWCATEGPERC | EXC_CHTEXT_SHOWCATEG);
+ sal_uInt16 SHOWANYVALUE = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWVALUE : EXC_CHTEXT_SHOWVALUE;
+ sal_uInt16 SHOWANYPERCENT = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWPERCENT : (EXC_CHTEXT_SHOWPERCENT | EXC_CHTEXT_SHOWCATEGPERC);
+ sal_uInt16 SHOWANYBUBBLE = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWBUBBLE : EXC_CHTEXT_SHOWBUBBLE;
+
+ // get raw flags for label values
+ bool bShowNone = IsDeleted();
+ bool bShowCateg = !bShowNone && ::get_flag( nShowFlags, SHOWANYCATEG );
+ bool bShowPercent = !bShowNone && ::get_flag( nShowFlags, SHOWANYPERCENT );
+ bool bShowValue = !bShowNone && ::get_flag( nShowFlags, SHOWANYVALUE );
+ bool bShowBubble = !bShowNone && ::get_flag( nShowFlags, SHOWANYBUBBLE );
+
+ // adjust to Chart2 behaviour
+ if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
+ bShowValue = bShowBubble; // Chart2 bubble charts show bubble size if 'ShowValue' is set
+
+ // other flags
+ bool bShowAny = bShowValue || bShowPercent || bShowCateg;
+ bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL );
+
+ // create API struct for label values, set API label separator
+ cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
+ rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel );
+ String aSep = mxLabelProps ? mxLabelProps->maSeparator : String( sal_Unicode( '\n' ) );
+ if( aSep.Len() == 0 )
+ aSep = CREATE_STRING( "; " );
+ rPropSet.SetStringProperty( EXC_CHPROP_LABELSEPARATOR, aSep );
+
+ // text properties of attached label
+ if( bShowAny )
+ {
+ ConvertFont( rPropSet );
+ ConvertRotation( rPropSet, false );
+ // label placement
+ using namespace cssc::DataLabelPlacement;
+ sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos;
+ switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) )
+ {
+ case EXC_CHTEXT_POS_DEFAULT: nPlacement = rTypeInfo.mnDefaultLabelPos; break;
+ case EXC_CHTEXT_POS_OUTSIDE: nPlacement = OUTSIDE; break;
+ case EXC_CHTEXT_POS_INSIDE: nPlacement = INSIDE; break;
+ case EXC_CHTEXT_POS_CENTER: nPlacement = CENTER; break;
+ case EXC_CHTEXT_POS_AXIS: nPlacement = NEAR_ORIGIN; break;
+ case EXC_CHTEXT_POS_ABOVE: nPlacement = TOP; break;
+ case EXC_CHTEXT_POS_BELOW: nPlacement = BOTTOM; break;
+ case EXC_CHTEXT_POS_LEFT: nPlacement = LEFT; break;
+ case EXC_CHTEXT_POS_RIGHT: nPlacement = RIGHT; break;
+ case EXC_CHTEXT_POS_AUTO: nPlacement = AVOID_OVERLAP; break;
+ }
+ rPropSet.SetProperty( EXC_CHPROP_LABELPLACEMENT, nPlacement );
+ // label number format (percentage format wins over value format)
+ if( bShowPercent || bShowValue )
+ ConvertNumFmt( rPropSet, bShowPercent );
+ }
+}
+
+Reference< XTitle > XclImpChText::CreateTitle() const
+{
+ Reference< XTitle > xTitle;
+ if( mxSrcLink && mxSrcLink->HasString() )
+ {
+ // create the formatted strings
+ Sequence< Reference< XFormattedString > > aStringSeq(
+ mxSrcLink->CreateStringSequence( GetChRoot(), GetFontIndex(), GetFontColor() ) );
+ if( aStringSeq.hasElements() )
+ {
+ // create the title object
+ xTitle.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_TITLE ), UNO_QUERY );
+ if( xTitle.is() )
+ {
+ // set the formatted strings
+ xTitle->setText( aStringSeq );
+ // more title formatting properties
+ ScfPropertySet aTitleProp( xTitle );
+ ConvertFrame( aTitleProp );
+ ConvertRotation( aTitleProp, true );
+ }
+ }
+ }
+ return xTitle;
+}
+
+void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const
+{
+ if( !mxFramePos ) return;
+
+ const XclChFramePos& rPosData = mxFramePos->GetFramePosData();
+ OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT),
+ "XclImpChText::ConvertTitlePosition - unexpected frame position mode" );
+
+ /* Check if title is moved manually. To get the actual position of the
+ title, we do some kind of hack and use the values from the CHTEXT
+ record, effectively ignoring the contents of the CHFRAMEPOS record
+ which contains the position relative to the default title position
+ (according to the spec, the CHFRAMEPOS supersedes the CHTEXT record).
+ Especially when it comes to axis titles, things would become very
+ complicated here, because the relative title position is stored in a
+ measurement unit that is dependent on the size of the inner plot area,
+ the interpretation of the X and Y coordinate is dependent on the
+ direction of the axis, and in 3D charts, and the title default
+ positions are dependent on the 3D view settings (rotation, elevation,
+ and perspective). Thus, it is easier to assume that the creator has
+ written out the correct absolute position and size of the title in the
+ CHTEXT record. This is assured by checking that the shape size stored
+ in the CHTEXT record is non-zero. */
+ if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) &&
+ ((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) &&
+ (maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try
+ {
+ Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW );
+ // the call to XShape.getSize() may recalc the chart view
+ ::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize();
+ // rotated titles need special handling...
+ sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 );
+ double fRad = nScRot * F_PI18000;
+ double fSin = fabs( sin( fRad ) );
+ double fCos = fabs( cos( fRad ) );
+ ::com::sun::star::awt::Size aBoundSize(
+ static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ),
+ static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) );
+ // calculate the title position from the values in the CHTEXT record
+ ::com::sun::star::awt::Point aTitlePos(
+ CalcHmmFromChartX( maData.maRect.mnX ),
+ CalcHmmFromChartY( maData.maRect.mnY ) );
+ // add part of height to X direction, if title is rotated down (clockwise)
+ if( nScRot > 18000 )
+ aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 );
+ // add part of width to Y direction, if title is rotated up (counterclockwise)
+ else if( nScRot > 0 )
+ aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 );
+ // set the resulting position at the title shape
+ xTitleShape->setPosition( aTitlePos );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mxLabelProps.reset( new XclChFrLabelProps );
+ sal_uInt16 nSepLen;
+ rStrm.Ignore( 12 );
+ rStrm >> mxLabelProps->mnFlags >> nSepLen;
+ if( nSepLen > 0 )
+ mxLabelProps->maSeparator = rStrm.ReadUniString( nSepLen );
+ }
+}
+
+namespace {
+
+void lclUpdateText( XclImpChTextRef& rxText, const XclImpChText* xDefText )
+{
+ if( rxText )
+ rxText->UpdateText( xDefText );
+ else
+ {
+ XclImpChTextRef xNew(new XclImpChText(*xDefText));
+ rxText = xNew;
+ }
+}
+
+void lclFinalizeTitle( XclImpChTextRef& rxTitle, const XclImpChText* pDefText, const String& rAutoTitle )
+{
+ /* Do not update a title, if it is not visible (if rxTitle is null).
+ Existing reference indicates enabled title. */
+ if( rxTitle )
+ {
+ if( !rxTitle->HasString() )
+ rxTitle->SetString( rAutoTitle );
+ if( rxTitle->HasString() )
+ rxTitle->UpdateText(pDefText);
+ else
+ rxTitle.reset();
+ }
+}
+
+} // namespace
+
+// Data series ================================================================
+
+void XclImpChMarkerFormat::ReadChMarkerFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.maLineColor >> maData.maFillColor >> maData.mnMarkerType >> maData.mnFlags;
+
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ if( rRoot.GetBiff() == EXC_BIFF8 )
+ {
+ // BIFF8: index into palette used instead of RGB data
+ const XclImpPalette& rPal = rRoot.GetPalette();
+ maData.maLineColor = rPal.GetColor( rStrm.ReaduInt16() );
+ maData.maFillColor = rPal.GetColor( rStrm.ReaduInt16() );
+ // marker size
+ rStrm >> maData.mnMarkerSize;
+ }
+}
+
+void XclImpChMarkerFormat::Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const
+{
+ if( IsAuto() )
+ {
+ XclChMarkerFormat aMarkerFmt;
+ // line and fill color of the symbol are equal to series line color
+ //! TODO: Excel sets no fill color for specific symbols (e.g. cross)
+ aMarkerFmt.maLineColor = aMarkerFmt.maFillColor = rRoot.GetSeriesLineAutoColor( nFormatIdx );
+ switch( nLineWeight )
+ {
+ case EXC_CHLINEFORMAT_HAIR: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_HAIRSIZE; break;
+ case EXC_CHLINEFORMAT_SINGLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE; break;
+ case EXC_CHLINEFORMAT_DOUBLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE; break;
+ case EXC_CHLINEFORMAT_TRIPLE: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_TRIPLESIZE; break;
+ default: aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE;
+ }
+ aMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, aMarkerFmt );
+ }
+ else
+ {
+ rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, maData );
+ }
+}
+
+void XclImpChMarkerFormat::ConvertColor( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
+{
+ Color aLineColor = IsAuto() ? rRoot.GetSeriesLineAutoColor( nFormatIdx ) : maData.maFillColor;
+ rPropSet.SetColorProperty( EXC_CHPROP_COLOR, aLineColor );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChPieFormat::XclImpChPieFormat() :
+ mnPieDist( 0 )
+{
+}
+
+void XclImpChPieFormat::ReadChPieFormat( XclImpStream& rStrm )
+{
+ rStrm >> mnPieDist;
+}
+
+void XclImpChPieFormat::Convert( ScfPropertySet& rPropSet ) const
+{
+ double fApiDist = ::std::min< double >( mnPieDist / 100.0, 1.0 );
+ rPropSet.SetProperty( EXC_CHPROP_OFFSET, fApiDist );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSeriesFormat::XclImpChSeriesFormat() :
+ mnFlags( 0 )
+{
+}
+
+void XclImpChSeriesFormat::ReadChSeriesFormat( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpCh3dDataFormat::ReadCh3dDataFormat( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnBase >> maData.mnTop;
+}
+
+void XclImpCh3dDataFormat::Convert( ScfPropertySet& rPropSet ) const
+{
+ using namespace ::com::sun::star::chart2::DataPointGeometry3D;
+ sal_Int32 nApiType = (maData.mnBase == EXC_CH3DDATAFORMAT_RECT) ?
+ ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CUBOID : PYRAMID) :
+ ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CYLINDER : CONE);
+ rPropSet.SetProperty( EXC_CHPROP_GEOMETRY3D, nApiType );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAttachedLabel::XclImpChAttachedLabel( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ mnFlags( 0 )
+{
+}
+
+void XclImpChAttachedLabel::ReadChAttachedLabel( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags;
+}
+
+XclImpChTextRef XclImpChAttachedLabel::CreateDataLabel( const XclImpChText* pParent ) const
+{
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYVALUE = EXC_CHATTLABEL_SHOWVALUE;
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYPERCENT = EXC_CHATTLABEL_SHOWPERCENT | EXC_CHATTLABEL_SHOWCATEGPERC;
+ const sal_uInt16 EXC_CHATTLABEL_SHOWANYCATEG = EXC_CHATTLABEL_SHOWCATEG | EXC_CHATTLABEL_SHOWCATEGPERC;
+
+ XclImpChTextRef xLabel( pParent ? new XclImpChText( *pParent ) : new XclImpChText( GetChRoot() ) );
+ xLabel->UpdateDataLabel(
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYCATEG ),
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYVALUE ),
+ ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYPERCENT ) );
+ return xLabel;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChDataFormat::XclImpChDataFormat( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChDataFormat::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.maPointPos.mnPointIdx
+ >> maData.maPointPos.mnSeriesIdx
+ >> maData.mnFormatIdx
+ >> maData.mnFlags;
+}
+
+void XclImpChDataFormat::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHMARKERFORMAT:
+ mxMarkerFmt.reset( new XclImpChMarkerFormat );
+ mxMarkerFmt->ReadChMarkerFormat( rStrm );
+ break;
+ case EXC_ID_CHPIEFORMAT:
+ mxPieFmt.reset( new XclImpChPieFormat );
+ mxPieFmt->ReadChPieFormat( rStrm );
+ break;
+ case EXC_ID_CHSERIESFORMAT:
+ mxSeriesFmt.reset( new XclImpChSeriesFormat );
+ mxSeriesFmt->ReadChSeriesFormat( rStrm );
+ break;
+ case EXC_ID_CH3DDATAFORMAT:
+ mx3dDataFmt.reset( new XclImpCh3dDataFormat );
+ mx3dDataFmt->ReadCh3dDataFormat( rStrm );
+ break;
+ case EXC_ID_CHATTACHEDLABEL:
+ mxAttLabel.reset( new XclImpChAttachedLabel( GetChRoot() ) );
+ mxAttLabel->ReadChAttachedLabel( rStrm );
+ break;
+ default:
+ XclImpChFrameBase::ReadSubRecord( rStrm );
+ }
+}
+
+void XclImpChDataFormat::SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx )
+{
+ maData.maPointPos = rPointPos;
+ maData.mnFormatIdx = nFormatIdx;
+}
+
+void XclImpChDataFormat::UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo )
+{
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+}
+
+void XclImpChDataFormat::UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt )
+{
+ // update missing formats from passed chart type group format
+ if( pGroupFmt )
+ {
+ if( !mxLineFmt )
+ mxLineFmt = pGroupFmt->mxLineFmt;
+ if( !mxAreaFmt && !mxEscherFmt )
+ {
+ mxAreaFmt = pGroupFmt->mxAreaFmt;
+ mxEscherFmt = pGroupFmt->mxEscherFmt;
+ }
+ if( !mxMarkerFmt )
+ mxMarkerFmt = pGroupFmt->mxMarkerFmt;
+ if( !mxPieFmt )
+ mxPieFmt = pGroupFmt->mxPieFmt;
+ if( !mxSeriesFmt )
+ mxSeriesFmt = pGroupFmt->mxSeriesFmt;
+ if( !mx3dDataFmt )
+ mx3dDataFmt = pGroupFmt->mx3dDataFmt;
+ if( !mxAttLabel )
+ mxAttLabel = pGroupFmt->mxAttLabel;
+ }
+
+ /* Create missing but required formats. Existing line, area, and marker
+ format objects are needed to create automatic series formatting. */
+ if( !mxLineFmt )
+ mxLineFmt.reset( new XclImpChLineFormat );
+ if( !mxAreaFmt && !mxEscherFmt )
+ mxAreaFmt.reset( new XclImpChAreaFormat );
+ if( !mxMarkerFmt )
+ mxMarkerFmt.reset( new XclImpChMarkerFormat );
+
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+ // update data label
+ UpdateDataLabel( pGroupFmt );
+}
+
+void XclImpChDataFormat::UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt )
+{
+ // remove formats if they are automatic in this and in the passed series format
+ if( pSeriesFmt )
+ {
+ if( IsAutoLine() && pSeriesFmt->IsAutoLine() )
+ mxLineFmt.reset();
+ if( IsAutoArea() && pSeriesFmt->IsAutoArea() )
+ mxAreaFmt.reset();
+ if( IsAutoMarker() && pSeriesFmt->IsAutoMarker() )
+ mxMarkerFmt.reset();
+ mxSeriesFmt.reset();
+ }
+
+ // Excel ignores 3D bar format for single data points
+ mx3dDataFmt.reset();
+ // remove point line formats for linear chart types, TODO: implement in OOChart
+ if( !rTypeInfo.IsSeriesFrameFormat() )
+ mxLineFmt.reset();
+
+ // remove formats not used for the current chart type
+ RemoveUnusedFormats( rTypeInfo );
+ // update data label
+ UpdateDataLabel( pSeriesFmt );
+}
+
+void XclImpChDataFormat::UpdateTrendLineFormat()
+{
+ if( !mxLineFmt )
+ mxLineFmt.reset( new XclImpChLineFormat );
+ mxAreaFmt.reset();
+ mxEscherFmt.reset();
+ mxMarkerFmt.reset();
+ mxPieFmt.reset();
+ mxSeriesFmt.reset();
+ mx3dDataFmt.reset();
+ mxAttLabel.reset();
+ // update data label
+ UpdateDataLabel( 0 );
+}
+
+void XclImpChDataFormat::Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const
+{
+ // line and area format
+ ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx );
+#if EXC_CHART2_3DBAR_HAIRLINES_ONLY
+ // #i83151# only hair lines in 3D charts with filled data points
+ if( rTypeInfo.mb3dChart && rTypeInfo.IsSeriesFrameFormat() && mxLineFmt && mxLineFmt->HasLine() )
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BorderWidth" ), 0 );
+#endif
+
+ // other formatting
+ if( mxMarkerFmt )
+ mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx, GetLineWeight() );
+ if( mxPieFmt )
+ mxPieFmt->Convert( rPropSet );
+ if( mx3dDataFmt )
+ mx3dDataFmt->Convert( rPropSet );
+ if( mxLabel )
+ mxLabel->ConvertDataLabel( rPropSet, rTypeInfo );
+
+ // 3D settings
+ rPropSet.SetProperty< sal_Int16 >( EXC_CHPROP_PERCENTDIAGONAL, 0 );
+
+ /* Special case: set marker color as line color, if series line is not
+ visible. This makes the color visible in the marker area.
+ TODO: remove this if OOChart supports own colors in markers. */
+ if( !rTypeInfo.IsSeriesFrameFormat() && !HasLine() && mxMarkerFmt )
+ mxMarkerFmt->ConvertColor( GetChRoot(), rPropSet, maData.mnFormatIdx );
+}
+
+void XclImpChDataFormat::ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
+{
+ ConvertLineBase( GetChRoot(), rPropSet, eObjType );
+}
+
+void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
+{
+ ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx );
+}
+
+void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo )
+{
+ // data point marker only in linear 2D charts
+ if( rTypeInfo.IsSeriesFrameFormat() )
+ mxMarkerFmt.reset();
+ // pie format only in pie/donut charts
+ if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
+ mxPieFmt.reset();
+ // 3D format only in 3D bar charts
+ if( !rTypeInfo.mb3dChart || (rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
+ mx3dDataFmt.reset();
+}
+
+void XclImpChDataFormat::UpdateDataLabel( const XclImpChDataFormat* pParentFmt )
+{
+ /* CHTEXT groups linked to data labels override existing CHATTACHEDLABEL
+ records. Only if there is a CHATTACHEDLABEL record without a CHTEXT
+ group, the contents of the CHATTACHEDLABEL record are used. In this
+ case a new CHTEXT group is created and filled with the settings from
+ the CHATTACHEDLABEL record. */
+ const XclImpChText* pDefText = NULL;
+ if (pParentFmt)
+ pDefText = pParentFmt->GetDataLabel();
+ if (!pDefText)
+ pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_DATALABEL );
+ if (mxLabel)
+ mxLabel->UpdateText(pDefText);
+ else if (mxAttLabel)
+ mxLabel = mxAttLabel->CreateDataLabel( pDefText );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSerTrendLine::XclImpChSerTrendLine( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChSerTrendLine::ReadChSerTrendLine( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnLineType
+ >> maData.mnOrder
+ >> maData.mfIntercept
+ >> maData.mnShowEquation
+ >> maData.mnShowRSquared
+ >> maData.mfForecastFor
+ >> maData.mfForecastBack;
+}
+
+Reference< XRegressionCurve > XclImpChSerTrendLine::CreateRegressionCurve() const
+{
+ // trend line type
+ OUString aService;
+ switch( maData.mnLineType )
+ {
+ case EXC_CHSERTREND_POLYNOMIAL:
+ // TODO: only linear trend lines are supported by OOChart (#i20819#)
+ if( maData.mnOrder == 1 )
+ aService = SERVICE_CHART2_LINEARREGCURVE;
+ break;
+ case EXC_CHSERTREND_EXPONENTIAL:
+ aService = SERVICE_CHART2_EXPREGCURVE;
+ break;
+ case EXC_CHSERTREND_LOGARITHMIC:
+ aService = SERVICE_CHART2_LOGREGCURVE;
+ break;
+ case EXC_CHSERTREND_POWER:
+ aService = SERVICE_CHART2_POTREGCURVE;
+ break;
+ }
+ Reference< XRegressionCurve > xRegCurve;
+ if( aService.getLength() > 0 )
+ xRegCurve.set( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
+
+ // trend line formatting
+ if( xRegCurve.is() && mxDataFmt )
+ {
+ ScfPropertySet aPropSet( xRegCurve );
+ mxDataFmt->ConvertLine( aPropSet, EXC_CHOBJTYPE_TRENDLINE );
+
+ // #i83100# show equation and correlation coefficient
+ ScfPropertySet aLabelProp( xRegCurve->getEquationProperties() );
+ aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWEQUATION, maData.mnShowEquation != 0 );
+ aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWCORRELATION, maData.mnShowRSquared != 0 );
+
+ // #i83100# formatting of the equation text box
+ if (const XclImpChText* pLabel = mxDataFmt->GetDataLabel())
+ {
+ pLabel->ConvertFont( aLabelProp );
+ pLabel->ConvertFrame( aLabelProp );
+ pLabel->ConvertNumFmt( aLabelProp, false );
+ }
+ }
+
+ // missing features
+ // #i20819# polynomial trend lines
+ // #i66819# moving average trend lines
+ // #i5085# manual trend line size
+ // #i34093# manual crossing point
+
+ return xRegCurve;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSerErrorBar::XclImpChSerErrorBar( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChSerErrorBar::ReadChSerErrorBar( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnBarType >> maData.mnSourceType >> maData.mnLineEnd;
+ rStrm.Ignore( 1 );
+ rStrm >> maData.mfValue >> maData.mnValueCount;
+}
+
+void XclImpChSerErrorBar::SetSeriesData( XclImpChSourceLinkRef xValueLink, XclImpChDataFormatRef xDataFmt )
+{
+ mxValueLink = xValueLink;
+ mxDataFmt = xDataFmt;
+}
+
+Reference< XLabeledDataSequence > XclImpChSerErrorBar::CreateValueSequence() const
+{
+ return lclCreateLabeledDataSequence( mxValueLink, XclChartHelper::GetErrorBarValuesRole( maData.mnBarType ) );
+}
+
+Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSerErrorBar* pPosBar, const XclImpChSerErrorBar* pNegBar )
+{
+ Reference< XPropertySet > xErrorBar;
+
+ if( const XclImpChSerErrorBar* pPrimaryBar = pPosBar ? pPosBar : pNegBar )
+ {
+ xErrorBar.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_ERRORBAR ), UNO_QUERY );
+ ScfPropertySet aBarProp( xErrorBar );
+
+ // plus/minus bars visible?
+ aBarProp.SetBoolProperty( EXC_CHPROP_SHOWPOSITIVEERROR, pPosBar != 0 );
+ aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 );
+
+ // type of displayed error
+ switch( pPrimaryBar->maData.mnSourceType )
+ {
+ case EXC_CHSERERR_PERCENT:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::RELATIVE );
+ aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
+ aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_FIXED:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::ABSOLUTE );
+ aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
+ aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_STDDEV:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_DEVIATION );
+ aBarProp.SetProperty( EXC_CHPROP_WEIGHT, pPrimaryBar->maData.mfValue );
+ break;
+ case EXC_CHSERERR_STDERR:
+ aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_ERROR );
+ break;
+ case EXC_CHSERERR_CUSTOM:
+ {
+ aBarProp.SetProperty( EXC_CHPROP_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( pPosBar )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = pPosBar->CreateValueSequence();
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // add negative values
+ if( pNegBar )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = pNegBar->CreateValueSequence();
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // attach labeled data sequences to series
+ if( aLabeledSeqVec.empty() )
+ xErrorBar.clear();
+ else
+ xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+ }
+ }
+ break;
+ default:
+ xErrorBar.clear();
+ }
+
+ // error bar formatting
+ if( pPrimaryBar->mxDataFmt && xErrorBar.is() )
+ pPrimaryBar->mxDataFmt->ConvertLine( aBarProp, EXC_CHOBJTYPE_ERRORBAR );
+ }
+
+ return xErrorBar;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChSeries::XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
+ XclImpChRoot( rRoot ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE ),
+ mnSeriesIdx( nSeriesIdx ),
+ mnParentIdx( EXC_CHSERIES_INVALID )
+{
+}
+
+void XclImpChSeries::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnCategType >> maData.mnValueType >> maData.mnCategCount >> maData.mnValueCount;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnBubbleType >> maData.mnBubbleCount;
+}
+
+void XclImpChSeries::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHSOURCELINK:
+ ReadChSourceLink( rStrm );
+ break;
+ case EXC_ID_CHDATAFORMAT:
+ ReadChDataFormat( rStrm );
+ break;
+ case EXC_ID_CHSERGROUP:
+ rStrm >> mnGroupIdx;
+ break;
+ case EXC_ID_CHSERPARENT:
+ ReadChSerParent( rStrm );
+ break;
+ case EXC_ID_CHSERTRENDLINE:
+ ReadChSerTrendLine( rStrm );
+ break;
+ case EXC_ID_CHSERERRORBAR:
+ ReadChSerErrorBar( rStrm );
+ break;
+ }
+}
+
+void XclImpChSeries::SetDataFormat( XclImpChDataFormatRef xDataFmt )
+{
+ if( xDataFmt )
+ {
+ XclImpChDataFormatRef* pxDataFmt = GetDataFormatRef( xDataFmt->GetPointPos().mnPointIdx );
+ // do not overwrite existing data format
+ if( pxDataFmt && !*pxDataFmt )
+ {
+ *pxDataFmt = xDataFmt;
+ // #i51639# register series format index at chart type group
+ if( (pxDataFmt == &mxSeriesFmt) && !HasParentSeries() )
+ if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ pTypeGroup->SetUsedFormatIndex( xDataFmt->GetFormatIdx() );
+ }
+ }
+}
+
+void XclImpChSeries::SetDataLabel( XclImpChTextRef xLabel )
+{
+ if( xLabel )
+ {
+ XclImpChTextRef* pxLabel = GetDataLabelRef( xLabel->GetPointPos().mnPointIdx );
+ if( pxLabel && !*pxLabel )
+ *pxLabel = xLabel;
+ }
+}
+
+void XclImpChSeries::AddChildSeries( const XclImpChSeries& rSeries )
+{
+ DBG_ASSERT( !HasParentSeries(), "XclImpChSeries::AddChildSeries - not allowed for child series" );
+
+ /* In Excel, trend lines and error bars are stored as own series. In Calc,
+ these are properties of the parent series. This function adds the
+ settings of the passed series to this series. */
+ maTrendLines.insert( maTrendLines.end(), rSeries.maTrendLines.begin(), rSeries.maTrendLines.end() );
+ maErrorBars.insert( rSeries.maErrorBars.begin(), rSeries.maErrorBars.end() );
+}
+
+void XclImpChSeries::FinalizeDataFormats()
+{
+ if( HasParentSeries() )
+ {
+ // *** series is a child series, e.g. trend line or error bar ***
+
+ // create missing series format
+ if( !mxSeriesFmt )
+ mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, 0 );
+
+ if( mxSeriesFmt )
+ {
+ // #i83100# set text label format, e.g. for trend line equations
+ XclImpChTextRef xLabel;
+ XclImpChTextMap::iterator itr = maLabels.find(EXC_CHDATAFORMAT_ALLPOINTS);
+ if (itr != maLabels.end())
+ xLabel = itr->second;
+ mxSeriesFmt->SetDataLabel(xLabel);
+ // create missing automatic formats
+ mxSeriesFmt->UpdateTrendLineFormat();
+ }
+
+ // copy series formatting to child objects
+ for( XclImpChSerTrendLineList::iterator aLIt = maTrendLines.begin(), aLEnd = maTrendLines.end(); aLIt != aLEnd; ++aLIt )
+ (*aLIt)->SetDataFormat( mxSeriesFmt );
+ for( XclImpChSerErrorBarMap::iterator aMIt = maErrorBars.begin(), aMEnd = maErrorBars.end(); aMIt != aMEnd; ++aMIt )
+ aMIt->second->SetSeriesData( mxValueLink, mxSeriesFmt );
+ }
+ else if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ {
+ // *** series is a regular data series ***
+
+ // create missing series format
+ if( !mxSeriesFmt )
+ {
+ // #i51639# use a new unused format index to create series default format
+ sal_uInt16 nFormatIdx = pTypeGroup->PopUnusedFormatIndex();
+ mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, nFormatIdx );
+ }
+
+ // set text labels to data formats
+ for( XclImpChTextMap::iterator aTIt = maLabels.begin(), aTEnd = maLabels.end(); aTIt != aTEnd; ++aTIt )
+ {
+ if( XclImpChDataFormatRef* pxDataFmt = GetDataFormatRef( aTIt->first ) )
+ {
+ if( !*pxDataFmt )
+ *pxDataFmt = CreateDataFormat( aTIt->first, EXC_CHDATAFORMAT_DEFAULT );
+ (*pxDataFmt)->SetDataLabel( aTIt->second );
+ }
+ }
+
+ // update series format (copy missing formatting from group default format)
+ if( mxSeriesFmt )
+ mxSeriesFmt->UpdateSeriesFormat( pTypeGroup->GetTypeInfo(), pTypeGroup->GetGroupFormat().get() );
+
+ // update data point formats (removes unchanged automatic formatting)
+ for( XclImpChDataFormatMap::iterator aFIt = maPointFmts.begin(), aFEnd = maPointFmts.end(); aFIt != aFEnd; ++aFIt )
+ aFIt->second->UpdatePointFormat( pTypeGroup->GetTypeInfo(), mxSeriesFmt.get() );
+ }
+}
+
+namespace {
+
+/** Returns the property set of the specified data point. */
+ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_uInt16 nPointIdx )
+{
+ ScfPropertySet aPropSet;
+ try
+ {
+ aPropSet.Set( xDataSeries->getDataPointByIndex( static_cast< sal_Int32 >( nPointIdx ) ) );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
+ }
+ return aPropSet;
+}
+
+} // namespace
+
+Reference< XLabeledDataSequence > XclImpChSeries::CreateValueSequence( const OUString& rValueRole ) const
+{
+ return lclCreateLabeledDataSequence( mxValueLink, rValueRole, mxTitleLink.get() );
+}
+
+Reference< XLabeledDataSequence > XclImpChSeries::CreateCategSequence( const OUString& rCategRole ) const
+{
+ return lclCreateLabeledDataSequence( mxCategLink, rCategRole );
+}
+
+Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const
+{
+ Reference< XDataSeries > xDataSeries;
+ if( const XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
+ {
+ const XclChExtTypeInfo& rTypeInfo = pTypeGroup->GetTypeInfo();
+
+ // create the data series object
+ xDataSeries.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
+
+ // attach data and title sequences to series
+ 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( EXC_CHPROP_ROLE_YVALUES );
+ if( xYValueSeq.is() )
+ aLabeledSeqVec.push_back( xYValueSeq );
+ // add X values
+ if( !rTypeInfo.mbCategoryAxis )
+ {
+ Reference< XLabeledDataSequence > xXValueSeq =
+ CreateCategSequence( EXC_CHPROP_ROLE_XVALUES );
+ if( xXValueSeq.is() )
+ aLabeledSeqVec.push_back( xXValueSeq );
+ // add size values of bubble charts
+ if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
+ {
+ Reference< XLabeledDataSequence > xSizeValueSeq =
+ lclCreateLabeledDataSequence( mxBubbleLink, EXC_CHPROP_ROLE_SIZEVALUES, mxTitleLink.get() );
+ if( xSizeValueSeq.is() )
+ aLabeledSeqVec.push_back( xSizeValueSeq );
+ }
+ }
+ // attach labeled data sequences to series
+ if( !aLabeledSeqVec.empty() )
+ xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+ }
+
+ // series formatting
+ ScfPropertySet aSeriesProp( xDataSeries );
+ if( mxSeriesFmt )
+ mxSeriesFmt->Convert( aSeriesProp, rTypeInfo );
+
+ // trend lines
+ ConvertTrendLines( xDataSeries );
+
+ // error bars
+ Reference< XPropertySet > xErrorBarX = CreateErrorBar( EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
+ if( xErrorBarX.is() )
+ aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARX, xErrorBarX );
+ Reference< XPropertySet > xErrorBarY = CreateErrorBar( EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
+ if( xErrorBarY.is() )
+ aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARY, xErrorBarY );
+
+ // own area formatting for every data point (TODO: varying line color not supported)
+ bool bVarPointFmt = pTypeGroup->HasVarPointFormat() && rTypeInfo.IsSeriesFrameFormat();
+#if EXC_CHART2_VARYCOLORSBY_PROP
+ aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, bVarPointFmt );
+#else
+ aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
+#endif
+ // #i91271# always set area formatting for every point in pie/doughnut charts
+ if( mxSeriesFmt && ((bVarPointFmt && mxSeriesFmt->IsAutoArea()) || (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE)) )
+ {
+ for( sal_uInt16 nPointIdx = 0, nPointCount = mxValueLink->GetCellCount(); nPointIdx < nPointCount; ++nPointIdx )
+ {
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
+ mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx );
+ }
+ }
+
+ // data point formatting
+ for( XclImpChDataFormatMap::const_iterator aIt = maPointFmts.begin(), aEnd = maPointFmts.end(); aIt != aEnd; ++aIt )
+ {
+ ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, aIt->first );
+ aIt->second->Convert( aPointProp, rTypeInfo );
+ }
+ }
+ return xDataSeries;
+}
+
+void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScTokenRef >& rTokens ) const
+{
+ if( mxValueLink )
+ mxValueLink->FillSourceLink( rTokens );
+ if( mxCategLink )
+ mxCategLink->FillSourceLink( rTokens );
+ if( mxTitleLink )
+ mxTitleLink->FillSourceLink( rTokens );
+ if( mxBubbleLink )
+ mxBubbleLink->FillSourceLink( rTokens );
+}
+
+void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm )
+{
+ XclImpChSourceLinkRef xSrcLink( new XclImpChSourceLink( GetChRoot() ) );
+ xSrcLink->ReadChSourceLink( rStrm );
+ switch( xSrcLink->GetDestType() )
+ {
+ case EXC_CHSRCLINK_TITLE: mxTitleLink = xSrcLink; break;
+ case EXC_CHSRCLINK_VALUES: mxValueLink = xSrcLink; break;
+ case EXC_CHSRCLINK_CATEGORY: mxCategLink = xSrcLink; break;
+ case EXC_CHSRCLINK_BUBBLES: mxBubbleLink = xSrcLink; break;
+ }
+}
+
+void XclImpChSeries::ReadChDataFormat( XclImpStream& rStrm )
+{
+ // #i51639# chart stores all data formats and assigns them later to the series
+ GetChartData().ReadChDataFormat( rStrm );
+}
+
+void XclImpChSeries::ReadChSerParent( XclImpStream& rStrm )
+{
+ rStrm >> mnParentIdx;
+ // index to parent series is 1-based, convert it to 0-based
+ if( mnParentIdx > 0 )
+ --mnParentIdx;
+ else
+ mnParentIdx = EXC_CHSERIES_INVALID;
+}
+
+void XclImpChSeries::ReadChSerTrendLine( XclImpStream& rStrm )
+{
+ XclImpChSerTrendLineRef xTrendLine( new XclImpChSerTrendLine( GetChRoot() ) );
+ xTrendLine->ReadChSerTrendLine( rStrm );
+ maTrendLines.push_back( xTrendLine );
+}
+
+void XclImpChSeries::ReadChSerErrorBar( XclImpStream& rStrm )
+{
+ auto_ptr<XclImpChSerErrorBar> pErrorBar(new XclImpChSerErrorBar(GetChRoot()));
+ pErrorBar->ReadChSerErrorBar(rStrm);
+ sal_uInt8 nBarType = pErrorBar->GetBarType();
+ maErrorBars.insert(nBarType, pErrorBar);
+}
+
+XclImpChDataFormatRef XclImpChSeries::CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx )
+{
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->SetPointPos( XclChDataPointPos( mnSeriesIdx, nPointIdx ), nFormatIdx );
+ return xDataFmt;
+}
+
+XclImpChDataFormatRef* XclImpChSeries::GetDataFormatRef( sal_uInt16 nPointIdx )
+{
+ if( nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS )
+ return &mxSeriesFmt;
+
+ if (nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT)
+ {
+ XclImpChDataFormatMap::iterator itr = maPointFmts.lower_bound(nPointIdx);
+ if (itr == maPointFmts.end() || maPointFmts.key_comp()(nPointIdx, itr->first))
+ {
+ // No object exists at this point index position. Insert a new one.
+ XclImpChDataFormatRef p(new XclImpChDataFormat(GetChRoot()));
+ itr = maPointFmts.insert(itr, XclImpChDataFormatMap::value_type(nPointIdx, p));
+ }
+ return &itr->second;
+ }
+ return 0;
+}
+
+XclImpChTextRef* XclImpChSeries::GetDataLabelRef( sal_uInt16 nPointIdx )
+{
+ if ((nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS) || (nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT))
+ {
+ XclImpChTextMap::iterator itr = maLabels.lower_bound(nPointIdx);
+ if (itr == maLabels.end() || maLabels.key_comp()(nPointIdx, itr->first))
+ {
+ // No object exists at this point index position. Insert a new one.
+ XclImpChTextRef p(new XclImpChText(GetChRoot()));
+ itr = maLabels.insert(itr, XclImpChTextMap::value_type(nPointIdx, p));
+ }
+ return &itr->second;
+ }
+ return 0;
+}
+
+void XclImpChSeries::ConvertTrendLines( Reference< XDataSeries > xDataSeries ) const
+{
+ Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
+ if( xRegCurveCont.is() )
+ {
+ for( XclImpChSerTrendLineList::const_iterator aIt = maTrendLines.begin(), aEnd = maTrendLines.end(); aIt != aEnd; ++aIt )
+ {
+ try
+ {
+ Reference< XRegressionCurve > xRegCurve = (*aIt)->CreateRegressionCurve();
+ if( xRegCurve.is() )
+ xRegCurveCont->addRegressionCurve( xRegCurve );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChSeries::ConvertTrendLines - cannot add regression curve" );
+ }
+ }
+ }
+}
+
+Reference< XPropertySet > XclImpChSeries::CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const
+{
+ XclImpChSerErrorBarMap::const_iterator itrPosBar = maErrorBars.find(nPosBarId);
+ XclImpChSerErrorBarMap::const_iterator itrNegBar = maErrorBars.find(nNegBarId);
+ XclImpChSerErrorBarMap::const_iterator itrEnd = maErrorBars.end();
+ if (itrPosBar == itrEnd || itrNegBar == itrEnd)
+ return Reference<XPropertySet>();
+
+ return XclImpChSerErrorBar::CreateErrorBar(itrPosBar->second, itrNegBar->second);
+}
+
+// Chart type groups ==========================================================
+
+XclImpChType::XclImpChType( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ mnRecId( EXC_ID_CHUNKNOWN ),
+ maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
+{
+}
+
+void XclImpChType::ReadChType( XclImpStream& rStrm )
+{
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bool bKnownType = true;
+
+ switch( nRecId )
+ {
+ case EXC_ID_CHBAR:
+ rStrm >> maData.mnOverlap >> maData.mnGap >> maData.mnFlags;
+ break;
+
+ case EXC_ID_CHLINE:
+ case EXC_ID_CHAREA:
+ case EXC_ID_CHRADARLINE:
+ case EXC_ID_CHRADARAREA:
+ rStrm >> maData.mnFlags;
+ break;
+
+ case EXC_ID_CHPIE:
+ rStrm >> maData.mnRotation >> maData.mnPieHole;
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnFlags;
+ else
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHPIEEXT:
+ maData.mnRotation = 0;
+ maData.mnPieHole = 0;
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHSCATTER:
+ if( GetBiff() == EXC_BIFF8 )
+ rStrm >> maData.mnBubbleSize >> maData.mnBubbleType >> maData.mnFlags;
+ else
+ maData.mnFlags = 0;
+ break;
+
+ case EXC_ID_CHSURFACE:
+ rStrm >> maData.mnFlags;
+ break;
+
+ default:
+ bKnownType = false;
+ }
+
+ if( bKnownType )
+ mnRecId = nRecId;
+}
+
+void XclImpChType::Finalize( bool bStockChart )
+{
+ switch( mnRecId )
+ {
+ case EXC_ID_CHLINE:
+ maTypeInfo = GetChartTypeInfo( bStockChart ?
+ EXC_CHTYPEID_STOCK : EXC_CHTYPEID_LINE );
+ break;
+ case EXC_ID_CHBAR:
+ maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
+ maData.mnFlags, EXC_CHBAR_HORIZONTAL,
+ EXC_CHTYPEID_HORBAR, EXC_CHTYPEID_BAR ) );
+ break;
+ case EXC_ID_CHPIE:
+ maTypeInfo = GetChartTypeInfo( (maData.mnPieHole > 0) ?
+ EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
+ break;
+ case EXC_ID_CHSCATTER:
+ maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
+ maData.mnFlags, EXC_CHSCATTER_BUBBLES,
+ EXC_CHTYPEID_BUBBLES, EXC_CHTYPEID_SCATTER ) );
+ break;
+ default:
+ maTypeInfo = GetChartTypeInfo( mnRecId );
+ }
+
+ switch( maTypeInfo.meTypeId )
+ {
+ case EXC_CHTYPEID_PIEEXT:
+ case EXC_CHTYPEID_BUBBLES:
+ case EXC_CHTYPEID_SURFACE:
+ case EXC_CHTYPEID_UNKNOWN:
+ GetTracer().TraceChartUnKnownType();
+ break;
+ default:;
+ }
+}
+
+bool XclImpChType::IsStacked() const
+{
+ bool bStacked = false;
+ if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ bStacked =
+ ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
+ !::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ bStacked =
+ ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
+ !::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
+ break;
+ default:;
+ }
+ return bStacked;
+}
+
+bool XclImpChType::IsPercent() const
+{
+ bool bPercent = false;
+ if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_LINE:
+ bPercent =
+ ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
+ ::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
+ break;
+ case EXC_CHTYPECATEG_BAR:
+ bPercent =
+ ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
+ ::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
+ break;
+ default:;
+ }
+ return bPercent;
+}
+
+bool XclImpChType::HasCategoryLabels() const
+{
+ // radar charts disable category labels in chart type, not in CHTICK of X axis
+ return (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) || ::get_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS );
+}
+
+Reference< XCoordinateSystem > XclImpChType::CreateCoordSystem( bool b3dChart ) const
+{
+ // service name
+ OUString aCoordSysService;
+ if( maTypeInfo.mbPolarCoordSystem )
+ {
+ if( b3dChart )
+ aCoordSysService = SERVICE_CHART2_POLARCOORDSYS3D;
+ else
+ aCoordSysService = SERVICE_CHART2_POLARCOORDSYS2D;
+ }
+ else
+ {
+ if( b3dChart )
+ aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS3D;
+ else
+ aCoordSysService = SERVICE_CHART2_CARTESIANCOORDSYS2D;
+ }
+
+ // create the coordinate system object
+ Reference< XCoordinateSystem > xCoordSystem( ScfApiHelper::CreateInstance( aCoordSysService ), UNO_QUERY );
+
+ // swap X and Y axis
+ if( maTypeInfo.mbSwappedAxesSet )
+ {
+ ScfPropertySet aCoordSysProp( xCoordSystem );
+ aCoordSysProp.SetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS, true );
+ }
+
+ return xCoordSystem;
+}
+
+Reference< XChartType > XclImpChType::CreateChartType( Reference< XDiagram > xDiagram, bool b3dChart ) const
+{
+ OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
+ Reference< XChartType > xChartType( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
+
+ // additional properties
+ switch( maTypeInfo.meTypeCateg )
+ {
+ case EXC_CHTYPECATEG_BAR:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ Sequence< sal_Int32 > aInt32Seq( 2 );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = -maData.mnOverlap;
+ aTypeProp.SetProperty( EXC_CHPROP_OVERLAPSEQ, aInt32Seq );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = maData.mnGap;
+ aTypeProp.SetProperty( EXC_CHPROP_GAPWIDTHSEQ, aInt32Seq );
+ }
+ break;
+ case EXC_CHTYPECATEG_PIE:
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_USERINGS, maTypeInfo.meTypeId == EXC_CHTYPEID_DONUT );
+ /* #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( !b3dChart && (maTypeInfo.meTypeId != EXC_CHTYPEID_PIEEXT) )
+ {
+ ScfPropertySet aDiaProp( xDiagram );
+ XclImpChRoot::ConvertPieRotation( aDiaProp, maData.mnRotation );
+ }
+ }
+ break;
+ default:;
+ }
+
+ return xChartType;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpChChart3d::ReadChChart3d( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnRotation
+ >> maData.mnElevation
+ >> maData.mnEyeDist
+ >> maData.mnRelHeight
+ >> maData.mnRelDepth
+ >> maData.mnDepthGap
+ >> maData.mnFlags;
+}
+
+void XclImpChChart3d::Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+// #i104057# do not assert this, written by broken external generators
+// DBG_ASSERT( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" );
+
+ sal_Int32 nRotationY = 0;
+ sal_Int32 nRotationX = 0;
+ sal_Int32 nPerspective = 15;
+ bool bRightAngled = false;
+ cssd::ProjectionMode eProjMode = cssd::ProjectionMode_PERSPECTIVE;
+ Color aAmbientColor, aLightColor;
+
+ if( b3dWallChart )
+ {
+ // Y rotation (Excel [0..359], Chart2 [-179,180])
+ nRotationY = maData.mnRotation % 360;
+ if( nRotationY > 180 ) nRotationY -= 360;
+ // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
+ nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, -90, 90 );
+ // perspective (Excel and Chart2 [0,100])
+ nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
+ // right-angled axes
+ bRightAngled = !::get_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D );
+ // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
+ bool bParallel = bRightAngled || (nPerspective == 0);
+ eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
+ // ambient color (Gray 20%)
+ aAmbientColor.SetColor( RGB_COLORDATA( 204, 204, 204 ) );
+ // light color (Gray 60%)
+ aLightColor.SetColor( RGB_COLORDATA( 102, 102, 102 ) );
+ }
+ else
+ {
+ // Y rotation not used in pie charts, but 'first pie slice angle'
+ nRotationY = 0;
+ XclImpChRoot::ConvertPieRotation( rPropSet, maData.mnRotation );
+ // X rotation a.k.a. elevation (map Excel [10..80] to Chart2 [-80,-10])
+ nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, 10, 80 ) - 90;
+ // perspective (Excel and Chart2 [0,100])
+ nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
+ // no right-angled axes in pie charts, but parallel projection
+ bRightAngled = false;
+ eProjMode = cssd::ProjectionMode_PARALLEL;
+ // ambient color (Gray 30%)
+ aAmbientColor.SetColor( RGB_COLORDATA( 179, 179, 179 ) );
+ // light color (Gray 70%)
+ aLightColor.SetColor( RGB_COLORDATA( 76, 76, 76 ) );
+ }
+
+ // properties
+ rPropSet.SetProperty( EXC_CHPROP_ROTATIONVERTICAL, nRotationY );
+ rPropSet.SetProperty( EXC_CHPROP_ROTATIONHORIZONTAL, nRotationX );
+ rPropSet.SetProperty( EXC_CHPROP_PERSPECTIVE, nPerspective );
+ rPropSet.SetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES, bRightAngled );
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENEPERSPECTIVE, eProjMode );
+
+ // light settings
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENESHADEMODE, cssd::ShadeMode_FLAT );
+ rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENEAMBIENTCOLOR, aAmbientColor );
+ rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON1, false );
+ rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON2, true );
+ rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENELIGHTCOLOR2, aLightColor );
+ rPropSet.SetProperty( EXC_CHPROP_D3DSCENELIGHTDIR2, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChLegend::XclImpChLegend( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChLegend::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.maRect >> maData.mnDockMode >> maData.mnSpacing >> maData.mnFlags;
+
+ // trace unsupported features
+ if( GetTracer().IsEnabled() )
+ {
+ if( maData.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
+ GetTracer().TraceChartLegendPosition();
+ if( ::get_flag( maData.mnFlags, EXC_CHLEGEND_DATATABLE ) )
+ GetTracer().TraceChartDataTable();
+ }
+}
+
+void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ mxText.reset( new XclImpChText( GetChRoot() ) );
+ mxText->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChLegend::Finalize()
+{
+ // legend default formatting differs in OOChart and Excel, missing frame means automatic
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
+ // Update text formatting. If mxText is empty, the passed default text is used.
+ lclUpdateText( mxText, GetChartData().GetDefaultText( EXC_CHTEXTTYPE_LEGEND ) );
+}
+
+Reference< XLegend > XclImpChLegend::CreateLegend() const
+{
+ Reference< XLegend > xLegend( ScfApiHelper::CreateInstance( SERVICE_CHART2_LEGEND ), UNO_QUERY );
+ if( xLegend.is() )
+ {
+ ScfPropertySet aLegendProp( xLegend );
+ aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true );
+
+ // frame properties
+ if( mxFrame )
+ mxFrame->Convert( aLegendProp );
+ // text properties
+ if( mxText )
+ mxText->ConvertFont( aLegendProp );
+
+ /* Legend position and size. Default positions are used only if the
+ plot area is positioned automatically (Excel sets the plot area to
+ manual mode, if the legend is moved or resized). With manual plot
+ areas, Excel ignores the value in maData.mnDockMode completely. */
+ cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
+ cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
+ if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode )
+ {
+ case EXC_CHLEGEND_LEFT:
+ eApiPos = cssc2::LegendPosition_LINE_START;
+ eApiExpand = cssc::ChartLegendExpansion_HIGH;
+ break;
+ case EXC_CHLEGEND_RIGHT:
+ // top-right not supported
+ case EXC_CHLEGEND_CORNER:
+ eApiPos = cssc2::LegendPosition_LINE_END;
+ eApiExpand = cssc::ChartLegendExpansion_HIGH;
+ break;
+ case EXC_CHLEGEND_TOP:
+ eApiPos = cssc2::LegendPosition_PAGE_START;
+ eApiExpand = cssc::ChartLegendExpansion_WIDE;
+ break;
+ case EXC_CHLEGEND_BOTTOM:
+ eApiPos = cssc2::LegendPosition_PAGE_END;
+ eApiExpand = cssc::ChartLegendExpansion_WIDE;
+ break;
+ }
+
+ // no automatic position/size: try to find the correct position and size
+ if( eApiPos == cssc2::LegendPosition_CUSTOM )
+ {
+ const XclChFramePos* pFramePos = mxFramePos ? &mxFramePos->GetFramePosData() : 0;
+
+ /* Legend position. Only the settings from the CHFRAMEPOS record
+ are used by Excel, the position in the CHLEGEND record will be
+ ignored. */
+ if( pFramePos )
+ {
+ RelativePosition aRelPos(
+ CalcRelativeFromChartX( pFramePos->maRect.mnX ),
+ CalcRelativeFromChartY( pFramePos->maRect.mnY ),
+ ::com::sun::star::drawing::Alignment_TOP_LEFT );
+ aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos );
+ }
+ else
+ {
+ // no manual position/size found, just go for the default
+ eApiPos = cssc2::LegendPosition_LINE_END;
+ }
+
+ /* Legend size. The member mnBRMode specifies whether size is
+ automatic or changes manually. Manual size is given in points,
+ not in chart units. */
+ if( pFramePos && (pFramePos->mnBRMode == EXC_CHFRAMEPOS_ABSSIZE_POINTS) &&
+ (pFramePos->maRect.mnWidth > 0) && (pFramePos->maRect.mnHeight > 0) )
+ {
+ eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
+ sal_Int32 nWidthHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnWidth / EXC_POINTS_PER_HMM );
+ sal_Int32 nHeightHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnHeight / EXC_POINTS_PER_HMM );
+ RelativeSize aRelSize( CalcRelativeFromHmmX( nWidthHmm ), CalcRelativeFromHmmY( nHeightHmm ) );
+ aLegendProp.SetProperty( EXC_CHPROP_RELATIVESIZE, aRelSize );
+ }
+ else
+ {
+ // automatic size: determine entry direction from flags
+ eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED,
+ cssc::ChartLegendExpansion_HIGH, cssc::ChartLegendExpansion_WIDE );
+ }
+ }
+ aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos );
+ aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand );
+ }
+ return xLegend;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChDropBar::XclImpChDropBar( sal_uInt16 nDropBar ) :
+ mnDropBar( nDropBar ),
+ mnBarDist( 0 )
+{
+}
+
+void XclImpChDropBar::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> mnBarDist;
+}
+
+void XclImpChDropBar::Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
+{
+ XclChObjectType eObjType = EXC_CHOBJTYPE_BACKGROUND;
+ switch( mnDropBar )
+ {
+ case EXC_CHDROPBAR_UP: eObjType = EXC_CHOBJTYPE_WHITEDROPBAR; break;
+ case EXC_CHDROPBAR_DOWN: eObjType = EXC_CHOBJTYPE_BLACKDROPBAR; break;
+ }
+ ConvertFrameBase( rRoot, rPropSet, eObjType );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot ),
+ maType( rRoot ),
+ maTypeInfo( maType.GetTypeInfo() )
+{
+ // Initialize unused format indexes set. At this time, all formats are unused.
+ for( sal_uInt16 nFormatIdx = 0; nFormatIdx <= EXC_CHSERIES_MAXSERIES; ++nFormatIdx )
+ maUnusedFormats.insert( maUnusedFormats.end(), nFormatIdx );
+}
+
+void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 16 );
+ rStrm >> maData.mnFlags >> maData.mnGroupIdx;
+}
+
+void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHCHART3D:
+ mxChart3d.reset( new XclImpChChart3d );
+ mxChart3d->ReadChChart3d( rStrm );
+ break;
+ case EXC_ID_CHLEGEND:
+ mxLegend.reset( new XclImpChLegend( GetChRoot() ) );
+ mxLegend->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHDEFAULTTEXT:
+ GetChartData().ReadChDefaultText( rStrm );
+ break;
+ case EXC_ID_CHDROPBAR:
+ ReadChDropBar( rStrm );
+ break;
+ case EXC_ID_CHCHARTLINE:
+ ReadChChartLine( rStrm );
+ break;
+ case EXC_ID_CHDATAFORMAT:
+ ReadChDataFormat( rStrm );
+ break;
+ default:
+ maType.ReadChType( rStrm );
+ }
+}
+
+void XclImpChTypeGroup::Finalize()
+{
+ // check and set valid chart type
+ bool bStockChart =
+ (maType.GetRecId() == EXC_ID_CHLINE) && // must be a line chart
+ !mxChart3d && // must be a 2d chart
+ HasHiLoLine() && // must contain hi-lo lines
+ (maSeries.size() == static_cast<XclImpChSeriesVec::size_type>(HasDropBars() ? 4 : 3)); // correct series count
+ maType.Finalize( bStockChart );
+
+ // extended type info
+ maTypeInfo.Set( maType.GetTypeInfo(), mxChart3d, false );
+
+ // reverse series order for some unstacked 2D chart types
+ if( maTypeInfo.mbReverseSeries && !Is3dChart() && !maType.IsStacked() && !maType.IsPercent() )
+ ::std::reverse( maSeries.begin(), maSeries.end() );
+
+ // update chart type group format, may depend on chart type finalized above
+ if( mxGroupFmt )
+ mxGroupFmt->UpdateGroupFormat( maTypeInfo );
+}
+
+void XclImpChTypeGroup::AddSeries( XclImpChSeriesRef xSeries )
+{
+ if( xSeries )
+ maSeries.push_back( xSeries );
+ // store first inserted series separately, series order may be reversed later
+ if( !mxFirstSeries )
+ mxFirstSeries = xSeries;
+}
+
+void XclImpChTypeGroup::SetUsedFormatIndex( sal_uInt16 nFormatIdx )
+{
+ maUnusedFormats.erase( nFormatIdx );
+}
+
+sal_uInt16 XclImpChTypeGroup::PopUnusedFormatIndex()
+{
+ DBG_ASSERT( !maUnusedFormats.empty(), "XclImpChTypeGroup::PopUnusedFormatIndex - no more format indexes available" );
+ sal_uInt16 nFormatIdx = maUnusedFormats.empty() ? 0 : *maUnusedFormats.begin();
+ SetUsedFormatIndex( nFormatIdx );
+ return nFormatIdx;
+}
+
+bool XclImpChTypeGroup::HasVarPointFormat() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS ) &&
+ ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_MULTI) || // multiple series allowed
+ ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_SINGLE) && // or exactly 1 series?
+ (maSeries.size() == 1)));
+}
+
+bool XclImpChTypeGroup::HasConnectorLines() const
+{
+ // existence of connector lines (only in stacked bar charts)
+ if ( !(maType.IsStacked() || maType.IsPercent()) || (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
+ return false;
+ XclImpChLineFormatMap::const_iterator xConLine = maChartLines.find( EXC_CHCHARTLINE_CONNECT );
+ return ( xConLine != maChartLines.end() && xConLine->second->HasLine() );
+}
+
+const String& XclImpChTypeGroup::GetSingleSeriesTitle() const
+{
+ // no automatic title for series with trendlines or error bars
+ // pie charts always show an automatic title, even if more series exist
+ return (mxFirstSeries && !mxFirstSeries->HasChildSeries() && (maTypeInfo.mbSingleSeriesVis || (maSeries.size() == 1))) ?
+ mxFirstSeries->GetTitle() : String::EmptyString();
+}
+
+void XclImpChTypeGroup::ConvertChart3d( ScfPropertySet& rPropSet ) const
+{
+ if( mxChart3d )
+ mxChart3d->Convert( rPropSet, Is3dWallChart() );
+}
+
+Reference< XCoordinateSystem > XclImpChTypeGroup::CreateCoordSystem() const
+{
+ return maType.CreateCoordSystem( Is3dChart() );
+}
+
+Reference< XChartType > XclImpChTypeGroup::CreateChartType( Reference< XDiagram > xDiagram, sal_Int32 nApiAxesSetIdx ) const
+{
+ DBG_ASSERT( IsValidGroup(), "XclImpChTypeGroup::CreateChartType - type group without series" );
+
+ // create the chart type object
+ Reference< XChartType > xChartType = maType.CreateChartType( xDiagram, Is3dChart() );
+
+ // bar chart connector lines
+ if( HasConnectorLines() )
+ {
+ ScfPropertySet aDiaProp( xDiagram );
+ aDiaProp.SetBoolProperty( EXC_CHPROP_CONNECTBARS, true );
+ }
+
+ /* Stock chart needs special processing. Create one 'big' series with
+ data sequences of different roles. */
+ if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
+ CreateStockSeries( xChartType, nApiAxesSetIdx );
+ else
+ CreateDataSeries( xChartType, nApiAxesSetIdx );
+
+ return xChartType;
+}
+
+Reference< XLabeledDataSequence > XclImpChTypeGroup::CreateCategSequence() const
+{
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ // create category sequence from first visible series
+ if( mxFirstSeries )
+ xLabeledSeq = mxFirstSeries->CreateCategSequence( EXC_CHPROP_ROLE_CATEG );
+ return xLabeledSeq;
+}
+
+void XclImpChTypeGroup::ReadChDropBar( XclImpStream& rStrm )
+{
+ if (maDropBars.find(EXC_CHDROPBAR_UP) == maDropBars.end())
+ {
+ auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_UP));
+ p->ReadRecordGroup(rStrm);
+ maDropBars.insert(EXC_CHDROPBAR_UP, p);
+ }
+ else if(maDropBars.find(EXC_CHDROPBAR_DOWN) == maDropBars.end())
+ {
+ auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_DOWN));
+ p->ReadRecordGroup(rStrm);
+ maDropBars.insert(EXC_CHDROPBAR_DOWN, p);
+ }
+}
+
+void XclImpChTypeGroup::ReadChChartLine( XclImpStream& rStrm )
+{
+ sal_uInt16 nLineId = rStrm.ReaduInt16();
+ if( (rStrm.GetNextRecId() == EXC_ID_CHLINEFORMAT) && rStrm.StartNextRecord() )
+ {
+ XclImpChLineFormat xLineFmt;
+ xLineFmt.ReadChLineFormat( rStrm );
+ maChartLines[ nLineId ] = xLineFmt;
+ }
+}
+
+void XclImpChTypeGroup::ReadChDataFormat( XclImpStream& rStrm )
+{
+ // global series and data point format
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->ReadRecordGroup( rStrm );
+ const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
+ if( (rPos.mnSeriesIdx == 0) && (rPos.mnPointIdx == 0) &&
+ (xDataFmt->GetFormatIdx() == EXC_CHDATAFORMAT_DEFAULT) )
+ mxGroupFmt = xDataFmt;
+}
+
+
+void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType,
+ Reference< XDataSeries > xSeries, sal_Int32 nApiAxesSetIdx ) const
+{
+ Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
+ if( xSeriesCont.is() && xSeries.is() )
+ {
+ // series stacking mode
+ cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING;
+ // stacked overrides deep-3d
+ if( maType.IsStacked() || maType.IsPercent() )
+ eStacking = cssc2::StackingDirection_Y_STACKING;
+ else if( Is3dDeepChart() )
+ eStacking = cssc2::StackingDirection_Z_STACKING;
+
+ // additional series properties
+ ScfPropertySet aSeriesProp( xSeries );
+ aSeriesProp.SetProperty( EXC_CHPROP_STACKINGDIR, eStacking );
+ aSeriesProp.SetProperty( EXC_CHPROP_ATTAXISINDEX, nApiAxesSetIdx );
+
+ // insert series into container
+ try
+ {
+ xSeriesCont->addDataSeries( xSeries );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChTypeGroup::InsertDataSeries - cannot add data series" );
+ }
+ }
+}
+
+void XclImpChTypeGroup::CreateDataSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
+{
+ bool bSpline = false;
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
+ {
+ Reference< XDataSeries > xDataSeries = (*aIt)->CreateDataSeries();
+ InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
+ bSpline |= (*aIt)->HasSpline();
+ }
+ // spline - TODO: set at single series (#i66858#)
+ if( bSpline && !maTypeInfo.IsSeriesFrameFormat() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) )
+ {
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetProperty( EXC_CHPROP_CURVESTYLE, ::com::sun::star::chart2::CurveStyle_CUBIC_SPLINES );
+ }
+}
+
+void XclImpChTypeGroup::CreateStockSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
+{
+ // create the data series object
+ Reference< XDataSeries > xDataSeries( ScfApiHelper::CreateInstance( SERVICE_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;
+ DBG_ASSERT( maSeries.size() >= 3, "XclImpChTypeGroup::CreateChartType - missing stock series" );
+ int nRoleIdx = (maSeries.size() == 3) ? 1 : 0;
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end();
+ (nRoleIdx < 4) && (aIt != aEnd); ++nRoleIdx, ++aIt )
+ {
+ // create a data sequence with a specific role
+ OUString aRole;
+ switch( nRoleIdx )
+ {
+ case 0: aRole = EXC_CHPROP_ROLE_OPENVALUES; break;
+ case 1: aRole = EXC_CHPROP_ROLE_HIGHVALUES; break;
+ case 2: aRole = EXC_CHPROP_ROLE_LOWVALUES; break;
+ case 3: aRole = EXC_CHPROP_ROLE_CLOSEVALUES; 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( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
+
+ // formatting of special stock chart elements
+ ScfPropertySet aTypeProp( xChartType );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_JAPANESE, HasDropBars() );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWFIRST, HasDropBars() );
+ aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWHIGHLOW, true );
+ // hi-lo line format
+ XclImpChLineFormatMap::const_iterator xHiLoLine = maChartLines.find( EXC_CHCHARTLINE_HILO );
+ if ( xHiLoLine != maChartLines.end() )
+ {
+ ScfPropertySet aSeriesProp( xDataSeries );
+ xHiLoLine->second->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
+ }
+ // white dropbar format
+ XclImpChDropBarMap::const_iterator itr = maDropBars.find(EXC_CHDROPBAR_UP);
+ Reference<XPropertySet> xWhitePropSet;
+ if (itr != maDropBars.end() && aTypeProp.GetProperty(xWhitePropSet, EXC_CHPROP_WHITEDAY))
+ {
+ ScfPropertySet aBarProp( xWhitePropSet );
+ itr->second->Convert(GetChRoot(), aBarProp);
+ }
+ // black dropbar format
+ itr = maDropBars.find(EXC_CHDROPBAR_DOWN);
+ Reference<XPropertySet> xBlackPropSet;
+ if (itr != maDropBars.end() && aTypeProp.GetProperty(xBlackPropSet, EXC_CHPROP_BLACKDAY))
+ {
+ ScfPropertySet aBarProp( xBlackPropSet );
+ itr->second->Convert(GetChRoot(), aBarProp);
+ }
+
+ // insert the series into the chart type object
+ InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
+ }
+}
+
+// Axes =======================================================================
+
+XclImpChLabelRange::XclImpChLabelRange( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChLabelRange::ReadChLabelRange( XclImpStream& rStrm )
+{
+ rStrm >> maLabelData.mnCross >> maLabelData.mnLabelFreq >> maLabelData.mnTickFreq >> maLabelData.mnFlags;
+}
+
+void XclImpChLabelRange::ReadChDateRange( XclImpStream& rStrm )
+{
+ rStrm >> maDateData.mnMinDate
+ >> maDateData.mnMaxDate
+ >> maDateData.mnMajorStep
+ >> maDateData.mnMajorUnit
+ >> maDateData.mnMinorStep
+ >> maDateData.mnMinorUnit
+ >> maDateData.mnBaseUnit
+ >> maDateData.mnCross
+ >> maDateData.mnFlags;
+}
+
+void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const
+{
+ // automatic axis type detection
+ rScaleData.AutoDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE );
+
+ // the flag EXC_CHDATERANGE_DATEAXIS specifies whether this is a date axis
+ if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
+ {
+ /* Chart2 requires axis type CATEGORY for automatic category/date axis
+ (even if it is a date axis currently). */
+ rScaleData.AxisType = rScaleData.AutoDateAxis ? cssc2::AxisType::CATEGORY : cssc2::AxisType::DATE;
+ rScaleData.Scaling.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LINEARSCALING ), UNO_QUERY );
+ /* Min/max values depend on base time unit, they specify the number of
+ days, months, or years starting from null date. */
+ lclConvertTimeValue( GetRoot(), rScaleData.Minimum, maDateData.mnMinDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN ), maDateData.mnBaseUnit );
+ lclConvertTimeValue( GetRoot(), rScaleData.Maximum, maDateData.mnMaxDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX ), maDateData.mnBaseUnit );
+ // increment
+ cssc::TimeIncrement& rTimeIncrement = rScaleData.TimeIncrement;
+ lclConvertTimeInterval( rTimeIncrement.MajorTimeInterval, maDateData.mnMajorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR ), maDateData.mnMajorUnit );
+ lclConvertTimeInterval( rTimeIncrement.MinorTimeInterval, maDateData.mnMinorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR ), maDateData.mnMinorUnit );
+ // base unit
+ if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE ) )
+ rTimeIncrement.TimeResolution.clear();
+ else
+ rTimeIncrement.TimeResolution <<= lclGetApiTimeUnit( maDateData.mnBaseUnit );
+ }
+ else
+ {
+ // do not overlap text unless all labels are visible
+ rPropSet.SetBoolProperty( EXC_CHPROP_TEXTOVERLAP, maLabelData.mnLabelFreq == 1 );
+ // do not break text into several lines unless all labels are visible
+ rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maLabelData.mnLabelFreq == 1 );
+ // do not stagger labels in two lines
+ rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
+ }
+
+ // reverse order
+ bool bReverse = ::get_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient;
+ rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
+
+ //! TODO #i58731# show n-th category
+}
+
+void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const
+{
+ /* Crossing mode (max-cross flag overrides other crossing settings). Excel
+ does not move the Y axis in 3D charts, regardless of actual settings.
+ But: the Y axis has to be moved to "end", if the X axis is mirrored,
+ to keep it at the left end of the chart. */
+ bool bMaxCross = ::get_flag( maLabelData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS );
+ cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
+
+ // crossing position (depending on axis type text/date)
+ if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
+ {
+ bool bAutoCross = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
+ /* Crossing position value depends on base time unit, it specifies the
+ number of days, months, or years from null date. Note that Excel
+ 2007/2010 write broken BIFF8 files, they always stores the number
+ of days cregardless of the base time unit (and they are reading it
+ the same way, thus wrongly displaying files written by Excel
+ 97-2003). This filter sticks to the correct behaviour of Excel
+ 97-2003. */
+ double fCrossingPos = bAutoCross ? 1.0 : lclGetSerialDay( GetRoot(), maDateData.mnCross, maDateData.mnBaseUnit );
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
+ }
+ else
+ {
+ double fCrossingPos = b3dChart ? 1.0 : maLabelData.mnCross;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChValueRange::XclImpChValueRange( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChValueRange::ReadChValueRange( XclImpStream& rStrm )
+{
+ rStrm >> maData.mfMin
+ >> maData.mfMax
+ >> maData.mfMajorStep
+ >> maData.mfMinorStep
+ >> maData.mfCross
+ >> maData.mnFlags;
+}
+
+void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) const
+{
+ // scaling algorithm
+ bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
+ OUString aScalingService = bLogScale ? SERVICE_CHART2_LOGSCALING : SERVICE_CHART2_LINEARSCALING;
+ rScaleData.Scaling.set( ScfApiHelper::CreateInstance( aScalingService ), UNO_QUERY );
+
+ // min/max
+ lclSetExpValueOrClearAny( rScaleData.Minimum, maData.mfMin, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN ) );
+ lclSetExpValueOrClearAny( rScaleData.Maximum, maData.mfMax, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX ) );
+
+ // increment
+ bool bAutoMajor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR );
+ bool bAutoMinor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR );
+ // major increment
+ IncrementData& rIncrementData = rScaleData.IncrementData;
+ lclSetValueOrClearAny( rIncrementData.Distance, maData.mfMajorStep, bAutoMajor );
+ // minor increment
+ Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
+ rSubIncrementSeq.realloc( 1 );
+ Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
+ rIntervalCount.clear();
+ if( bLogScale )
+ {
+ if( !bAutoMinor )
+ rIntervalCount <<= sal_Int32( 9 );
+ }
+ else
+ {
+ if( !bAutoMajor && !bAutoMinor && (0.0 < maData.mfMinorStep) && (maData.mfMinorStep <= maData.mfMajorStep) )
+ {
+ double fCount = maData.mfMajorStep / maData.mfMinorStep + 0.5;
+ if( (1.0 <= fCount) && (fCount < 1001.0) )
+ rIntervalCount <<= static_cast< sal_Int32 >( fCount );
+ }
+ }
+
+ // reverse order
+ bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient;
+ rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
+}
+
+void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const
+{
+ bool bMaxCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
+ bool bAutoCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
+ bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
+
+ // crossing mode (max-cross flag overrides other crossing settings)
+ cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
+
+ // crossing position
+ double fCrossingPos = bAutoCross ? 0.0 : maData.mfCross;
+ if( bLogScale ) fCrossingPos = pow( 10.0, fCrossingPos );
+ rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos )
+{
+ using namespace ::com::sun::star::chart2::TickmarkStyle;
+ sal_Int32 nApiTickmarks = NONE;
+ ::set_flag( nApiTickmarks, INNER, ::get_flag( nXclTickPos, EXC_CHTICK_INSIDE ) );
+ ::set_flag( nApiTickmarks, OUTER, ::get_flag( nXclTickPos, EXC_CHTICK_OUTSIDE ) );
+ return nApiTickmarks;
+}
+
+cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
+{
+ using namespace ::com::sun::star::chart;
+ switch( nXclLabelPos )
+ {
+ case EXC_CHTICK_LOW: return ChartAxisLabelPosition_OUTSIDE_START;
+ case EXC_CHTICK_HIGH: return ChartAxisLabelPosition_OUTSIDE_END;
+ case EXC_CHTICK_NEXT: return ChartAxisLabelPosition_NEAR_AXIS;
+ }
+ return ChartAxisLabelPosition_NEAR_AXIS;
+}
+
+} // namespace
+
+XclImpChTick::XclImpChTick( const XclImpChRoot& rRoot ) :
+ XclImpChRoot( rRoot )
+{
+}
+
+void XclImpChTick::ReadChTick( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnMajor
+ >> maData.mnMinor
+ >> maData.mnLabelPos
+ >> maData.mnBackMode;
+ rStrm.Ignore( 16 );
+ rStrm >> maData.maTextColor
+ >> maData.mnFlags;
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ // BIFF8: index into palette used instead of RGB data
+ maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+ // rotation
+ rStrm >> maData.mnRotation;
+ }
+ else
+ {
+ // BIFF2-BIFF7: get rotation from text orientation
+ sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 2, 3 );
+ maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
+ }
+}
+
+Color XclImpChTick::GetFontColor() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
+}
+
+sal_uInt16 XclImpChTick::GetRotation() const
+{
+ return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOROT ) ? EXC_CHART_AUTOROTATION : maData.mnRotation;
+}
+
+void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const
+{
+ rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) );
+ rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) );
+ rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) );
+ rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) :
+ XclImpChRoot( rRoot ),
+ mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
+{
+ maData.mnType = nAxisType;
+}
+
+void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnType;
+}
+
+void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHLABELRANGE:
+ mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
+ mxLabelRange->ReadChLabelRange( rStrm );
+ break;
+ case EXC_ID_CHDATERANGE:
+ if( !mxLabelRange )
+ mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
+ mxLabelRange->ReadChDateRange( rStrm );
+ break;
+ case EXC_ID_CHVALUERANGE:
+ mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
+ mxValueRange->ReadChValueRange( rStrm );
+ break;
+ case EXC_ID_CHFORMAT:
+ rStrm >> mnNumFmtIdx;
+ break;
+ case EXC_ID_CHTICK:
+ mxTick.reset( new XclImpChTick( GetChRoot() ) );
+ mxTick->ReadChTick( rStrm );
+ break;
+ case EXC_ID_CHFONT:
+ mxFont.reset( new XclImpChFont );
+ mxFont->ReadChFont( rStrm );
+ break;
+ case EXC_ID_CHAXISLINE:
+ ReadChAxisLine( rStrm );
+ break;
+ }
+}
+
+void XclImpChAxis::Finalize()
+{
+ // add default scaling, needed e.g. to adjust rotation direction of pie and radar charts
+ if( !mxLabelRange )
+ mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
+ if( !mxValueRange )
+ mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
+ // remove invisible grid lines completely
+ if( mxMajorGrid && !mxMajorGrid->HasLine() )
+ mxMajorGrid.reset();
+ if( mxMinorGrid && !mxMinorGrid->HasLine() )
+ mxMinorGrid.reset();
+ // default tick settings different in OOChart and Excel
+ if( !mxTick )
+ mxTick.reset( new XclImpChTick( GetChRoot() ) );
+ // #i4140# different default axis line color
+ if( !mxAxisLine )
+ {
+ XclChLineFormat aLineFmt;
+ // set "show axis" flag, default if line format record is missing
+ ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS );
+ mxAxisLine.reset( new XclImpChLineFormat( aLineFmt ) );
+ }
+ // add wall/floor frame for 3d charts
+ if( !mxWallFrame )
+ CreateWallFrame();
+}
+
+sal_uInt16 XclImpChAxis::GetFontIndex() const
+{
+ return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+Color XclImpChAxis::GetFontColor() const
+{
+ return mxTick ? mxTick->GetFontColor() : GetFontAutoColor();
+}
+
+sal_uInt16 XclImpChAxis::GetRotation() const
+{
+ return mxTick ? mxTick->GetRotation() : EXC_CHART_AUTOROTATION;
+}
+
+Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const
+{
+ // create the axis object (always)
+ Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY );
+ if( xAxis.is() )
+ {
+ ScfPropertySet aAxisProp( xAxis );
+ // #i58688# axis enabled
+ aAxisProp.SetBoolProperty( EXC_CHPROP_SHOW, IsActivated() );
+
+ // axis line properties
+ if( mxAxisLine )
+ mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
+ // axis ticks properties
+ if( mxTick )
+ mxTick->Convert( aAxisProp );
+
+ // axis caption text --------------------------------------------------
+
+ // radar charts disable their category labels via chart type, not via axis
+ bool bHasLabels = HasLabels() &&
+ ((GetAxisType() != EXC_CHAXIS_X) || rTypeGroup.HasCategoryLabels());
+ aAxisProp.SetBoolProperty( EXC_CHPROP_DISPLAYLABELS, bHasLabels );
+ if( bHasLabels )
+ {
+ // font settings from CHFONT record or from default text
+ if( mxFont )
+ ConvertFontBase( GetChRoot(), aAxisProp );
+ else if( const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISLABEL ) )
+ pDefText->ConvertFont( aAxisProp );
+ // label text rotation
+ ConvertRotationBase( GetChRoot(), aAxisProp, true );
+ // number format
+ sal_uInt32 nScNumFmt = GetNumFmtBuffer().GetScFormat( mnNumFmtIdx );
+ if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+ aAxisProp.SetProperty( EXC_CHPROP_NUMBERFORMAT, static_cast< sal_Int32 >( nScNumFmt ) );
+ }
+
+ // axis scaling and increment -----------------------------------------
+
+ const XclChExtTypeInfo& rTypeInfo = rTypeGroup.GetTypeInfo();
+ ScaleData aScaleData = xAxis->getScaleData();
+ // set axis type
+ switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ if( rTypeInfo.mbCategoryAxis )
+ {
+ aScaleData.AxisType = cssc2::AxisType::CATEGORY;
+ aScaleData.Categories = rTypeGroup.CreateCategSequence();
+ }
+ else
+ aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
+ break;
+ case EXC_CHAXIS_Y:
+ aScaleData.AxisType = rTypeGroup.IsPercent() ?
+ cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
+ break;
+ case EXC_CHAXIS_Z:
+ aScaleData.AxisType = cssc2::AxisType::SERIES;
+ break;
+ }
+ // axis scaling settings, dependent on axis type
+ switch( aScaleData.AxisType )
+ {
+ case cssc2::AxisType::CATEGORY:
+ case cssc2::AxisType::SERIES:
+ // #i71684# radar charts have reversed rotation direction
+ mxLabelRange->Convert( aAxisProp, aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR );
+ break;
+ case cssc2::AxisType::REALNUMBER:
+ case cssc2::AxisType::PERCENT:
+ // #i85167# pie/donut charts have reversed rotation direction (at Y axis!)
+ mxValueRange->Convert( aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpChAxis::CreateAxis - unknown axis type" );
+ }
+
+ /* Do not set a value to the Origin member anymore (will be done via
+ new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
+ aScaleData.Origin.clear();
+
+ // write back
+ xAxis->setScaleData( aScaleData );
+
+ // grid ---------------------------------------------------------------
+
+ // main grid
+ ScfPropertySet aGridProp( xAxis->getGridProperties() );
+ aGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMajorGrid() );
+ if( mxMajorGrid )
+ mxMajorGrid->Convert( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ // sub grid
+ Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
+ if( aSubGridPropSeq.hasElements() )
+ {
+ ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
+ aSubGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMinorGrid() );
+ if( mxMinorGrid )
+ mxMinorGrid->Convert( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
+ }
+
+ // position of crossing axis ------------------------------------------
+
+ if( pCrossingAxis )
+ pCrossingAxis->ConvertAxisPosition( aAxisProp, rTypeGroup );
+ }
+ return xAxis;
+}
+
+void XclImpChAxis::ConvertWall( ScfPropertySet& rPropSet ) const
+{
+ if( mxWallFrame )
+ mxWallFrame->Convert( rPropSet );
+}
+
+void XclImpChAxis::ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const
+{
+ if( ((GetAxisType() == EXC_CHAXIS_X) && rTypeGroup.GetTypeInfo().mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z) )
+ mxLabelRange->ConvertAxisPosition( rPropSet, rTypeGroup.Is3dChart() );
+ else
+ mxValueRange->ConvertAxisPosition( rPropSet );
+}
+
+void XclImpChAxis::ReadChAxisLine( XclImpStream& rStrm )
+{
+ XclImpChLineFormatRef* pxLineFmt = 0;
+ bool bWallFrame = false;
+ switch( rStrm.ReaduInt16() )
+ {
+ case EXC_CHAXISLINE_AXISLINE: pxLineFmt = &mxAxisLine; break;
+ case EXC_CHAXISLINE_MAJORGRID: pxLineFmt = &mxMajorGrid; break;
+ case EXC_CHAXISLINE_MINORGRID: pxLineFmt = &mxMinorGrid; break;
+ case EXC_CHAXISLINE_WALLS: bWallFrame = true; break;
+ }
+ if( bWallFrame )
+ CreateWallFrame();
+
+ bool bLoop = pxLineFmt || bWallFrame;
+ while( bLoop )
+ {
+ sal_uInt16 nRecId = rStrm.GetNextRecId();
+ bLoop = ((nRecId == EXC_ID_CHLINEFORMAT) ||
+ (nRecId == EXC_ID_CHAREAFORMAT) ||
+ (nRecId == EXC_ID_CHESCHERFORMAT))
+ && rStrm.StartNextRecord();
+ if( bLoop )
+ {
+ if( pxLineFmt && (nRecId == EXC_ID_CHLINEFORMAT) )
+ {
+ pxLineFmt->reset( new XclImpChLineFormat );
+ (*pxLineFmt)->ReadChLineFormat( rStrm );
+ }
+ else if( bWallFrame && mxWallFrame )
+ {
+ mxWallFrame->ReadSubRecord( rStrm );
+ }
+ }
+ }
+}
+
+void XclImpChAxis::CreateWallFrame()
+{
+ switch( GetAxisType() )
+ {
+ case EXC_CHAXIS_X:
+ mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_WALL3D ) );
+ break;
+ case EXC_CHAXIS_Y:
+ mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_FLOOR3D ) );
+ break;
+ default:
+ mxWallFrame.reset();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChAxesSet::XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
+ XclImpChRoot( rRoot )
+{
+ maData.mnAxesSetId = nAxesSetId;
+}
+
+void XclImpChAxesSet::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnAxesSetId >> maData.maRect;
+}
+
+void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAMEPOS:
+ mxFramePos.reset( new XclImpChFramePos );
+ mxFramePos->ReadChFramePos( rStrm );
+ break;
+ case EXC_ID_CHAXIS:
+ ReadChAxis( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ ReadChText( rStrm );
+ break;
+ case EXC_ID_CHPLOTFRAME:
+ ReadChPlotFrame( rStrm );
+ break;
+ case EXC_ID_CHTYPEGROUP:
+ ReadChTypeGroup( rStrm );
+ break;
+ }
+}
+
+void XclImpChAxesSet::Finalize()
+{
+ if( IsValidAxesSet() )
+ {
+ // finalize chart type groups, erase empty groups without series
+ XclImpChTypeGroupMap aValidGroups;
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
+ {
+ XclImpChTypeGroupRef xTypeGroup = aIt->second;
+ xTypeGroup->Finalize();
+ if( xTypeGroup->IsValidGroup() )
+ aValidGroups.insert(
+ XclImpChTypeGroupMap::value_type(aIt->first, xTypeGroup));
+ }
+ maTypeGroups.swap( aValidGroups );
+ }
+
+ // invalid chart type groups are deleted now, check again with IsValidAxesSet()
+ if( IsValidAxesSet() )
+ {
+ // always create missing axis objects
+ if( !mxXAxis )
+ mxXAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_X ) );
+ if( !mxYAxis )
+ mxYAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Y ) );
+ if( !mxZAxis && GetFirstTypeGroup()->Is3dDeepChart() )
+ mxZAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Z ) );
+
+ // finalize axes
+ if( mxXAxis ) mxXAxis->Finalize();
+ if( mxYAxis ) mxYAxis->Finalize();
+ if( mxZAxis ) mxZAxis->Finalize();
+
+ // finalize axis titles
+ const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE );
+ String aAutoTitle = CREATE_STRING( "Axis Title" );
+ lclFinalizeTitle( mxXAxisTitle, pDefText, aAutoTitle );
+ lclFinalizeTitle( mxYAxisTitle, pDefText, aAutoTitle );
+ lclFinalizeTitle( mxZAxisTitle, pDefText, aAutoTitle );
+
+ // #i47745# missing plot frame -> invisible border and area
+ if( !mxPlotFrame )
+ mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
+ }
+}
+
+XclImpChTypeGroupRef XclImpChAxesSet::GetTypeGroup( sal_uInt16 nGroupIdx ) const
+{
+ XclImpChTypeGroupMap::const_iterator itr = maTypeGroups.find(nGroupIdx);
+ return itr == maTypeGroups.end() ? XclImpChTypeGroupRef() : itr->second;
+}
+
+XclImpChTypeGroupRef XclImpChAxesSet::GetFirstTypeGroup() const
+{
+ XclImpChTypeGroupRef xTypeGroup;
+ if( !maTypeGroups.empty() )
+ xTypeGroup = maTypeGroups.begin()->second;
+ return xTypeGroup;
+}
+
+XclImpChLegendRef XclImpChAxesSet::GetLegend() const
+{
+ XclImpChLegendRef xLegend;
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); !xLegend && (aIt != aEnd); ++aIt )
+ xLegend = aIt->second->GetLegend();
+ return xLegend;
+}
+
+const String& XclImpChAxesSet::GetSingleSeriesTitle() const
+{
+ return (maTypeGroups.size() == 1) ? maTypeGroups.begin()->second->GetSingleSeriesTitle() : String::EmptyString();
+}
+
+void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const
+{
+ if( IsValidAxesSet() && xDiagram.is() )
+ {
+ // diagram background formatting
+ if( GetAxesSetId() == EXC_CHAXESSET_PRIMARY )
+ ConvertBackground( xDiagram );
+
+ // create the coordinate system, this inserts all chart types and series
+ Reference< XCoordinateSystem > xCoordSystem = CreateCoordSystem( xDiagram );
+ if( xCoordSystem.is() )
+ {
+ // insert coordinate system, if not already done
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
+ if( aCoordSystems.getLength() == 0 )
+ xCoordSystemCont->addCoordinateSystem( xCoordSystem );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::Convert - cannot insert coordinate system" );
+ }
+
+ // create the axes with grids and axis titles and insert them into the diagram
+ ConvertAxis( mxXAxis, mxXAxisTitle, xCoordSystem, mxYAxis.get() );
+ ConvertAxis( mxYAxis, mxYAxisTitle, xCoordSystem, mxXAxis.get() );
+ ConvertAxis( mxZAxis, mxZAxisTitle, xCoordSystem, 0 );
+ }
+ }
+}
+
+void XclImpChAxesSet::ConvertTitlePositions() const
+{
+ if( mxXAxisTitle )
+ mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) );
+ if( mxYAxisTitle )
+ mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) );
+ if( mxZAxisTitle )
+ mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) );
+}
+
+void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm )
+{
+ XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) );
+ xAxis->ReadRecordGroup( rStrm );
+
+ switch( xAxis->GetAxisType() )
+ {
+ case EXC_CHAXIS_X: mxXAxis = xAxis; break;
+ case EXC_CHAXIS_Y: mxYAxis = xAxis; break;
+ case EXC_CHAXIS_Z: mxZAxis = xAxis; break;
+ }
+}
+
+void XclImpChAxesSet::ReadChText( XclImpStream& rStrm )
+{
+ XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
+ xText->ReadRecordGroup( rStrm );
+
+ switch( xText->GetLinkTarget() )
+ {
+ case EXC_CHOBJLINK_XAXIS: mxXAxisTitle = xText; break;
+ case EXC_CHOBJLINK_YAXIS: mxYAxisTitle = xText; break;
+ case EXC_CHOBJLINK_ZAXIS: mxZAxisTitle = xText; break;
+ }
+}
+
+void XclImpChAxesSet::ReadChPlotFrame( XclImpStream& rStrm )
+{
+ if( (rStrm.GetNextRecId() == EXC_ID_CHFRAME) && rStrm.StartNextRecord() )
+ {
+ mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
+ mxPlotFrame->ReadRecordGroup( rStrm );
+ }
+}
+
+void XclImpChAxesSet::ReadChTypeGroup( XclImpStream& rStrm )
+{
+ XclImpChTypeGroupRef xTypeGroup( new XclImpChTypeGroup( GetChRoot() ) );
+ xTypeGroup->ReadRecordGroup( rStrm );
+ sal_uInt16 nGroupIdx = xTypeGroup->GetGroupIdx();
+ XclImpChTypeGroupMap::iterator itr = maTypeGroups.lower_bound(nGroupIdx);
+ if (itr != maTypeGroups.end() && !maTypeGroups.key_comp()(nGroupIdx, itr->first))
+ // Overwrite the existing element.
+ itr->second = xTypeGroup;
+ else
+ maTypeGroups.insert(
+ itr, XclImpChTypeGroupMap::value_type(nGroupIdx, xTypeGroup));
+}
+
+Reference< XCoordinateSystem > XclImpChAxesSet::CreateCoordSystem( Reference< XDiagram > xDiagram ) const
+{
+ Reference< XCoordinateSystem > xCoordSystem;
+
+ /* Try to get existing ccordinate system. For now, all series from primary
+ and secondary axes sets are inserted into one coordinate system. Later,
+ this should be changed to use one coordinate system for each axes set. */
+ Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY );
+ if( xCoordSystemCont.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
+ DBG_ASSERT( aCoordSystems.getLength() <= 1, "XclImpChAxesSet::CreateCoordSystem - too many existing coordinate systems" );
+ if( aCoordSystems.getLength() > 0 )
+ xCoordSystem = aCoordSystems[ 0 ];
+ }
+
+ // create the coordinate system according to the first chart type
+ if( !xCoordSystem.is() )
+ {
+ XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup )
+ {
+ xCoordSystem = xTypeGroup->CreateCoordSystem();
+ // convert 3d chart settings
+ ScfPropertySet aDiaProp( xDiagram );
+ xTypeGroup->ConvertChart3d( aDiaProp );
+ }
+ }
+
+ /* Create XChartType objects for all chart type groups. Each group will
+ add its series to the data provider attached to the chart document. */
+ Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
+ if( xChartTypeCont.is() )
+ {
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
+ {
+ try
+ {
+ Reference< XChartType > xChartType = aIt->second->CreateChartType( xDiagram, nApiAxesSetIdx );
+ if( xChartType.is() )
+ xChartTypeCont->addChartType( xChartType );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::CreateCoordSystem - cannot add chart type" );
+ }
+ }
+ }
+
+ return xCoordSystem;
+}
+
+void XclImpChAxesSet::ConvertAxis(
+ XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
+ Reference< XCoordinateSystem > xCoordSystem, const XclImpChAxis* pCrossingAxis ) const
+{
+ if( xChAxis )
+ {
+ // create and attach the axis object
+ Reference< XAxis > xAxis = CreateAxis( *xChAxis, pCrossingAxis );
+ if( xAxis.is() )
+ {
+ // create and attach the axis title
+ if( xChAxisTitle ) try
+ {
+ Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
+ Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW );
+ xTitled->setTitleObject( xTitle );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis title" );
+ }
+
+ // insert axis into coordinate system
+ try
+ {
+ sal_Int32 nApiAxisDim = xChAxis->GetApiAxisDimension();
+ sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
+ xCoordSystem->setAxisByDimension( nApiAxisDim, xAxis, nApiAxesSetIdx );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis" );
+ }
+ }
+ }
+}
+
+Reference< XAxis > XclImpChAxesSet::CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const
+{
+ Reference< XAxis > xAxis;
+ if( const XclImpChTypeGroup* pTypeGroup = GetFirstTypeGroup().get() )
+ xAxis = rChAxis.CreateAxis( *pTypeGroup, pCrossingAxis );
+ return xAxis;
+}
+
+void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const
+{
+ XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
+ if( xTypeGroup && xTypeGroup->Is3dWallChart() )
+ {
+ // wall/floor formatting (3D charts)
+ if( mxXAxis )
+ {
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxXAxis->ConvertWall( aWallProp );
+ }
+ if( mxYAxis )
+ {
+ ScfPropertySet aFloorProp( xDiagram->getFloor() );
+ mxYAxis->ConvertWall( aFloorProp );
+ }
+ }
+ else if( mxPlotFrame )
+ {
+ // diagram background formatting
+ ScfPropertySet aWallProp( xDiagram->getWall() );
+ mxPlotFrame->Convert( aWallProp );
+ }
+}
+
+// The chart object ===========================================================
+
+XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) :
+ XclImpChRoot( rRoot, *this )
+{
+ mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
+ mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
+}
+
+XclImpChChart::~XclImpChChart()
+{
+}
+
+void XclImpChChart::ReadHeaderRecord( XclImpStream& rStrm )
+{
+ // coordinates are stored as 16.16 fixed point
+ rStrm >> maRect;
+}
+
+void XclImpChChart::ReadSubRecord( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_CHFRAME:
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ mxFrame->ReadRecordGroup( rStrm );
+ break;
+ case EXC_ID_CHSERIES:
+ ReadChSeries( rStrm );
+ break;
+ case EXC_ID_CHPROPERTIES:
+ ReadChProperties( rStrm );
+ break;
+ case EXC_ID_CHDEFAULTTEXT:
+ ReadChDefaultText( rStrm );
+ break;
+ case EXC_ID_CHAXESSET:
+ ReadChAxesSet( rStrm );
+ break;
+ case EXC_ID_CHTEXT:
+ ReadChText( rStrm );
+ break;
+ case EXC_ID_CHEND:
+ Finalize(); // finalize the entire chart object
+ break;
+ }
+}
+
+void XclImpChChart::ReadChDefaultText( XclImpStream& rStrm )
+{
+ sal_uInt16 nTextId = rStrm.ReaduInt16();
+ if( (rStrm.GetNextRecId() == EXC_ID_CHTEXT) && rStrm.StartNextRecord() )
+ {
+ auto_ptr<XclImpChText> pText(new XclImpChText(GetChRoot()));
+ pText->ReadRecordGroup(rStrm);
+ maDefTexts.insert(nTextId, pText);
+ }
+}
+
+void XclImpChChart::ReadChDataFormat( XclImpStream& rStrm )
+{
+ XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
+ xDataFmt->ReadRecordGroup( rStrm );
+ if( xDataFmt->GetPointPos().mnSeriesIdx <= EXC_CHSERIES_MAXSERIES )
+ {
+ const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
+ XclImpChDataFormatMap::iterator itr = maDataFmts.lower_bound(rPos);
+ if (itr == maDataFmts.end() || maDataFmts.key_comp()(rPos, itr->first))
+ // No element exists for this data point. Insert it.
+ maDataFmts.insert(
+ itr, XclImpChDataFormatMap::value_type(rPos, xDataFmt));
+
+ /* Do not overwrite existing data format group, Excel always uses the
+ first data format group occuring in any CHSERIES group. */
+ }
+}
+
+void XclImpChChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ mxFrame->UpdateObjFrame( rLineData, rFillData );
+}
+
+XclImpChTypeGroupRef XclImpChChart::GetTypeGroup( sal_uInt16 nGroupIdx ) const
+{
+ XclImpChTypeGroupRef xTypeGroup = mxPrimAxesSet->GetTypeGroup( nGroupIdx );
+ if( !xTypeGroup ) xTypeGroup = mxSecnAxesSet->GetTypeGroup( nGroupIdx );
+ if( !xTypeGroup ) xTypeGroup = mxPrimAxesSet->GetFirstTypeGroup();
+ return xTypeGroup;
+}
+
+const XclImpChText* XclImpChChart::GetDefaultText( XclChTextType eTextType ) const
+{
+ sal_uInt16 nDefTextId = EXC_CHDEFTEXT_GLOBAL;
+ bool bBiff8 = GetBiff() == EXC_BIFF8;
+ switch( eTextType )
+ {
+ case EXC_CHTEXTTYPE_TITLE: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_LEGEND: nDefTextId = EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_AXISTITLE: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_AXISLABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ case EXC_CHTEXTTYPE_DATALABEL: nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
+ }
+
+ XclImpChTextMap::const_iterator itr = maDefTexts.find(nDefTextId);
+ return itr == maDefTexts.end() ? NULL : itr->second;
+}
+
+bool XclImpChChart::IsManualPlotArea() const
+{
+ // there is no real automatic mode in BIFF5 charts
+ return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
+}
+
+void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc,
+ XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
+{
+ // initialize conversion (locks the model to suppress any internal updates)
+ InitConversion( xChartDoc, rChartRect );
+
+ // chart frame formatting
+ if( mxFrame )
+ {
+ ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
+ mxFrame->Convert( aFrameProp );
+ }
+
+ // chart title
+ if( mxTitle ) try
+ {
+ Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW );
+ Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW );
+ xTitled->setTitleObject( xTitle );
+ }
+ catch( Exception& )
+ {
+ }
+
+ /* Create the diagram object and attach it to the chart document. Currently,
+ one diagram is used to carry all coordinate systems and data series. */
+ Reference< XDiagram > xDiagram = CreateDiagram();
+ xChartDoc->setFirstDiagram( xDiagram );
+
+ // coordinate systems and chart types, convert axis settings
+ mxPrimAxesSet->Convert( xDiagram );
+ mxSecnAxesSet->Convert( xDiagram );
+
+ // legend
+ if( xDiagram.is() && mxLegend )
+ xDiagram->setLegend( mxLegend->CreateLegend() );
+
+ /* Following all conversions needing the old Chart1 API that involves full
+ initialization of the chart view. */
+ Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY );
+ if( xChart1Doc.is() )
+ {
+ Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram();
+
+ /* Set the 'IncludeHiddenCells' property via the old API as only this
+ ensures that the data provider and all created sequences get this
+ flag correctly. */
+ ScfPropertySet aDiaProp( xDiagram1 );
+ bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY );
+ aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
+
+ // plot area position and size (there is no real automatic mode in BIFF5 charts)
+ XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos();
+ if( IsManualPlotArea() && xPlotAreaPos ) try
+ {
+ const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData();
+ if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) )
+ {
+ Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW );
+ ::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect );
+ // for pie charts, always set inner plot area size to exclude the data labels as Excel does
+ const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get();
+ if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) )
+ xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
+ else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() )
+ xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect );
+ else
+ xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // positions of all title objects
+ if( mxTitle )
+ mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) );
+ mxPrimAxesSet->ConvertTitlePositions();
+ mxSecnAxesSet->ConvertTitlePositions();
+ }
+
+ // unlock the model
+ FinishConversion( rDffConv );
+
+ // start listening to this chart
+ ScDocument& rDoc = GetRoot().GetDoc();
+ if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() )
+ {
+ ::std::auto_ptr< ::std::vector< ScTokenRef > > xRefTokens( new ::std::vector< ScTokenRef > );
+ for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
+ (*aIt)->FillAllSourceLinks( *xRefTokens );
+ if( !xRefTokens->empty() )
+ {
+ ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) );
+ xListener->SetUsed( true );
+ xListener->StartListeningTo();
+ pChartCollection->Insert( xListener.release() );
+ }
+ }
+}
+
+void XclImpChChart::ReadChSeries( XclImpStream& rStrm )
+{
+ sal_uInt16 nNewSeriesIdx = static_cast< sal_uInt16 >( maSeries.size() );
+ XclImpChSeriesRef xSeries( new XclImpChSeries( GetChRoot(), nNewSeriesIdx ) );
+ xSeries->ReadRecordGroup( rStrm );
+ maSeries.push_back( xSeries );
+}
+
+void XclImpChChart::ReadChProperties( XclImpStream& rStrm )
+{
+ rStrm >> maProps.mnFlags >> maProps.mnEmptyMode;
+}
+
+void XclImpChChart::ReadChAxesSet( XclImpStream& rStrm )
+{
+ XclImpChAxesSetRef xAxesSet( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_NONE ) );
+ xAxesSet->ReadRecordGroup( rStrm );
+ switch( xAxesSet->GetAxesSetId() )
+ {
+ case EXC_CHAXESSET_PRIMARY: mxPrimAxesSet = xAxesSet; break;
+ case EXC_CHAXESSET_SECONDARY: mxSecnAxesSet = xAxesSet; break;
+ }
+}
+
+void XclImpChChart::ReadChText( XclImpStream& rStrm )
+{
+ XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
+ xText->ReadRecordGroup( rStrm );
+ switch( xText->GetLinkTarget() )
+ {
+ case EXC_CHOBJLINK_TITLE:
+ mxTitle = xText;
+ break;
+ case EXC_CHOBJLINK_DATA:
+ {
+ sal_uInt16 nSeriesIdx = xText->GetPointPos().mnSeriesIdx;
+ if( nSeriesIdx < maSeries.size() )
+ maSeries[ nSeriesIdx ]->SetDataLabel( xText );
+ }
+ break;
+ }
+}
+
+void XclImpChChart::Finalize()
+{
+ // finalize series (must be done first)
+ FinalizeSeries();
+ // #i49218# legend may be attached to primary or secondary axes set
+ mxLegend = mxPrimAxesSet->GetLegend();
+ if( !mxLegend )
+ mxLegend = mxSecnAxesSet->GetLegend();
+ if( mxLegend )
+ mxLegend->Finalize();
+ // axes sets, updates chart type group default formats -> must be called before FinalizeDataFormats()
+ mxPrimAxesSet->Finalize();
+ mxSecnAxesSet->Finalize();
+ // formatting of all series
+ FinalizeDataFormats();
+ // #i47745# missing frame -> invisible border and area
+ if( !mxFrame )
+ mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
+ // chart title
+ FinalizeTitle();
+}
+
+void XclImpChChart::FinalizeSeries()
+{
+ for( XclImpChSeriesVec::iterator aSIt = maSeries.begin(), aSEnd = maSeries.end(); aSIt != aSEnd; ++aSIt )
+ {
+ XclImpChSeriesRef xSeries = *aSIt;
+ if( xSeries->HasParentSeries() )
+ {
+ /* Process child series (trend lines and error bars). Data of
+ child series will be set at the connected parent series. */
+ if( xSeries->GetParentIdx() < maSeries.size() )
+ maSeries[ xSeries->GetParentIdx() ]->AddChildSeries( *xSeries );
+ }
+ else
+ {
+ // insert the series into the related chart type group
+ if( XclImpChTypeGroup* pTypeGroup = GetTypeGroup( xSeries->GetGroupIdx() ).get() )
+ pTypeGroup->AddSeries( xSeries );
+ }
+ }
+}
+
+void XclImpChChart::FinalizeDataFormats()
+{
+ /* #i51639# (part 1): CHDATAFORMAT groups are part of CHSERIES groups.
+ Each CHDATAFORMAT group specifies the series and data point it is
+ assigned to. This makes it possible to have a data format that is
+ related to another series, e.g. a CHDATAFORMAT group for series 2 is
+ part of a CHSERIES group that describes series 1. Therefore the chart
+ itself has collected all CHDATAFORMAT groups to be able to store data
+ format groups for series that have not been imported at that time. This
+ loop finally assigns these groups to the related series. */
+ for( XclImpChDataFormatMap::const_iterator aMIt = maDataFmts.begin(), aMEnd = maDataFmts.end(); aMIt != aMEnd; ++aMIt )
+ {
+ sal_uInt16 nSeriesIdx = aMIt->first.mnSeriesIdx;
+ if( nSeriesIdx < maSeries.size() )
+ maSeries[ nSeriesIdx ]->SetDataFormat( aMIt->second );
+ }
+
+ /* #i51639# (part 2): Finalize data formats of all series. This adds for
+ example missing CHDATAFORMAT groups for entire series that are needed
+ for automatic colors of lines and areas. */
+ for( XclImpChSeriesVec::iterator aVIt = maSeries.begin(), aVEnd = maSeries.end(); aVIt != aVEnd; ++aVIt )
+ (*aVIt)->FinalizeDataFormats();
+}
+
+void XclImpChChart::FinalizeTitle()
+{
+ // special handling for auto-generated title
+ String aAutoTitle;
+ if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) )
+ {
+ // automatic title from first series name (if there are no series on secondary axes set)
+ if( !mxSecnAxesSet->IsValidAxesSet() )
+ aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle();
+ if( mxTitle || (aAutoTitle.Len() > 0) )
+ {
+ if( !mxTitle )
+ mxTitle.reset( new XclImpChText( GetChRoot() ) );
+ if( aAutoTitle.Len() == 0 )
+ aAutoTitle = CREATE_STRING( "Chart Title" );
+ }
+ }
+
+ // will reset mxTitle, if it does not contain a string and no auto title exists
+ lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle );
+}
+
+Reference< XDiagram > XclImpChChart::CreateDiagram() const
+{
+ // create a diagram object
+ Reference< XDiagram > xDiagram( ScfApiHelper::CreateInstance( SERVICE_CHART2_DIAGRAM ), UNO_QUERY );
+
+ // convert global chart settings
+ ScfPropertySet aDiaProp( xDiagram );
+
+ // treatment of missing values
+ using namespace cssc::MissingValueTreatment;
+ sal_Int32 nMissingValues = LEAVE_GAP;
+ switch( maProps.mnEmptyMode )
+ {
+ case EXC_CHPROPS_EMPTY_SKIP: nMissingValues = LEAVE_GAP; break;
+ case EXC_CHPROPS_EMPTY_ZERO: nMissingValues = USE_ZERO; break;
+ case EXC_CHPROPS_EMPTY_INTERPOLATE: nMissingValues = CONTINUE; break;
+ }
+ aDiaProp.SetProperty( EXC_CHPROP_MISSINGVALUETREATMENT, nMissingValues );
+
+ return xDiagram;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects
+ mnScTab( rRoot.GetCurrScTab() ),
+ mbOwnTab( bOwnTab )
+{
+}
+
+void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv,
+ const Reference< XModel >& rxModel, const Rectangle& rChartRect )
+{
+ maChartRect = rChartRect; // needed in CalcAnchorRect() callback
+
+ SdrModel* pSdrModel = 0;
+ SdrPage* pSdrPage = 0;
+ if( mbOwnTab )
+ {
+ // chart sheet: insert all shapes into the sheet, not into the chart object
+ pSdrModel = GetDoc().GetDrawLayer();
+ pSdrPage = GetSdrPage( mnScTab );
+ }
+ else
+ {
+ // embedded chart object: insert all shapes into the chart
+ try
+ {
+ Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW );
+ pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage );
+ pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ if( pSdrModel && pSdrPage )
+ ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
+}
+
+Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const
+{
+ /* In objects with DFF client anchor, the position of the shape is stored
+ in the cell address components of the client anchor. In old BIFF3-BIFF5
+ objects, the position is stored in the offset components of the anchor. */
+ Rectangle aRect(
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
+ static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) );
+ aRect.Justify();
+ // move shapes into chart area for sheet charts
+ if( mbOwnTab )
+ aRect.Move( maChartRect.Left(), maChartRect.Top() );
+ return aRect;
+}
+
+void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpRoot( rRoot ),
+ mbOwnTab( bOwnTab ),
+ mbIsPivotChart( false )
+{
+}
+
+XclImpChart::~XclImpChart()
+{
+}
+
+void XclImpChart::ReadChartSubStream( XclImpStream& rStrm )
+{
+ XclImpPageSettings& rPageSett = GetPageSettings();
+ XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
+
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ // page settings - only for charts in entire sheet
+ if( mbOwnTab ) switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HORPAGEBREAKS:
+ case EXC_ID_VERPAGEBREAKS: rPageSett.ReadPageBreaks( rStrm ); break;
+ case EXC_ID_HEADER:
+ case EXC_ID_FOOTER: rPageSett.ReadHeaderFooter( rStrm ); break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN: rPageSett.ReadMargin( rStrm ); break;
+ case EXC_ID_PRINTHEADERS: rPageSett.ReadPrintHeaders( rStrm ); break;
+ case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( rStrm ); break;
+ case EXC_ID_HCENTER:
+ case EXC_ID_VCENTER: rPageSett.ReadCenter( rStrm ); break;
+ case EXC_ID_SETUP: rPageSett.ReadSetup( rStrm ); break;
+ case EXC_ID8_IMGDATA: rPageSett.ReadImgData( rStrm ); break;
+
+ case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( rStrm, true );break;
+ case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break;
+
+ case EXC_ID_SHEETEXT: //0x0862
+ {
+ // FIXME: do not need to pass palette, XclImpTabVieSettings is derived from root
+ XclImpPalette& rPal = GetPalette();
+ rTabViewSett.ReadTabBgColor( rStrm, rPal);
+ }
+ break;
+
+ case EXC_ID_CODENAME: ReadCodeName( rStrm, false ); break;
+ }
+
+ // common records
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_EOF: bLoop = false; break;
+
+ // #i31882# ignore embedded chart objects
+ case EXC_ID2_BOF:
+ case EXC_ID3_BOF:
+ case EXC_ID4_BOF:
+ case EXC_ID5_BOF: XclTools::SkipSubStream( rStrm ); break;
+
+ case EXC_ID_CHCHART: ReadChChart( rStrm ); break;
+
+ case EXC_ID8_CHPIVOTREF:
+ GetTracer().TracePivotChartExists();
+ mbIsPivotChart = true;
+ break;
+
+ // BIFF specific records
+ default: switch( GetBiff() )
+ {
+ case EXC_BIFF5: switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
+ }
+ break;
+ case EXC_BIFF8: switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm ); break;
+ // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
+ case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break;
+ }
+ break;
+ default:;
+ }
+ }
+ }
+}
+
+void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
+{
+ if( !mxChartData )
+ mxChartData.reset( new XclImpChChart( GetRoot() ) );
+ mxChartData->UpdateObjFrame( rLineData, rFillData );
+}
+
+sal_Size XclImpChart::GetProgressSize() const
+{
+ return
+ (mxChartData ? mxChartData->GetProgressSize() : 0) +
+ (mxChartDrawing ? mxChartDrawing->GetProgressSize() : 0);
+}
+
+void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
+{
+ Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
+ if( xChartDoc.is() )
+ {
+ if( mxChartData )
+ mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect );
+ if( mxChartDrawing )
+ mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect );
+ }
+}
+
+XclImpChartDrawing& XclImpChart::GetChartDrawing()
+{
+ if( !mxChartDrawing )
+ mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) );
+ return *mxChartDrawing;
+}
+
+void XclImpChart::ReadChChart( XclImpStream& rStrm )
+{
+ mxChartData.reset( new XclImpChChart( GetRoot() ) );
+ mxChartData->ReadRecordGroup( rStrm );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
new file mode 100644
index 000000000000..07bfb4e239fa
--- /dev/null
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -0,0 +1,1329 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xicontent.hxx"
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svl/itemset.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include "document.hxx"
+#include "editutil.hxx"
+#include "cell.hxx"
+#include "validat.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "rangenam.hxx"
+#include "arealink.hxx"
+#include "stlsheet.hxx"
+#include "scextopt.hxx"
+#include "xlformula.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xistyle.hxx"
+#include "xiescher.hxx"
+#include "xiname.hxx"
+
+#include "excform.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
+
+// Shared string table ========================================================
+
+XclImpSst::XclImpSst( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpSst::ReadSst( XclImpStream& rStrm )
+{
+ sal_uInt32 nStrCount;
+ rStrm.Ignore( 4 );
+ rStrm >> nStrCount;
+ maStrings.clear();
+ maStrings.reserve( static_cast< size_t >( nStrCount ) );
+ while( (nStrCount > 0) && rStrm.IsValid() )
+ {
+ XclImpString aString;
+ aString.Read( rStrm );
+ maStrings.push_back( aString );
+ --nStrCount;
+ }
+}
+
+const XclImpString* XclImpSst::GetString( sal_uInt32 nSstIndex ) const
+{
+ return (nSstIndex < maStrings.size()) ? &maStrings[ nSstIndex ] : 0;
+}
+
+ScBaseCell* XclImpSst::CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex ) const
+{
+ ScBaseCell* pCell = 0;
+ if( const XclImpString* pString = GetString( nSstIndex ) )
+ pCell = XclImpStringHelper::CreateCell( *this, *pString, nXFIndex );
+ return pCell;
+}
+
+// Hyperlinks =================================================================
+
+namespace {
+
+/** Reads character array and stores it into rString.
+ @param nChars Number of following characters (not byte count!).
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclAppendString32( String& rString, XclImpStream& rStrm, sal_uInt32 nChars, bool b16Bit )
+{
+ sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
+ rString.Append( rStrm.ReadRawUniString( nReadChars, b16Bit ) );
+ // ignore remaining chars
+ sal_Size nIgnore = nChars - nReadChars;
+ if( b16Bit )
+ nIgnore *= 2;
+ rStrm.Ignore( nIgnore );
+}
+
+/** Reads 32-bit string length and the character array and stores it into rString.
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclAppendString32( String& rString, XclImpStream& rStrm, bool b16Bit )
+{
+ lclAppendString32( rString, rStrm, rStrm.ReaduInt32(), b16Bit );
+}
+
+/** Reads 32-bit string length and ignores following character array.
+ @param b16Bit true = 16-bit characters, false = 8-bit characters. */
+void lclIgnoreString32( XclImpStream& rStrm, bool b16Bit )
+{
+ sal_uInt32 nChars;
+ rStrm >> nChars;
+ if( b16Bit )
+ nChars *= 2;
+ rStrm.Ignore( nChars );
+}
+
+/** Converts a path to an absolute path.
+ @param rPath The source path. The resulting path is returned here.
+ @param nLevel Number of parent directories to add in front of the path. */
+void lclGetAbsPath( String& rPath, sal_uInt16 nLevel, SfxObjectShell* pDocShell )
+{
+ String aTmpStr;
+ while( nLevel )
+ {
+ aTmpStr.AppendAscii( "../" );
+ --nLevel;
+ }
+ aTmpStr += rPath;
+
+ if( pDocShell )
+ {
+ bool bWasAbs = false;
+ rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
+ // full path as stored in SvxURLField must be encoded
+ }
+ else
+ rPath = aTmpStr;
+}
+
+/** Inserts the URL into a text cell. Does not modify value or formula cells. */
+void lclInsertUrl( const XclImpRoot& rRoot, const String& rUrl, SCCOL nScCol, SCROW nScRow, SCTAB nScTab )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ ScAddress aScPos( nScCol, nScRow, nScTab );
+ CellType eCellType = rDoc.GetCellType( aScPos );
+ switch( eCellType )
+ {
+ // #i54261# hyperlinks in string cells
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ String aDisplText;
+ rDoc.GetString( nScCol, nScRow, nScTab, aDisplText );
+ if( !aDisplText.Len() )
+ aDisplText = rUrl;
+
+ ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
+ SvxURLField aUrlField( rUrl, aDisplText, SVXURLFORMAT_APPDEFAULT );
+
+ const ScEditCell* pEditCell = (eCellType == CELLTYPE_EDIT) ? static_cast< const ScEditCell* >( rDoc.GetCell( aScPos ) ) : 0;
+ const EditTextObject* pEditObj = pEditCell ? pEditCell->GetData() : 0;
+ if( pEditObj )
+ {
+ rEE.SetText( *pEditObj );
+ rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection( 0, 0, 0xFFFF, 0 ) );
+ }
+ else
+ {
+ rEE.SetText( EMPTY_STRING );
+ rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection() );
+ if( const ScPatternAttr* pPattern = rDoc.GetPattern( aScPos.Col(), aScPos.Row(), nScTab ) )
+ {
+ SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
+ pPattern->FillEditItemSet( &aItemSet );
+ rEE.QuickSetAttribs( aItemSet, ESelection( 0, 0, 0xFFFF, 0 ) );
+ }
+ }
+ ::std::auto_ptr< EditTextObject > xTextObj( rEE.CreateTextObject() );
+
+ ScEditCell* pCell = new ScEditCell( xTextObj.get(), &rDoc, rEE.GetEditTextObjectPool() );
+ rDoc.PutCell( aScPos, pCell );
+ }
+ break;
+
+ default:;
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+void XclImpHyperlink::ReadHlink( XclImpStream& rStrm )
+{
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ rStrm >> aXclRange;
+ // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
+ aXclRange.maFirst.mnCol &= 0xFF;
+ aXclRange.maLast.mnCol &= 0xFF;
+ String aString = ReadEmbeddedData( rStrm );
+ if ( aString.Len() > 0 )
+ rStrm.GetRoot().GetXFRangeBuffer().SetHyperlink( aXclRange, aString );
+}
+
+String XclImpHyperlink::ReadEmbeddedData( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ SfxObjectShell* pDocShell = rRoot.GetDocShell();
+
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ sal_uInt32 nFlags;
+ XclGuid aGuid;
+ rStrm >> aGuid;
+ rStrm.Ignore( 4 );
+ rStrm >> nFlags;
+
+ DBG_ASSERT( aGuid == XclTools::maGuidStdLink, "XclImpHyperlink::ReadEmbeddedData - unknown header GUID" );
+
+ ::std::auto_ptr< String > xLongName; // link / file name
+ ::std::auto_ptr< String > xShortName; // 8.3-representation of file name
+ ::std::auto_ptr< String > xTextMark; // text mark
+
+ // description (ignore)
+ if( ::get_flag( nFlags, EXC_HLINK_DESCR ) )
+ lclIgnoreString32( rStrm, true );
+ // target frame (ignore) !! DESCR/FRAME - is this the right order? (never seen them together)
+ if( ::get_flag( nFlags, EXC_HLINK_FRAME ) )
+ lclIgnoreString32( rStrm, true );
+
+ // URL fields are zero-terminated - do not let the stream replace them
+ // in the lclAppendString32() with the '?' character.
+ rStrm.SetNulSubstChar( '\0' );
+
+ // UNC path
+ if( ::get_flag( nFlags, EXC_HLINK_UNC ) )
+ {
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, true );
+ lclGetAbsPath( *xLongName, 0, pDocShell );
+ }
+ // file link or URL
+ else if( ::get_flag( nFlags, EXC_HLINK_BODY ) )
+ {
+ rStrm >> aGuid;
+
+ if( aGuid == XclTools::maGuidFileMoniker )
+ {
+ sal_uInt16 nLevel = 0; // counter for level to climb down in path
+ rStrm >> nLevel;
+ xShortName.reset( new String );
+ lclAppendString32( *xShortName, rStrm, false );
+ rStrm.Ignore( 24 );
+
+ sal_uInt32 nStrLen;
+ rStrm >> nStrLen;
+ if( nStrLen )
+ {
+ rStrm >> nStrLen;
+ nStrLen /= 2; // it's byte count here...
+ rStrm.Ignore( 2 );
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, nStrLen, true );
+ lclGetAbsPath( *xLongName, nLevel, pDocShell );
+ }
+ else
+ lclGetAbsPath( *xShortName, nLevel, pDocShell );
+ }
+ else if( aGuid == XclTools::maGuidUrlMoniker )
+ {
+ sal_uInt32 nStrLen;
+ rStrm >> nStrLen;
+ nStrLen /= 2; // it's byte count here...
+ xLongName.reset( new String );
+ lclAppendString32( *xLongName, rStrm, nStrLen, true );
+ if( !::get_flag( nFlags, EXC_HLINK_ABS ) )
+ lclGetAbsPath( *xLongName, 0, pDocShell );
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclImpHyperlink::ReadEmbeddedData - unknown content GUID" );
+ }
+ }
+
+ // text mark
+ if( ::get_flag( nFlags, EXC_HLINK_MARK ) )
+ {
+ xTextMark.reset( new String );
+ lclAppendString32( *xTextMark, rStrm, true );
+ }
+
+ rStrm.SetNulSubstChar(); // back to default
+
+ DBG_ASSERT( rStrm.GetRecLeft() == 0, "XclImpHyperlink::ReadEmbeddedData - record size mismatch" );
+
+ if( !xLongName.get() && xShortName.get() )
+ xLongName = xShortName;
+ else if( !xLongName.get() && xTextMark.get() )
+ xLongName.reset( new String );
+
+ if( xLongName.get() )
+ {
+ if( xTextMark.get() )
+ {
+ if( xLongName->Len() == 0 )
+ xTextMark->SearchAndReplaceAll( '!', '.' );
+ xLongName->Append( '#' );
+ xLongName->Append( *xTextMark );
+ }
+ return *xLongName;
+ }
+ return String::EmptyString();
+}
+
+void XclImpHyperlink::ConvertToValidTabName(String& rUrl)
+{
+ xub_StrLen n = rUrl.Len();
+ if (n < 4)
+ // Needs at least 4 characters.
+ return;
+
+ sal_Unicode c = rUrl.GetChar(0);
+ if (c != sal_Unicode('#'))
+ // the 1st character must be '#'.
+ return;
+
+ String aNewUrl(sal_Unicode('#')), aTabName;
+
+ bool bInQuote = false;
+ bool bQuoteTabName = false;
+ for (xub_StrLen i = 1; i < n; ++i)
+ {
+ c = rUrl.GetChar(i);
+ if (c == sal_Unicode('\''))
+ {
+ if (bInQuote && i+1 < n && rUrl.GetChar(i+1) == sal_Unicode('\''))
+ {
+ // Two consecutive single quotes ('') signify a single literal
+ // quite. When this occurs, the whole table name needs to be
+ // quoted.
+ bQuoteTabName = true;
+ aTabName.Append(c);
+ aTabName.Append(c);
+ ++i;
+ continue;
+ }
+
+ bInQuote = !bInQuote;
+ if (!bInQuote && aTabName.Len() > 0)
+ {
+ if (bQuoteTabName)
+ aNewUrl.Append(sal_Unicode('\''));
+ aNewUrl.Append(aTabName);
+ if (bQuoteTabName)
+ aNewUrl.Append(sal_Unicode('\''));
+ }
+ }
+ else if (bInQuote)
+ aTabName.Append(c);
+ else
+ aNewUrl.Append(c);
+ }
+
+ if (bInQuote)
+ // It should be outside the quotes!
+ return;
+
+ // All is good. Pass the new URL.
+ rUrl = aNewUrl;
+}
+
+void XclImpHyperlink::InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl )
+{
+ String aUrl(rUrl);
+ ConvertToValidTabName(aUrl);
+
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( rRoot.GetAddressConverter().ConvertRange( aScRange, rXclRange, nScTab, nScTab, true ) )
+ {
+ SCCOL nScCol1, nScCol2;
+ SCROW nScRow1, nScRow2;
+ aScRange.GetVars( nScCol1, nScRow1, nScTab, nScCol2, nScRow2, nScTab );
+ for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
+ for( SCROW nScRow = nScRow1; nScRow <= nScRow2; ++nScRow )
+ lclInsertUrl( rRoot, aUrl, nScCol, nScRow, nScTab );
+ }
+}
+
+// Label ranges ===============================================================
+
+void XclImpLabelranges::ReadLabelranges( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ XclImpAddressConverter& rAddrConv = rRoot.GetAddressConverter();
+ ScRangePairListRef xLabelRangesRef;
+ const ScRange* pScRange = 0;
+
+ XclRangeList aRowXclRanges, aColXclRanges;
+ rStrm >> aRowXclRanges >> aColXclRanges;
+
+ // row label ranges
+ ScRangeList aRowScRanges;
+ rAddrConv.ConvertRangeList( aRowScRanges, aRowXclRanges, nScTab, false );
+ xLabelRangesRef = rDoc.GetRowNameRangesRef();
+ for ( size_t i = 0, nRanges = aRowScRanges.size(); i < nRanges; ++i )
+ {
+ pScRange = aRowScRanges[ i ];
+ ScRange aDataRange( *pScRange );
+ if( aDataRange.aEnd.Col() < MAXCOL )
+ {
+ aDataRange.aStart.SetCol( aDataRange.aEnd.Col() + 1 );
+ aDataRange.aEnd.SetCol( MAXCOL );
+ }
+ else if( aDataRange.aStart.Col() > 0 )
+ {
+ aDataRange.aEnd.SetCol( aDataRange.aStart.Col() - 1 );
+ aDataRange.aStart.SetCol( 0 );
+ }
+ xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
+ }
+
+ // column label ranges
+ ScRangeList aColScRanges;
+ rAddrConv.ConvertRangeList( aColScRanges, aColXclRanges, nScTab, false );
+ xLabelRangesRef = rDoc.GetColNameRangesRef();
+
+ for ( size_t i = 0, nRanges = aColScRanges.size(); i < nRanges; ++i )
+ {
+ pScRange = aColScRanges[ i ];
+ ScRange aDataRange( *pScRange );
+ if( aDataRange.aEnd.Row() < MAXROW )
+ {
+ aDataRange.aStart.SetRow( aDataRange.aEnd.Row() + 1 );
+ aDataRange.aEnd.SetRow( MAXROW );
+ }
+ else if( aDataRange.aStart.Row() > 0 )
+ {
+ aDataRange.aEnd.SetRow( aDataRange.aStart.Row() - 1 );
+ aDataRange.aStart.SetRow( 0 );
+ }
+ xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
+ }
+}
+
+// Conditional formatting =====================================================
+
+XclImpCondFormat::XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex ) :
+ XclImpRoot( rRoot ),
+ mnFormatIndex( nFormatIndex ),
+ mnCondCount( 0 ),
+ mnCondIndex( 0 )
+{
+}
+
+XclImpCondFormat::~XclImpCondFormat()
+{
+}
+
+void XclImpCondFormat::ReadCondfmt( XclImpStream& rStrm )
+{
+ DBG_ASSERT( !mnCondCount, "XclImpCondFormat::ReadCondfmt - already initialized" );
+ XclRangeList aXclRanges;
+ rStrm >> mnCondCount;
+ rStrm.Ignore( 10 );
+ rStrm >> aXclRanges;
+ GetAddressConverter().ConvertRangeList( maRanges, aXclRanges, GetCurrScTab(), true );
+}
+
+void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
+{
+ if( mnCondIndex >= mnCondCount )
+ {
+ DBG_ERRORFILE( "XclImpCondFormat::ReadCF - CF without leading CONDFMT" );
+ return;
+ }
+
+ // entire conditional format outside of valid range?
+ if( maRanges.empty() )
+ return;
+
+ sal_uInt8 nType, nOperator;
+ sal_uInt16 nFmlaSize1, nFmlaSize2;
+ sal_uInt32 nFlags;
+
+ rStrm >> nType >> nOperator >> nFmlaSize1 >> nFmlaSize2 >> nFlags;
+ rStrm.Ignore( 2 );
+
+ // *** mode and comparison operator ***
+
+ ScConditionMode eMode = SC_COND_NONE;
+ switch( nType )
+ {
+ case EXC_CF_TYPE_CELL:
+ {
+ switch( nOperator )
+ {
+ case EXC_CF_CMP_BETWEEN: eMode = SC_COND_BETWEEN; break;
+ case EXC_CF_CMP_NOT_BETWEEN: eMode = SC_COND_NOTBETWEEN; break;
+ case EXC_CF_CMP_EQUAL: eMode = SC_COND_EQUAL; break;
+ case EXC_CF_CMP_NOT_EQUAL: eMode = SC_COND_NOTEQUAL; break;
+ case EXC_CF_CMP_GREATER: eMode = SC_COND_GREATER; break;
+ case EXC_CF_CMP_LESS: eMode = SC_COND_LESS; break;
+ case EXC_CF_CMP_GREATER_EQUAL: eMode = SC_COND_EQGREATER; break;
+ case EXC_CF_CMP_LESS_EQUAL: eMode = SC_COND_EQLESS; break;
+ default:
+ OSL_TRACE( "XclImpCondFormat::ReadCF - unknown CF comparison 0x%02hX", nOperator );
+ }
+ }
+ break;
+
+ case EXC_CF_TYPE_FMLA:
+ eMode = SC_COND_DIRECT;
+ break;
+
+ default:
+ OSL_TRACE( "XclImpCondFormat::ReadCF - unknown CF mode 0x%02hX", nType );
+ return;
+ }
+
+ // *** create style sheet ***
+
+ String aStyleName( XclTools::GetCondFormatStyleName( GetCurrScTab(), mnFormatIndex, mnCondIndex ) );
+ SfxItemSet& rStyleItemSet = ScfTools::MakeCellStyleSheet( GetStyleSheetPool(), aStyleName, true ).GetItemSet();
+
+ const XclImpPalette& rPalette = GetPalette();
+
+ // *** font block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_FONT ) )
+ {
+ XclImpFont aFont( GetRoot() );
+ aFont.ReadCFFontBlock( rStrm );
+ aFont.FillToItemSet( rStyleItemSet, EXC_FONTITEM_CELL );
+ }
+
+ // *** border block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_BORDER ) )
+ {
+ sal_uInt16 nLineStyle;
+ sal_uInt32 nLineColor;
+ rStrm >> nLineStyle >> nLineColor;
+ rStrm.Ignore( 2 );
+
+ XclImpCellBorder aBorder;
+ aBorder.FillFromCF8( nLineStyle, nLineColor, nFlags );
+ aBorder.FillToItemSet( rStyleItemSet, rPalette );
+ }
+
+ // *** pattern block ***
+
+ if( ::get_flag( nFlags, EXC_CF_BLOCK_AREA ) )
+ {
+ sal_uInt16 nPattern, nColor;
+ rStrm >> nPattern >> nColor;
+
+ XclImpCellArea aArea;
+ aArea.FillFromCF8( nPattern, nColor, nFlags );
+ aArea.FillToItemSet( rStyleItemSet, rPalette );
+ }
+
+ // *** formulas ***
+
+ const ScAddress& rPos = maRanges.front()->aStart; // assured above that maRanges is not empty
+ ExcelToSc& rFmlaConv = GetOldFmlaConverter();
+
+ ::std::auto_ptr< ScTokenArray > xTokArr1;
+ if( nFmlaSize1 > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset( rPos );
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr1.reset( pTokArr->Clone() );
+ }
+
+ ::std::auto_ptr< ScTokenArray > pTokArr2;
+ if( nFmlaSize2 > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset( rPos );
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ pTokArr2.reset( pTokArr->Clone() );
+ }
+
+ // *** create the Calc conditional formatting ***
+
+ if( !mxScCondFmt.get() )
+ {
+ sal_uLong nKey = 0;
+ mxScCondFmt.reset( new ScConditionalFormat( nKey, GetDocPtr() ) );
+ }
+
+ ScCondFormatEntry aEntry( eMode, xTokArr1.get(), pTokArr2.get(), GetDocPtr(), rPos, aStyleName );
+ mxScCondFmt->AddEntry( aEntry );
+ ++mnCondIndex;
+}
+
+void XclImpCondFormat::Apply()
+{
+ if( mxScCondFmt.get() )
+ {
+ ScDocument& rDoc = GetDoc();
+
+ sal_uLong nKey = rDoc.AddCondFormat( *mxScCondFmt );
+ ScPatternAttr aPattern( rDoc.GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nKey ) );
+
+ // maRanges contains only valid cell ranges
+ for ( size_t i = 0, nRanges = maRanges.size(); i < nRanges; ++i )
+ {
+ const ScRange* pScRange = maRanges[ i ];
+ rDoc.ApplyPatternAreaTab(
+ pScRange->aStart.Col(), pScRange->aStart.Row(),
+ pScRange->aEnd.Col(), pScRange->aEnd.Row(),
+ pScRange->aStart.Tab(), aPattern );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCondFormatManager::XclImpCondFormatManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpCondFormatManager::ReadCondfmt( XclImpStream& rStrm )
+{
+ XclImpCondFormat* pFmt = new XclImpCondFormat( GetRoot(), maCondFmtList.size() );
+ pFmt->ReadCondfmt( rStrm );
+ maCondFmtList.push_back( pFmt );
+}
+
+void XclImpCondFormatManager::ReadCF( XclImpStream& rStrm )
+{
+ DBG_ASSERT( !maCondFmtList.empty(), "XclImpCondFormatManager::ReadCF - CF without leading CONDFMT" );
+ if( !maCondFmtList.empty() )
+ maCondFmtList.back().ReadCF( rStrm );
+}
+
+void XclImpCondFormatManager::Apply()
+{
+ for( XclImpCondFmtList::iterator itFmt = maCondFmtList.begin(); itFmt != maCondFmtList.end(); ++itFmt )
+ itFmt->Apply();
+ maCondFmtList.clear();
+}
+
+// Data Validation ============================================================
+
+XclImpValidationManager::DVItem::DVItem( const ScRangeList& rRanges, const ScValidationData& rValidData ) :
+ maRanges(rRanges), maValidData(rValidData) {}
+
+XclImpValidationManager::XclImpValidationManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpValidationManager::ReadDval( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ sal_uInt32 nObjId;
+ rStrm.Ignore( 10 );
+ rStrm >> nObjId;
+ if( nObjId != EXC_DVAL_NOOBJ )
+ {
+ DBG_ASSERT( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" );
+ rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) );
+ }
+}
+
+void XclImpValidationManager::ReadDV( XclImpStream& rStrm )
+{
+ const XclImpRoot& rRoot = rStrm.GetRoot();
+ DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ SCTAB nScTab = rRoot.GetCurrScTab();
+ ExcelToSc& rFmlaConv = rRoot.GetOldFmlaConverter();
+
+ // flags
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+
+ // message strings
+ /* Empty strings are single NUL characters in Excel (string length is 1).
+ -> Do not let the stream replace them with '?' characters. */
+ rStrm.SetNulSubstChar( '\0' );
+ String aPromptTitle( rStrm.ReadUniString() );
+ String aErrorTitle( rStrm.ReadUniString() );
+ String aPromptMessage( rStrm.ReadUniString() );
+ String aErrorMessage( rStrm.ReadUniString() );
+ rStrm.SetNulSubstChar(); // back to default
+
+ // formula(s)
+ if ( rStrm.GetRecLeft() <= 8 )
+ // Not enough bytes left in the record. Bail out.
+ return;
+
+ sal_uInt16 nLen;
+
+ // first formula
+ // string list is single tStr token with NUL separators -> replace them with LF
+ rStrm.SetNulSubstChar( '\n' );
+ ::std::auto_ptr< ScTokenArray > xTokArr1;
+ rStrm >> nLen;
+ rStrm.Ignore( 2 );
+ if( nLen > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset();
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr1.reset( pTokArr->Clone() );
+ }
+ rStrm.SetNulSubstChar(); // back to default
+
+ // second formula
+ ::std::auto_ptr< ScTokenArray > xTokArr2;
+ rStrm >> nLen;
+ rStrm.Ignore( 2 );
+ if( nLen > 0 )
+ {
+ const ScTokenArray* pTokArr = 0;
+ rFmlaConv.Reset();
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ // formula converter owns pTokArr -> create a copy of the token array
+ if( pTokArr )
+ xTokArr2.reset( pTokArr->Clone() );
+ }
+
+ // read all cell ranges
+ XclRangeList aXclRanges;
+ rStrm >> aXclRanges;
+
+ // convert to Calc range list
+ ScRangeList aScRanges;
+ rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
+
+ // only continue if there are valid ranges
+ if ( aScRanges.empty() )
+ return;
+
+ bool bIsValid = true; // valid settings in flags field
+
+ ScValidationMode eValMode = SC_VALID_ANY;
+ switch( nFlags & EXC_DV_MODE_MASK )
+ {
+ case EXC_DV_MODE_ANY: eValMode = SC_VALID_ANY; break;
+ case EXC_DV_MODE_WHOLE: eValMode = SC_VALID_WHOLE; break;
+ case EXC_DV_MODE_DECIMAL: eValMode = SC_VALID_DECIMAL; break;
+ case EXC_DV_MODE_LIST: eValMode = SC_VALID_LIST; break;
+ case EXC_DV_MODE_DATE: eValMode = SC_VALID_DATE; break;
+ case EXC_DV_MODE_TIME: eValMode = SC_VALID_TIME; break;
+ case EXC_DV_MODE_TEXTLEN: eValMode = SC_VALID_TEXTLEN; break;
+ case EXC_DV_MODE_CUSTOM: eValMode = SC_VALID_CUSTOM; break;
+ default: bIsValid = false;
+ }
+ rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
+
+ ScConditionMode eCondMode = SC_COND_BETWEEN;
+ switch( nFlags & EXC_DV_COND_MASK )
+ {
+ case EXC_DV_COND_BETWEEN: eCondMode = SC_COND_BETWEEN; break;
+ case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
+ case EXC_DV_COND_EQUAL: eCondMode = SC_COND_EQUAL; break;
+ case EXC_DV_COND_NOTEQUAL: eCondMode = SC_COND_NOTEQUAL; break;
+ case EXC_DV_COND_GREATER: eCondMode = SC_COND_GREATER; break;
+ case EXC_DV_COND_LESS: eCondMode = SC_COND_LESS; break;
+ case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER; break;
+ case EXC_DV_COND_EQLESS: eCondMode = SC_COND_EQLESS; break;
+ default: bIsValid = false;
+ }
+
+ if ( !bIsValid )
+ // No valid validation found. Bail out.
+ return;
+
+
+ // first range for base address for relative references
+ const ScRange& rScRange = *aScRanges.front(); // aScRanges is not empty
+
+ // process string list of a list validity (convert to list of string tokens)
+ if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
+ XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
+
+ maDVItems.push_back(
+ new DVItem(aScRanges, ScValidationData(eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart)));
+ DVItem& rItem = maDVItems.back();
+
+ rItem.maValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
+ rItem.maValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
+
+ // *** prompt box ***
+ if( aPromptTitle.Len() || aPromptMessage.Len() )
+ {
+ // set any text stored in the record
+ rItem.maValidData.SetInput( aPromptTitle, aPromptMessage );
+ if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
+ rItem.maValidData.ResetInput();
+ }
+
+ // *** error box ***
+ ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
+ switch( nFlags & EXC_DV_ERROR_MASK )
+ {
+ case EXC_DV_ERROR_WARNING: eErrStyle = SC_VALERR_WARNING; break;
+ case EXC_DV_ERROR_INFO: eErrStyle = SC_VALERR_INFO; break;
+ }
+ // set texts and error style
+ rItem.maValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
+ if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
+ rItem.maValidData.ResetError();
+}
+
+void XclImpValidationManager::Apply()
+{
+ ScDocument& rDoc = GetRoot().GetDoc();
+ DVItemList::iterator itr = maDVItems.begin(), itrEnd = maDVItems.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ DVItem& rItem = *itr;
+ // set the handle ID
+ sal_uLong nHandle = rDoc.AddValidationEntry( rItem.maValidData );
+ ScPatternAttr aPattern( rDoc.GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
+
+ // apply all ranges
+ for ( size_t i = 0, nRanges = rItem.maRanges.size(); i < nRanges; ++i )
+ {
+ const ScRange* pScRange = rItem.maRanges[ i ];
+ rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
+ pScRange->aEnd.Col(), pScRange->aEnd.Row(), pScRange->aStart.Tab(), aPattern );
+ }
+ }
+ maDVItems.clear();
+}
+
+// Web queries ================================================================
+
+XclImpWebQuery::XclImpWebQuery( const ScRange& rDestRange ) :
+ maDestRange( rDestRange ),
+ meMode( xlWQUnknown ),
+ mnRefresh( 0 )
+{
+}
+
+void XclImpWebQuery::ReadParamqry( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags = rStrm.ReaduInt16();
+ sal_uInt16 nType = ::extract_value< sal_uInt16 >( nFlags, 0, 3 );
+ if( (nType == EXC_PQRYTYPE_WEBQUERY) && ::get_flag( nFlags, EXC_PQRY_WEBQUERY ) )
+ {
+ if( ::get_flag( nFlags, EXC_PQRY_TABLES ) )
+ {
+ meMode = xlWQAllTables;
+ maTables = ScfTools::GetHTMLTablesName();
+ }
+ else
+ {
+ meMode = xlWQDocument;
+ maTables = ScfTools::GetHTMLDocName();
+ }
+ }
+}
+
+void XclImpWebQuery::ReadWqstring( XclImpStream& rStrm )
+{
+ maURL = rStrm.ReadUniString();
+}
+
+void XclImpWebQuery::ReadWqsettings( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> nFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnRefresh;
+
+ if( ::get_flag( nFlags, EXC_WQSETT_SPECTABLES ) && (meMode == xlWQAllTables) )
+ meMode = xlWQSpecTables;
+}
+
+void XclImpWebQuery::ReadWqtables( XclImpStream& rStrm )
+{
+ if( meMode == xlWQSpecTables )
+ {
+ rStrm.Ignore( 4 );
+ String aTables( rStrm.ReadUniString() );
+
+ const sal_Unicode cSep = ';';
+ String aQuotedPairs( RTL_CONSTASCII_USTRINGPARAM( "\"\"" ) );
+ xub_StrLen nTokenCnt = aTables.GetQuotedTokenCount( aQuotedPairs, ',' );
+ maTables.Erase();
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aTables.GetQuotedToken( 0, aQuotedPairs, ',', nStringIx ) );
+ sal_Int32 nTabNum = CharClass::isAsciiNumeric( aToken ) ? aToken.ToInt32() : 0;
+ if( nTabNum > 0 )
+ ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLIndex( static_cast< sal_uInt32 >( nTabNum ) ), cSep );
+ else
+ {
+ ScGlobal::EraseQuotes( aToken, '"', false );
+ if( aToken.Len() )
+ ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLName( aToken ), cSep );
+ }
+ }
+ }
+}
+
+void XclImpWebQuery::Apply( ScDocument& rDoc, const String& rFilterName )
+{
+ if( maURL.Len() && (meMode != xlWQUnknown) && rDoc.GetDocumentShell() )
+ {
+ ScAreaLink* pLink = new ScAreaLink( rDoc.GetDocumentShell(),
+ maURL, rFilterName, EMPTY_STRING, maTables, maDestRange, mnRefresh * 60UL );
+ rDoc.GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE,
+ maURL, &rFilterName, &maTables );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpWebQueryBuffer::XclImpWebQueryBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpWebQueryBuffer::ReadQsi( XclImpStream& rStrm )
+{
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ rStrm.Ignore( 10 );
+ String aXclName( rStrm.ReadUniString() );
+
+ // #i64794# Excel replaces spaces with underscores
+ aXclName.SearchAndReplaceAll( ' ', '_' );
+
+ // find the defined name used in Calc
+ if( const XclImpName* pName = GetNameManager().FindName( aXclName, GetCurrScTab() ) )
+ {
+ if( const ScRangeData* pRangeData = pName->GetScRangeData() )
+ {
+ ScRange aRange;
+ if( pRangeData->IsReference( aRange ) )
+ maWQList.push_back( new XclImpWebQuery( aRange ) );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpWebQueryBuffer::ReadParamqry( XclImpStream& rStrm )
+{
+ if (!maWQList.empty())
+ maWQList.back().ReadParamqry( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqstring( XclImpStream& rStrm )
+{
+ if (!maWQList.empty())
+ maWQList.back().ReadWqstring( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqsettings( XclImpStream& rStrm )
+{
+ if (!maWQList.empty())
+ maWQList.back().ReadWqsettings( rStrm );
+}
+
+void XclImpWebQueryBuffer::ReadWqtables( XclImpStream& rStrm )
+{
+ if (!maWQList.empty())
+ maWQList.back().ReadWqtables( rStrm );
+}
+
+void XclImpWebQueryBuffer::Apply()
+{
+ ScDocument& rDoc = GetDoc();
+ String aFilterName( RTL_CONSTASCII_USTRINGPARAM( EXC_WEBQRY_FILTER ) );
+ for( XclImpWebQueryList::iterator itQuery = maWQList.begin(); itQuery != maWQList.end(); ++itQuery )
+ itQuery->Apply( rDoc, aFilterName );
+}
+
+// Decryption =================================================================
+
+namespace {
+
+XclImpDecrypterRef lclReadFilepass5( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ DBG_ASSERT( rStrm.GetRecLeft() == 4, "lclReadFilepass5 - wrong record size" );
+ if( rStrm.GetRecLeft() == 4 )
+ {
+ sal_uInt16 nKey, nHash;
+ rStrm >> nKey >> nHash;
+ xDecr.reset( new XclImpBiff5Decrypter( nKey, nHash ) );
+ }
+ return xDecr;
+}
+
+XclImpDecrypterRef lclReadFilepass8_Standard( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ DBG_ASSERT( rStrm.GetRecLeft() == 48, "lclReadFilepass8 - wrong record size" );
+ if( rStrm.GetRecLeft() == 48 )
+ {
+ sal_uInt8 pnSalt[ 16 ];
+ sal_uInt8 pnVerifier[ 16 ];
+ sal_uInt8 pnVerifierHash[ 16 ];
+ rStrm.Read( pnSalt, 16 );
+ rStrm.Read( pnVerifier, 16 );
+ rStrm.Read( pnVerifierHash, 16 );
+ xDecr.reset( new XclImpBiff8Decrypter( pnSalt, pnVerifier, pnVerifierHash ) );
+ }
+ return xDecr;
+}
+
+XclImpDecrypterRef lclReadFilepass8_Strong( XclImpStream& /*rStrm*/ )
+{
+ // not supported
+ return XclImpDecrypterRef();
+}
+
+XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+
+ sal_uInt16 nMode;
+ rStrm >> nMode;
+ switch( nMode )
+ {
+ case EXC_FILEPASS_BIFF5:
+ xDecr = lclReadFilepass5( rStrm );
+ break;
+
+ case EXC_FILEPASS_BIFF8:
+ {
+ rStrm.Ignore( 2 );
+ sal_uInt16 nSubMode;
+ rStrm >> nSubMode;
+ switch( nSubMode )
+ {
+ case EXC_FILEPASS_BIFF8_STD:
+ xDecr = lclReadFilepass8_Standard( rStrm );
+ break;
+ case EXC_FILEPASS_BIFF8_STRONG:
+ xDecr = lclReadFilepass8_Strong( rStrm );
+ break;
+ default:
+ DBG_ERRORFILE( "lclReadFilepass8 - unknown BIFF8 encryption sub mode" );
+ }
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "lclReadFilepass8 - unknown encryption mode" );
+ }
+
+ return xDecr;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xDecr;
+ rStrm.DisableDecryption();
+
+ // read the FILEPASS record and create a new decrypter object
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5: xDecr = lclReadFilepass5( rStrm ); break;
+ case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ };
+
+ // set decrypter at import stream
+ rStrm.SetDecrypter( xDecr );
+
+ // request and verify a password (decrypter implements IDocPasswordVerifier)
+ if( xDecr )
+ rStrm.GetRoot().RequestEncryptionData( *xDecr );
+
+ // return error code (success, wrong password, etc.)
+ return xDecr ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
+}
+
+// Document protection ========================================================
+
+XclImpDocProtectBuffer::XclImpDocProtectBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnPassHash(0x0000),
+ mbDocProtect(false),
+ mbWinProtect(false)
+{
+}
+
+void XclImpDocProtectBuffer::ReadDocProtect( XclImpStream& rStrm )
+{
+ mbDocProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadWinProtect( XclImpStream& rStrm )
+{
+ mbWinProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadPasswordHash( XclImpStream& rStrm )
+{
+ rStrm.EnableDecryption();
+ mnPassHash = rStrm.ReaduInt16();
+}
+
+void XclImpDocProtectBuffer::Apply() const
+{
+ if (!mbDocProtect && !mbWinProtect)
+ // Excel requires either the structure or windows protection is set.
+ // If neither is set then the document is not protected at all.
+ return;
+
+ auto_ptr<ScDocProtection> pProtect(new ScDocProtection);
+ pProtect->setProtected(true);
+
+ if (mnPassHash)
+ {
+ // 16-bit password pash.
+ Sequence<sal_Int8> aPass(2);
+ aPass[0] = (mnPassHash >> 8) & 0xFF;
+ aPass[1] = mnPassHash & 0xFF;
+ pProtect->setPasswordHash(aPass, PASSHASH_XL);
+ }
+
+ // document protection options
+ pProtect->setOption(ScDocProtection::STRUCTURE, mbDocProtect);
+ pProtect->setOption(ScDocProtection::WINDOWS, mbWinProtect);
+
+ GetDoc().SetDocProtection(pProtect.get());
+}
+
+// Sheet Protection ===========================================================
+
+XclImpSheetProtectBuffer::Sheet::Sheet() :
+ mbProtected(false),
+ mnPasswordHash(0x0000),
+ mnOptions(0x4400)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSheetProtectBuffer::Sheet::Sheet(const Sheet& r) :
+ mbProtected(r.mbProtected),
+ mnPasswordHash(r.mnPasswordHash),
+ mnOptions(r.mnOptions)
+{
+}
+
+XclImpSheetProtectBuffer::XclImpSheetProtectBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab )
+{
+ if ( rStrm.ReaduInt16() )
+ {
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mbProtected = true;
+ }
+}
+
+void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab )
+{
+ rStrm.Ignore(12);
+
+ // feature type can be either 2 or 4. If 2, this record stores flag for
+ // enhanced protection, whereas if 4 it stores flag for smart tag.
+ sal_uInt16 nFeatureType;
+ rStrm >> nFeatureType;
+ if (nFeatureType != 2)
+ // We currently only support import of enhanced protection data.
+ return;
+
+ rStrm.Ignore(1); // always 1
+
+ // The flag size specifies the size of bytes that follows that stores
+ // feature data. If -1 it depends on the feature type imported earlier.
+ // For enhanced protection data, the size is always 4. For the most xls
+ // documents out there this value is almost always -1.
+ sal_Int32 nFlagSize;
+ rStrm >> nFlagSize;
+ if (nFlagSize != -1)
+ return;
+
+ // There are actually 4 bytes to read, but the upper 2 bytes currently
+ // don't store any bits.
+ sal_uInt16 nOptions;
+ rStrm >> nOptions;
+
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnOptions = nOptions;
+}
+
+void XclImpSheetProtectBuffer::ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab )
+{
+ sal_uInt16 nHash;
+ rStrm >> nHash;
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnPasswordHash = nHash;
+}
+
+void XclImpSheetProtectBuffer::Apply() const
+{
+ for (ProtectedSheetMap::const_iterator itr = maProtectedSheets.begin(), itrEnd = maProtectedSheets.end();
+ itr != itrEnd; ++itr)
+ {
+ if (!itr->second.mbProtected)
+ // This sheet is (for whatever reason) not protected.
+ continue;
+
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(true);
+
+ // 16-bit hash password
+ const sal_uInt16 nHash = itr->second.mnPasswordHash;
+ if (nHash)
+ {
+ Sequence<sal_Int8> aPass(2);
+ aPass[0] = (nHash >> 8) & 0xFF;
+ aPass[1] = nHash & 0xFF;
+ pProtect->setPasswordHash(aPass, PASSHASH_XL);
+ }
+
+ // sheet protection options
+ const sal_uInt16 nOptions = itr->second.mnOptions;
+ pProtect->setOption( ScTableProtection::OBJECTS, (nOptions & 0x0001) );
+ pProtect->setOption( ScTableProtection::SCENARIOS, (nOptions & 0x0002) );
+ pProtect->setOption( ScTableProtection::FORMAT_CELLS, (nOptions & 0x0004) );
+ pProtect->setOption( ScTableProtection::FORMAT_COLUMNS, (nOptions & 0x0008) );
+ pProtect->setOption( ScTableProtection::FORMAT_ROWS, (nOptions & 0x0010) );
+ pProtect->setOption( ScTableProtection::INSERT_COLUMNS, (nOptions & 0x0020) );
+ pProtect->setOption( ScTableProtection::INSERT_ROWS, (nOptions & 0x0040) );
+ pProtect->setOption( ScTableProtection::INSERT_HYPERLINKS, (nOptions & 0x0080) );
+ pProtect->setOption( ScTableProtection::DELETE_COLUMNS, (nOptions & 0x0100) );
+ pProtect->setOption( ScTableProtection::DELETE_ROWS, (nOptions & 0x0200) );
+ pProtect->setOption( ScTableProtection::SELECT_LOCKED_CELLS, (nOptions & 0x0400) );
+ pProtect->setOption( ScTableProtection::SORT, (nOptions & 0x0800) );
+ pProtect->setOption( ScTableProtection::AUTOFILTER, (nOptions & 0x1000) );
+ pProtect->setOption( ScTableProtection::PIVOT_TABLES, (nOptions & 0x2000) );
+ pProtect->setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, (nOptions & 0x4000) );
+
+ // all done. now commit.
+ GetDoc().SetTabProtection(itr->first, pProtect.get());
+ }
+}
+
+XclImpSheetProtectBuffer::Sheet* XclImpSheetProtectBuffer::GetSheetItem( SCTAB nTab )
+{
+ ProtectedSheetMap::iterator itr = maProtectedSheets.find(nTab);
+ if (itr == maProtectedSheets.end())
+ {
+ // new sheet
+ if ( !maProtectedSheets.insert( ProtectedSheetMap::value_type(nTab, Sheet()) ).second )
+ return NULL;
+
+ itr = maProtectedSheets.find(nTab);
+ }
+
+ return &itr->second;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
new file mode 100644
index 000000000000..8d360b6f9259
--- /dev/null
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -0,0 +1,4206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xiescher.hxx"
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/awt/PushButtonType.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/awt/VisualEffect.hpp>
+#include <com/sun/star/style/HorizontalAlignment.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+
+#include <rtl/logfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <svtools/wmf.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/classids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include <svx/svdopath.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/svditer.hxx>
+#include <editeng/writingmodeitem.hxx>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/colritem.hxx>
+#include <svx/xflclit.hxx>
+#include <sal/macros.h>
+#include <editeng/adjitem.hxx>
+#include <svx/xlineit.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xbtmpit.hxx>
+
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "chartarr.hxx"
+#include "detfunc.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+
+#include "fprogressbar.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiformula.hxx"
+#include "xilink.hxx"
+#include "xistyle.hxx"
+#include "xipage.hxx"
+#include "xichart.hxx"
+#include "xicontent.hxx"
+#include "scextopt.hxx"
+
+#include "namebuff.hxx"
+#include <boost/shared_ptr.hpp>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::container::XIndexContainer;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::embed::XEmbeddedObject;
+using ::com::sun::star::embed::XEmbedPersist;
+using ::com::sun::star::drawing::XControlShape;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::form::XForm;
+using ::com::sun::star::form::XFormComponent;
+using ::com::sun::star::form::XFormsSupplier;
+using ::com::sun::star::form::binding::XBindableValue;
+using ::com::sun::star::form::binding::XValueBinding;
+using ::com::sun::star::form::binding::XListEntrySink;
+using ::com::sun::star::form::binding::XListEntrySource;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::script::XEventAttacherManager;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+
+// ============================================================================
+
+namespace {
+
+/** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls
+ SdrObject::Free instead of deleting the SdrObject directly. */
+template< typename SdrObjType >
+class TSdrObjectPtr
+{
+public:
+ inline explicit TSdrObjectPtr( SdrObjType* pObj = 0 ) : mpObj( pObj ) {}
+ inline ~TSdrObjectPtr() { free(); }
+
+ inline const SdrObjType* operator->() const { return mpObj; }
+ inline SdrObjType* operator->() { return mpObj; }
+
+ inline const SdrObjType* get() const { return mpObj; }
+ inline SdrObjType* get() { return mpObj; }
+
+ inline const SdrObjType& operator*() const { return *mpObj; }
+ inline SdrObjType& operator*() { return *mpObj; }
+
+ inline bool is() const { return mpObj != 0; }
+ inline bool operator!() const { return mpObj == 0; }
+
+ inline void reset( SdrObjType* pObj = 0 ) { free(); mpObj = pObj; }
+ inline SdrObjType* release() { SdrObjType* pObj = mpObj; mpObj = 0; return pObj; }
+
+private:
+ TSdrObjectPtr( const TSdrObjectPtr& ); // not implemented
+ TSdrObjectPtr& operator=( TSdrObjectPtr& rxObj ); // not implemented
+
+ inline void free() { SdrObject* pObj = mpObj; mpObj = 0; SdrObject::Free( pObj ); }
+
+private:
+ SdrObjType* mpObj;
+};
+
+typedef TSdrObjectPtr< SdrObject > SdrObjectPtr;
+
+} // namespace
+
+// Drawing objects ============================================================
+
+XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnObjId( EXC_OBJ_INVALID_ID ),
+ mnObjType( EXC_OBJTYPE_UNKNOWN ),
+ mnDffShapeId( 0 ),
+ mnDffFlags( 0 ),
+ mbHasAnchor( false ),
+ mbHidden( false ),
+ mbVisible( true ),
+ mbPrintable( true ),
+ mbAreaObj( false ),
+ mbAutoMargin( true ),
+ mbSimpleMacro( true ),
+ mbProcessSdr( true ),
+ mbInsertSdr( true ),
+ mbCustomDff( false )
+{
+}
+
+XclImpDrawObjBase::~XclImpDrawObjBase()
+{
+}
+
+XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 30 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ default:
+ OSL_TRACE( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->mnTab = rRoot.GetCurrScTab();
+ xDrawObj->ImplReadObj3( rStrm );
+ return xDrawObj;
+}
+
+XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 30 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
+ default:
+ OSL_TRACE( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->mnTab = rRoot.GetCurrScTab();
+ xDrawObj->ImplReadObj4( rStrm );
+ return xDrawObj;
+}
+
+XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 34 )
+ {
+ sal_uInt16 nObjType;
+ rStrm.Ignore( 4 );
+ rStrm >> nObjType;
+ switch( nObjType )
+ {
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
+ case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
+ case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
+ default:
+ OSL_TRACE( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+
+ xDrawObj->mnTab = rRoot.GetCurrScTab();
+ xDrawObj->ImplReadObj5( rStrm );
+ return xDrawObj;
+}
+
+XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ if( rStrm.GetRecLeft() >= 10 )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize, nObjType;
+ rStrm >> nSubRecId >> nSubRecSize >> nObjType;
+ DBG_ASSERT( nSubRecId == EXC_ID_OBJCMO, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
+ if( (nSubRecId == EXC_ID_OBJCMO) && (nSubRecSize >= 6) )
+ {
+ switch( nObjType )
+ {
+ // in BIFF8, all simple objects support text
+ case EXC_OBJTYPE_LINE:
+ case EXC_OBJTYPE_ARC:
+ xDrawObj.reset( new XclImpTextObj( rRoot ) );
+ // lines and arcs may be 2-dimensional
+ xDrawObj->SetAreaObj( false );
+ break;
+
+ // in BIFF8, all simple objects support text
+ case EXC_OBJTYPE_RECTANGLE:
+ case EXC_OBJTYPE_OVAL:
+ case EXC_OBJTYPE_POLYGON:
+ case EXC_OBJTYPE_DRAWING:
+ case EXC_OBJTYPE_TEXT:
+ xDrawObj.reset( new XclImpTextObj( rRoot ) );
+ break;
+
+ case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
+ case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
+ case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
+ case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
+ case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
+ case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
+ case EXC_OBJTYPE_NOTE: xDrawObj.reset( new XclImpNoteObj( rRoot ) ); break;
+
+ default:
+ OSL_TRACE( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType );
+ rRoot.GetTracer().TraceUnsupportedObjects();
+ xDrawObj.reset( new XclImpPhObj( rRoot ) );
+ }
+ }
+ }
+
+ xDrawObj->mnTab = rRoot.GetCurrScTab();
+ xDrawObj->ImplReadObj8( rStrm );
+ return xDrawObj;
+}
+
+void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor )
+{
+ maAnchor = rAnchor;
+ mbHasAnchor = true;
+}
+
+void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin )
+{
+ mnDffShapeId = rDffObjData.nShapeId;
+ mnDffFlags = rDffObjData.nSpFlags;
+ maObjName = rObjName;
+ maHyperlink = rHyperlink;
+ mbVisible = bVisible;
+ mbAutoMargin = bAutoMargin;
+}
+
+String XclImpDrawObjBase::GetObjName() const
+{
+ /* #i51348# Always return a non-empty name. Create English
+ default names depending on the object type. This is not implemented as
+ virtual functions in derived classes, as class type and object type may
+ not match. */
+ return (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this );
+}
+
+const XclObjAnchor* XclImpDrawObjBase::GetAnchor() const
+{
+ return mbHasAnchor ? &maAnchor : 0;
+}
+
+bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const
+{
+ // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
+ return mbAreaObj ?
+ ((rAnchorRect.GetWidth() > 3) && (rAnchorRect.GetHeight() > 1)) :
+ ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1));
+}
+
+ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const
+{
+ ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
+ // #i44077# object inserted -> update used area for OLE object import
+ if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) )
+ {
+ // reduce range, if object ends directly on borders between two columns or rows
+ if( (maAnchor.mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) )
+ aScUsedArea.aEnd.IncCol( -1 );
+ if( (maAnchor.mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) )
+ aScUsedArea.aEnd.IncRow( -1 );
+ }
+ return aScUsedArea;
+}
+
+sal_Size XclImpDrawObjBase::GetProgressSize() const
+{
+ return DoGetProgressSize();
+}
+
+SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const
+{
+ SdrObjectPtr xSdrObj;
+ if( bIsDff && !mbCustomDff )
+ {
+ rDffConv.Progress( GetProgressSize() );
+ }
+ else
+ {
+ xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) );
+ if( xSdrObj.is() )
+ xSdrObj->SetModel( rDffConv.GetModel() );
+ }
+ return xSdrObj.release();
+}
+
+void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj()
+ rSdrObj.NbcSetLayer( SC_LAYER_FRONT );
+
+ // set object name (GetObjName() will always return a non-empty name)
+ rSdrObj.SetName( GetObjName() );
+
+ // #i39167# full width for all objects regardless of horizontal alignment
+ rSdrObj.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
+
+ // automatic text margin
+ if( mbAutoMargin )
+ {
+ sal_Int32 nMargin = rDffConv.GetDefaultTextMargin();
+ rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) );
+ rSdrObj.SetMergedItem( SdrTextLowerDistItem( nMargin ) );
+ }
+
+ // macro and hyperlink
+ // removed oracle/sun check for mbSimpleMacro ( no idea what its for )
+ if( (maMacroName.Len() > 0 ) ||
+ (maHyperlink.Len() > 0) )
+ {
+ if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, sal_True ) )
+ {
+ pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) );
+ pInfo->SetHlink( maHyperlink );
+ }
+ }
+
+ // call virtual function for object type specific processing
+ DoPreProcessSdrObj( rDffConv, rSdrObj );
+}
+
+void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // call virtual function for object type specific processing
+ DoPostProcessSdrObj( rDffConv, rSdrObj );
+}
+
+// protected ------------------------------------------------------------------
+
+void XclImpDrawObjBase::ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen )
+{
+ maObjName.Erase();
+ if( nNameLen > 0 )
+ {
+ // name length field is repeated before the name
+ maObjName = rStrm.ReadByteString( false );
+ // skip padding byte for word boundaries
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+ }
+}
+
+void XclImpDrawObjBase::ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+ // skip padding byte for word boundaries, not contained in nMacroSize
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+}
+
+void XclImpDrawObjBase::ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+}
+
+void XclImpDrawObjBase::ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ maMacroName.Erase();
+ rStrm.Ignore( nMacroSize );
+}
+
+void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm )
+{
+ maMacroName.Erase();
+ if( rStrm.GetRecLeft() > 6 )
+ {
+ // macro is stored in a tNameXR token containing a link to a defined name
+ sal_uInt16 nFmlaSize;
+ rStrm >> nFmlaSize;
+ rStrm.Ignore( 4 );
+ DBG_ASSERT( nFmlaSize == 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
+ if( nFmlaSize == 7 )
+ {
+ sal_uInt8 nTokenId;
+ sal_uInt16 nExtSheet, nExtName;
+ rStrm >> nTokenId >> nExtSheet >> nExtName;
+ DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ),
+ "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
+ if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
+ maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName );
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const
+{
+ if( rLineData.IsAuto() )
+ {
+ XclObjLineData aAutoData;
+ aAutoData.mnAuto = 0;
+ ConvertLineStyle( rSdrObj, aAutoData );
+ }
+ else
+ {
+ long nLineWidth = 35 * ::std::min( rLineData.mnWidth, EXC_OBJ_LINE_THICK );
+ rSdrObj.SetMergedItem( XLineWidthItem( nLineWidth ) );
+ rSdrObj.SetMergedItem( XLineColorItem( EMPTY_STRING, GetPalette().GetColor( rLineData.mnColorIdx ) ) );
+ rSdrObj.SetMergedItem( XLineJointItem( XLINEJOINT_MITER ) );
+
+ sal_uLong nDotLen = ::std::max< sal_uLong >( 70 * rLineData.mnWidth, 35 );
+ sal_uLong nDashLen = 3 * nDotLen;
+ sal_uLong nDist = 2 * nDotLen;
+
+ switch( rLineData.mnStyle )
+ {
+ default:
+ case EXC_OBJ_LINE_SOLID:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ break;
+ case EXC_OBJ_LINE_DASH:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 0, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 0, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DASHDOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_DASHDOTDOT:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
+ rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 2, nDotLen, 1, nDashLen, nDist ) ) );
+ break;
+ case EXC_OBJ_LINE_MEDTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 50 ) );
+ break;
+ case EXC_OBJ_LINE_DARKTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 25 ) );
+ break;
+ case EXC_OBJ_LINE_LIGHTTRANS:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
+ rSdrObj.SetMergedItem( XLineTransparenceItem( 75 ) );
+ break;
+ case EXC_OBJ_LINE_NONE:
+ rSdrObj.SetMergedItem( XLineStyleItem( XLINE_NONE ) );
+ break;
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const
+{
+ if( rFillData.IsAuto() )
+ {
+ XclObjFillData aAutoData;
+ aAutoData.mnAuto = 0;
+ ConvertFillStyle( rSdrObj, aAutoData );
+ }
+ else if( rFillData.mnPattern == EXC_PATT_NONE )
+ {
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_NONE ) );
+ }
+ else
+ {
+ Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
+ Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
+ if( (rFillData.mnPattern == EXC_PATT_SOLID) || (aPattColor == aBackColor) )
+ {
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_SOLID ) );
+ rSdrObj.SetMergedItem( XFillColorItem( EMPTY_STRING, aPattColor ) );
+ }
+ else
+ {
+ static const sal_uInt8 sppnPatterns[][ 8 ] =
+ {
+ { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
+ { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
+ { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
+ { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
+ { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
+ { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
+ { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
+ { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
+ { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
+ { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
+ { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
+ { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
+ { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
+ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
+ };
+ const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, SAL_N_ELEMENTS( sppnPatterns ) ) ];
+ // create 2-colored 8x8 DIB
+ SvMemoryStream aMemStrm;
+ aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
+ aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
+ aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
+ for( size_t nIdx = 0; nIdx < 8; ++nIdx )
+ aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ Bitmap aBitmap;
+ aBitmap.Read( aMemStrm, false );
+ XOBitmap aXOBitmap( aBitmap );
+ aXOBitmap.Bitmap2Array();
+ aXOBitmap.SetBitmapType( XBITMAP_8X8 );
+ if( aXOBitmap.GetBackgroundColor().GetColor() == COL_BLACK )
+ ::std::swap( aPattColor, aBackColor );
+ aXOBitmap.SetPixelColor( aPattColor );
+ aXOBitmap.SetBackgroundColor( aBackColor );
+ rSdrObj.SetMergedItem( XFillStyleItem( XFILL_BITMAP ) );
+ rSdrObj.SetMergedItem( XFillBitmapItem( EMPTY_STRING, aXOBitmap ) );
+ }
+ }
+}
+
+void XclImpDrawObjBase::ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const
+{
+ if( ::get_flag( nFrameFlags, EXC_OBJ_FRAME_SHADOW ) )
+ {
+ rSdrObj.SetMergedItem( SdrShadowItem( sal_True ) );
+ rSdrObj.SetMergedItem( SdrShadowXDistItem( 35 ) );
+ rSdrObj.SetMergedItem( SdrShadowYDistItem( 35 ) );
+ rSdrObj.SetMergedItem( SdrShadowColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWTEXT ) ) );
+ }
+}
+
+Color XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData& rLineData ) const
+{
+ Color aColor( COL_TRANSPARENT );
+ if( rLineData.IsAuto() )
+ {
+ XclObjLineData aAutoData;
+ aAutoData.mnAuto = 0;
+ aColor = GetSolidLineColor( aAutoData );
+ }
+ else if( rLineData.mnStyle != EXC_OBJ_LINE_NONE )
+ {
+ aColor = GetPalette().GetColor( rLineData.mnColorIdx );
+ }
+ return aColor;
+}
+
+Color XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData& rFillData ) const
+{
+ Color aColor( COL_TRANSPARENT );
+ if( rFillData.IsAuto() )
+ {
+ XclObjFillData aAutoData;
+ aAutoData.mnAuto = 0;
+ aColor = GetSolidFillColor( aAutoData );
+ }
+ else if( rFillData.mnPattern != EXC_PATT_NONE )
+ {
+ Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
+ Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
+ aColor = XclTools::GetPatternColor( aPattColor, aBackColor, rFillData.mnPattern );
+ }
+ return aColor;
+}
+
+void XclImpDrawObjBase::DoReadObj3( XclImpStream&, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj4( XclImpStream&, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj5( XclImpStream&, sal_uInt16, sal_uInt16 )
+{
+}
+
+void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream&, sal_uInt16, sal_uInt16 )
+{
+}
+
+sal_Size XclImpDrawObjBase::DoGetProgressSize() const
+{
+ return 1;
+}
+
+SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const
+{
+ rDffConv.Progress( GetProgressSize() );
+ return 0;
+}
+
+void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
+{
+ // trace if object is not printable
+ if( !IsPrintable() )
+ GetTracer().TraceObjectNotPrintable();
+}
+
+void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
+{
+}
+
+void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ DoReadObj3( rStrm, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
+ DoReadObj4( rStrm, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm )
+{
+ // back to offset 4 (ignore object count field)
+ rStrm.Seek( 4 );
+
+ sal_uInt16 nObjFlags, nMacroSize, nNameLen;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
+ rStrm.Ignore( 2 );
+ rStrm >> nNameLen;
+ rStrm.Ignore( 2 );
+
+ mbHasAnchor = true;
+ mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
+ mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
+ DoReadObj5( rStrm, nNameLen, nMacroSize );
+}
+
+void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm )
+{
+ // back to beginning
+ rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
+
+ bool bLoop = true;
+ while( bLoop && (rStrm.GetRecLeft() >= 4) )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize;
+ rStrm >> nSubRecId >> nSubRecSize;
+ rStrm.PushPosition();
+ // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
+ nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nSubRecSize, rStrm.GetRecLeft() ) );
+
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJCMO:
+ DBG_ASSERT( rStrm.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
+ if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) )
+ {
+ sal_uInt16 nObjFlags;
+ rStrm >> mnObjType >> mnObjId >> nObjFlags;
+ mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE );
+ }
+ break;
+ case EXC_ID_OBJMACRO:
+ ReadMacro8( rStrm );
+ break;
+ case EXC_ID_OBJEND:
+ bLoop = false;
+ break;
+ default:
+ DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+
+ rStrm.PopPosition();
+ rStrm.Ignore( nSubRecSize );
+ }
+
+ /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
+ processing (e.g. charts), even if the OBJEND subrecord is missing. */
+ DoReadObj8SubRec( rStrm, EXC_ID_OBJEND, 0 );
+
+ /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
+ IMGDATA record following the OBJ record (but they use the image data
+ stored in DFF). The IMGDATA record may be continued by several CONTINUE
+ records. But the last CONTINUE record may be in fact an MSODRAWING
+ record that contains the DFF data of the next drawing object! So we
+ have to skip just enough CONTINUE records to look at the next
+ MSODRAWING/CONTINUE record. */
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ {
+ sal_uInt32 nDataSize;
+ rStrm.Ignore( 4 );
+ rStrm >> nDataSize;
+ nDataSize -= rStrm.GetRecLeft();
+ // skip following CONTINUE records until IMGDATA ends
+ while( (nDataSize > 0) && (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord() )
+ {
+ DBG_ASSERT( nDataSize >= rStrm.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
+ nDataSize -= ::std::min< sal_uInt32 >( rStrm.GetRecLeft(), nDataSize );
+ }
+ DBG_ASSERT( nDataSize == 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
+ // next record may be MSODRAWING or CONTINUE or anything else
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj )
+{
+ if( !empty() )
+ if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( back().get() ) )
+ if( pGroupObj->TryInsert( xDrawObj ) )
+ return;
+ push_back( xDrawObj );
+}
+
+sal_Size XclImpDrawObjVector::GetProgressSize() const
+{
+ sal_Size nProgressSize = 0;
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ nProgressSize += (*aIt)->GetProgressSize();
+ return nProgressSize;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPhObj::XclImpPhObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot )
+{
+ SetProcessSdrObj( false );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnFirstUngrouped( 0 )
+{
+}
+
+bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj )
+{
+ if( xDrawObj->GetObjId() == mnFirstUngrouped )
+ return false;
+ // insert into own list or into nested group
+ maChildren.InsertGrouped( xDrawObj );
+ return true;
+}
+
+void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnFirstUngrouped;
+ rStrm.Ignore( 16 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+sal_Size XclImpGroupObj::DoGetProgressSize() const
+{
+ return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize();
+}
+
+SdrObject* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& /*rAnchorRect*/ ) const
+{
+ TSdrObjectPtr< SdrObjGroup > xSdrObj( new SdrObjGroup );
+ // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
+ SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist
+ for( XclImpDrawObjVector::const_iterator aIt = maChildren.begin(), aEnd = maChildren.end(); aIt != aEnd; ++aIt )
+ rDffConv.ProcessObject( rObjList, **aIt );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpLineObj::XclImpLineObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnArrows( 0 ),
+ mnStartPoint( EXC_OBJ_LINE_TL )
+{
+ SetAreaObj( false );
+}
+
+void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm >> maLineData >> mnArrows >> mnStartPoint;
+ rStrm.Ignore( 1 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ ::basegfx::B2DPolygon aB2DPolygon;
+ switch( mnStartPoint )
+ {
+ default:
+ case EXC_OBJ_LINE_TL:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
+ break;
+ case EXC_OBJ_LINE_TR:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
+ break;
+ case EXC_OBJ_LINE_BR:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
+ break;
+ case EXC_OBJ_LINE_BL:
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
+ aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
+ break;
+ }
+ SdrObjectPtr xSdrObj( new SdrPathObj( OBJ_LINE, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
+ ConvertLineStyle( *xSdrObj, maLineData );
+
+ // line ends
+ sal_uInt8 nArrowType = ::extract_value< sal_uInt8 >( mnArrows, 0, 4 );
+ bool bLineStart = false;
+ bool bLineEnd = false;
+ bool bFilled = false;
+ switch( nArrowType )
+ {
+ case EXC_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break;
+ case EXC_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break;
+ case EXC_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break;
+ case EXC_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break;
+ }
+ if( bLineStart || bLineEnd )
+ {
+ sal_uInt8 nArrowWidth = ::extract_value< sal_uInt8 >( mnArrows, 4, 4 );
+ double fArrowWidth = 3.0;
+ switch( nArrowWidth )
+ {
+ case EXC_OBJ_ARROW_NARROW: fArrowWidth = 2.0; break;
+ case EXC_OBJ_ARROW_MEDIUM: fArrowWidth = 3.0; break;
+ case EXC_OBJ_ARROW_WIDE: fArrowWidth = 5.0; break;
+ }
+
+ sal_uInt8 nArrowLength = ::extract_value< sal_uInt8 >( mnArrows, 8, 4 );
+ double fArrowLength = 3.0;
+ switch( nArrowLength )
+ {
+ case EXC_OBJ_ARROW_NARROW: fArrowLength = 2.5; break;
+ case EXC_OBJ_ARROW_MEDIUM: fArrowLength = 3.5; break;
+ case EXC_OBJ_ARROW_WIDE: fArrowLength = 6.0; break;
+ }
+
+ ::basegfx::B2DPolygon aArrowPoly;
+#define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
+ if( bFilled )
+ {
+ aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) );
+ }
+ else
+ {
+ sal_uInt8 nLineWidth = ::limit_cast< sal_uInt8 >( maLineData.mnWidth, EXC_OBJ_LINE_THIN, EXC_OBJ_LINE_THICK );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 50, 12 * nLineWidth ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 5 * nLineWidth, 100 ) );
+ aArrowPoly.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth ) );
+ }
+#undef EXC_ARROW_POINT
+
+ ::basegfx::B2DPolyPolygon aArrowPolyPoly( aArrowPoly );
+ long nWidth = static_cast< long >( 125 * fArrowWidth );
+ if( bLineStart )
+ {
+ xSdrObj->SetMergedItem( XLineStartItem( EMPTY_STRING, aArrowPolyPoly ) );
+ xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) );
+ xSdrObj->SetMergedItem( XLineStartCenterItem( false ) );
+ }
+ if( bLineEnd )
+ {
+ xSdrObj->SetMergedItem( XLineEndItem( EMPTY_STRING, aArrowPolyPoly ) );
+ xSdrObj->SetMergedItem( XLineEndWidthItem( nWidth ) );
+ xSdrObj->SetMergedItem( XLineEndCenterItem( false ) );
+ }
+ }
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpRectObj::XclImpRectObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnFrameFlags( 0 )
+{
+ SetAreaObj( true );
+}
+
+void XclImpRectObj::ReadFrameData( XclImpStream& rStrm )
+{
+ rStrm >> maFillData >> maLineData >> mnFrameFlags;
+}
+
+void XclImpRectObj::ConvertRectStyle( SdrObject& rSdrObj ) const
+{
+ ConvertLineStyle( rSdrObj, maLineData );
+ ConvertFillStyle( rSdrObj, maFillData );
+ ConvertFrameStyle( rSdrObj, mnFrameFlags );
+}
+
+void XclImpRectObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpRectObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot )
+{
+}
+
+SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpArcObj::XclImpArcObj( const XclImpRoot& rRoot ) :
+ XclImpDrawObjBase( rRoot ),
+ mnQuadrant( EXC_OBJ_ARC_TR )
+{
+ SetAreaObj( false ); // arc may be 2-dimensional
+}
+
+void XclImpArcObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadMacro3( rStrm, nMacroSize );
+}
+
+void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadMacro4( rStrm, nMacroSize );
+}
+
+void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ rStrm >> maFillData >> maLineData >> mnQuadrant;
+ rStrm.Ignore( 1 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+}
+
+SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ Rectangle aNewRect = rAnchorRect;
+ long nStartAngle = 0;
+ long nEndAngle = 0;
+ switch( mnQuadrant )
+ {
+ default:
+ case EXC_OBJ_ARC_TR:
+ nStartAngle = 0;
+ nEndAngle = 9000;
+ aNewRect.Left() -= rAnchorRect.GetWidth();
+ aNewRect.Bottom() += rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_TL:
+ nStartAngle = 9000;
+ nEndAngle = 18000;
+ aNewRect.Right() += rAnchorRect.GetWidth();
+ aNewRect.Bottom() += rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_BL:
+ nStartAngle = 18000;
+ nEndAngle = 27000;
+ aNewRect.Right() += rAnchorRect.GetWidth();
+ aNewRect.Top() -= rAnchorRect.GetHeight();
+ break;
+ case EXC_OBJ_ARC_BR:
+ nStartAngle = 27000;
+ nEndAngle = 0;
+ aNewRect.Left() -= rAnchorRect.GetWidth();
+ aNewRect.Top() -= rAnchorRect.GetHeight();
+ break;
+ }
+ SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_SECT : OBJ_CARC;
+ SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) );
+ ConvertFillStyle( *xSdrObj, maFillData );
+ ConvertLineStyle( *xSdrObj, maLineData );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot ),
+ mnPolyFlags( 0 ),
+ mnPointCount( 0 )
+{
+ SetAreaObj( false ); // polygon may be 2-dimensional
+}
+
+void XclImpPolygonObj::ReadCoordList( XclImpStream& rStrm )
+{
+ if( (rStrm.GetNextRecId() == EXC_ID_COORDLIST) && rStrm.StartNextRecord() )
+ {
+ DBG_ASSERT( rStrm.GetRecLeft() / 4 == mnPointCount, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
+ while( rStrm.GetRecLeft() >= 4 )
+ {
+ sal_uInt16 nX, nY;
+ rStrm >> nX >> nY;
+ maCoords.push_back( Point( nX, nY ) );
+ }
+ }
+}
+
+void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnPointCount;
+ rStrm.Ignore( 8 );
+ ReadMacro4( rStrm, nMacroSize );
+ ReadCoordList( rStrm );
+}
+
+void XclImpPolygonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ rStrm >> mnPolyFlags;
+ rStrm.Ignore( 10 );
+ rStrm >> mnPointCount;
+ rStrm.Ignore( 8 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadCoordList( rStrm );
+}
+
+namespace {
+
+::basegfx::B2DPoint lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint )
+{
+ return ::basegfx::B2DPoint(
+ rAnchorRect.Left() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.X(), 16384.0 ) / 16384.0 * rAnchorRect.GetWidth() + 0.5 ),
+ rAnchorRect.Top() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.Y(), 16384.0 ) / 16384.0 * rAnchorRect.GetHeight() + 0.5 ) );
+}
+
+} // namespace
+
+SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj;
+ if( maCoords.size() >= 2 )
+ {
+ // create the polygon
+ ::basegfx::B2DPolygon aB2DPolygon;
+ for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt )
+ aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, *aIt ) );
+ // close polygon if specified
+ if( ::get_flag( mnPolyFlags, EXC_OBJ_POLY_CLOSED ) && (maCoords.front() != maCoords.back()) )
+ aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, maCoords.front() ) );
+ // create the SdrObject
+ SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_PATHPOLY : OBJ_PATHPLIN;
+ xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
+ ConvertRectStyle( *xSdrObj );
+ }
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpObjTextData::ReadByteString( XclImpStream& rStrm )
+{
+ mxString.reset();
+ if( maData.mnTextLen > 0 )
+ {
+ mxString.reset( new XclImpString( rStrm.ReadRawByteString( maData.mnTextLen ) ) );
+ // skip padding byte for word boundaries
+ if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
+ }
+}
+
+void XclImpObjTextData::ReadFormats( XclImpStream& rStrm )
+{
+ if( mxString )
+ mxString->ReadObjFormats( rStrm, maData.mnFormatSize );
+ else
+ rStrm.Ignore( maData.mnFormatSize );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTextObj::XclImpTextObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot )
+{
+}
+
+void XclImpTextObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj3( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ maTextData.ReadFormats( rStrm );
+}
+
+void XclImpTextObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj3( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ maTextData.ReadFormats( rStrm );
+}
+
+void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ ReadFrameData( rStrm );
+ maTextData.maData.ReadObj5( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ maTextData.ReadByteString( rStrm );
+ rStrm.Ignore( maTextData.maData.mnLinkSize ); // ignore text link formula
+ maTextData.ReadFormats( rStrm );
+}
+
+SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape );
+ xSdrObj->NbcSetSnapRect( rAnchorRect );
+ OUString aRectType = CREATE_OUSTRING( "rectangle" );
+ xSdrObj->MergeDefaultAttributes( &aRectType );
+ ConvertRectStyle( *xSdrObj );
+ sal_Bool bAutoSize = ::get_flag( maTextData.maData.mnFlags, EXC_OBJ_TEXT_AUTOSIZE );
+ xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) );
+ xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) );
+ xSdrObj->SetMergedItem( SdrTextWordWrapItem( sal_True ) );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // set text data
+ if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) )
+ {
+ if( maTextData.mxString )
+ {
+ if( maTextData.mxString->IsRich() )
+ {
+ // rich text
+ ::std::auto_ptr< EditTextObject > xEditObj(
+ XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData.mxString ) );
+ OutlinerParaObject* pOutlineObj = new OutlinerParaObject( *xEditObj );
+ pOutlineObj->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
+ // text object takes ownership of the outliner object
+ pTextObj->NbcSetOutlinerParaObject( pOutlineObj );
+ }
+ else
+ {
+ // plain text
+ pTextObj->NbcSetText( maTextData.mxString->GetText() );
+ }
+
+ /* #i96858# Do not apply any formatting if there is no text.
+ SdrObjCustomShape::SetVerticalWriting (initiated from
+ SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
+ ensures that we can erroneously write a ClientTextbox record
+ (with no content) while exporting to XLS, which can cause a
+ corrupted exported document. */
+
+ SvxAdjust eHorAlign = SVX_ADJUST_LEFT;
+ SdrTextVertAdjust eVerAlign = SDRTEXTVERTADJUST_TOP;
+
+ // orientation (this is only a fake, drawing does not support real text orientation)
+ namespace csst = ::com::sun::star::text;
+ csst::WritingMode eWriteMode = csst::WritingMode_LR_TB;
+ switch( maTextData.maData.mnOrient )
+ {
+ default:
+ case EXC_OBJ_ORIENT_NONE:
+ {
+ eWriteMode = csst::WritingMode_LR_TB;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_90CCW:
+ {
+ if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) )
+ {
+ double fAngle = 180.0;
+ com::sun::star::beans::PropertyValue aTextRotateAngle;
+ aTextRotateAngle.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ aTextRotateAngle.Value <<= fAngle;
+ SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+ aGeometryItem.SetPropertyValue( aTextRotateAngle );
+ pObjCustomShape->SetMergedItem( aGeometryItem );
+ }
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_STACKED: // PASSTHROUGH INTENDED
+ {
+ // sj: STACKED is not supported, maybe it can be optimized here a bit
+ }
+ case EXC_OBJ_ORIENT_90CW:
+ {
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
+ rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
+ rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) );
+ }
+ }
+ // base class processing
+ XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) :
+ XclImpRectObj( rRoot ),
+ mbOwnTab( bOwnTab )
+{
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm )
+{
+ if( mbOwnTab ? (rStrm.GetRecId() == EXC_ID5_BOF) : ((rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord()) )
+ {
+ sal_uInt16 nBofType;
+ rStrm.Seek( 2 );
+ rStrm >> nBofType;
+ DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
+
+ // read chart, even if BOF record contains wrong substream identifier
+ mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) );
+ mxChart->ReadChartSubStream( rStrm );
+ if( mbOwnTab )
+ FinalizeTabChart();
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
+ }
+}
+
+void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadMacro3( rStrm, nMacroSize );
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadMacro4( rStrm, nMacroSize );
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ // read OBJ record and the following chart substream
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 18 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadChartSubStream( rStrm );
+ // set frame format from OBJ record, it is used if chart itself is transparent
+ if( mxChart )
+ mxChart->UpdateObjFrame( maLineData, maFillData );
+}
+
+void XclImpChartObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 /*nSubRecSize*/ )
+{
+ // read the following chart substream
+ if( nSubRecId == EXC_ID_OBJEND )
+ {
+ // enable CONTINUE handling for the entire chart substream
+ rStrm.ResetRecord( true );
+ ReadChartSubStream( rStrm );
+ /* disable CONTINUE handling again to be able to read
+ following CONTINUE records as MSODRAWING records. */
+ rStrm.ResetRecord( false );
+ }
+}
+
+sal_Size XclImpChartObj::DoGetProgressSize() const
+{
+ return mxChart ? mxChart->GetProgressSize() : 1;
+}
+
+SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj;
+ SfxObjectShell* pDocShell = GetDocShell();
+ if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart && !mxChart->IsPivotChart() )
+ {
+ // create embedded chart object
+ OUString aEmbObjName;
+ Reference< XEmbeddedObject > xEmbObj = pDocShell->GetEmbeddedObjectContainer().
+ CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aEmbObjName );
+
+ /* Set the size to the embedded object, this prevents that font sizes
+ of text objects are changed in the chart when the object is
+ inserted into the draw page. */
+ sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj->getMapUnit( nAspect ) );
+ Size aSize( Window::LogicToLogic( rAnchorRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( aUnit ) ) );
+ ::com::sun::star::awt::Size aAwtSize( aSize.Width(), aSize.Height() );
+ xEmbObj->setVisualAreaSize( nAspect, aAwtSize );
+
+ // create the container OLE object
+ xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) );
+ }
+
+ return xSdrObj.release();
+}
+
+void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj );
+ if( mxChart && pSdrOleObj )
+ {
+ Reference< XEmbeddedObject > xEmbObj = pSdrOleObj->GetObjRef();
+ if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try
+ {
+ Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW );
+ Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW );
+ mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() );
+ xPersist->storeOwn();
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+void XclImpChartObj::FinalizeTabChart()
+{
+ /* #i44077# Calculate and store DFF anchor for sheet charts.
+ Needed to get used area if this chart is inserted as OLE object. */
+ DBG_ASSERT( mbOwnTab, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
+
+ // set uninitialized page to landscape
+ if( !GetPageSettings().GetPageData().mbValid )
+ GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT, false );
+
+ // calculate size of the chart object
+ const XclPageData& rPageData = GetPageSettings().GetPageData();
+ Size aPaperSize = rPageData.GetScPaperSize();
+
+ long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() );
+ long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() );
+
+ // subtract page margins, give some more extra space
+ nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000);
+ nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000);
+
+ // print column/row headers?
+ if( rPageData.mbPrintHeadings )
+ {
+ nWidth -= 2000;
+ nHeight -= 1000;
+ }
+
+ // create the object anchor
+ XclObjAnchor aAnchor;
+ aAnchor.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM );
+ SetAnchor( aAnchor );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpNoteObj::XclImpNoteObj( const XclImpRoot& rRoot ) :
+ XclImpTextObj( rRoot ),
+ maScPos( ScAddress::INITIALIZE_INVALID ),
+ mnNoteFlags( 0 )
+{
+ SetSimpleMacro( false );
+ // caption object will be created manually
+ SetInsertSdrObj( false );
+}
+
+void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags )
+{
+ maScPos = rScPos;
+ mnNoteFlags = nNoteFlags;
+}
+
+void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ // create formatted text
+ XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+ OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
+ if( maScPos.IsValid() && pOutlinerObj )
+ {
+ // create cell note with all data from drawing object
+ ScNoteUtil::CreateNoteFromObjectData(
+ GetDoc(), maScPos,
+ rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected
+ new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected
+ rSdrObj.GetLogicRect(),
+ ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ),
+ false );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) :
+ mrRoot( rRoot ),
+ meBindMode( eBindMode )
+{
+}
+
+XclImpControlHelper::~XclImpControlHelper()
+{
+}
+
+SdrObject* XclImpControlHelper::CreateSdrObjectFromShape(
+ const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const
+{
+ mxShape = rxShape;
+ SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) );
+ if( xSdrObj.is() )
+ {
+ xSdrObj->NbcSetSnapRect( rAnchorRect );
+ // #i30543# insert into control layer
+ xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
+ }
+ return xSdrObj.release();
+}
+
+void XclImpControlHelper::ApplySheetLinkProps() const
+{
+
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
+ if( !xCtrlModel.is() )
+ return;
+ ScfPropertySet aPropSet( xCtrlModel );
+
+ // sheet links
+ if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
+ {
+ Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
+ if( xFactory.is() )
+ {
+ // cell link
+ if( mxCellLink ) try
+ {
+ Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
+
+ // create argument sequence for createInstanceWithArguments()
+ CellAddress aApiAddress;
+ ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink );
+
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL );
+ aValue.Value <<= aApiAddress;
+
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the CellValueBinding instance and set at the control model
+ OUString aServiceName;
+ switch( meBindMode )
+ {
+ case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break;
+ case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break;
+ }
+ Reference< XValueBinding > xBinding(
+ xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
+ xBindable->setValueBinding( xBinding );
+ }
+ catch( const Exception& )
+ {
+ }
+
+ // source range
+ if( mxSrcRange ) try
+ {
+ Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
+
+ // create argument sequence for createInstanceWithArguments()
+ CellRangeAddress aApiRange;
+ ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange );
+
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE );
+ aValue.Value <<= aApiRange;
+
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the EntrySource instance and set at the control model
+ Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW );
+ xEntrySink->setListEntrySource( xEntrySource );
+ }
+ catch( const Exception& )
+ {
+ }
+ }
+ }
+}
+
+void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const
+{
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
+ if( !xCtrlModel.is() )
+ return;
+
+ ApplySheetLinkProps();
+
+ ScfPropertySet aPropSet( xCtrlModel );
+
+ // #i51348# set object name at control model
+ aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
+
+ // control visible and printable?
+ aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
+ aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
+
+
+ // virtual call for type specific processing
+ DoProcessControl( aPropSet );
+}
+
+void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
+{
+ ScRangeList aScRanges;
+ ReadRangeList( aScRanges, rStrm, bWithBoundSize );
+ // Use first cell of first range
+ if ( !aScRanges.empty() )
+ {
+ const ScRange* pScRange = aScRanges.front();
+ mxCellLink.reset( new ScAddress( pScRange->aStart ) );
+ }
+}
+
+void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize )
+{
+ ScRangeList aScRanges;
+ ReadRangeList( aScRanges, rStrm, bWithBoundSize );
+ // Use first range
+ if ( !aScRanges.empty() )
+ {
+ const ScRange* pScRange = aScRanges.front();
+ mxSrcRange.reset( new ScRange( *pScRange ) );
+ }
+}
+
+void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const
+{
+}
+
+void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm )
+{
+ XclTokenArray aXclTokArr;
+ aXclTokArr.ReadSize( rStrm );
+ rStrm.Ignore( 4 );
+ aXclTokArr.ReadArray( rStrm );
+ mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
+}
+
+void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
+{
+ if( bWithBoundSize )
+ {
+ sal_uInt16 nSize;
+ rStrm >> nSize;
+ if( nSize > 0 )
+ {
+ rStrm.PushPosition();
+ ReadRangeList( rScRanges, rStrm );
+ rStrm.PopPosition();
+ rStrm.Ignore( nSize );
+ }
+ }
+ else
+ {
+ ReadRangeList( rScRanges, rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) :
+ XclImpTextObj( rRoot ),
+ XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION )
+{
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+namespace {
+
+void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
+{
+ if( rDffPropSet.IsProperty( nPropId ) )
+ {
+ sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId );
+ if( (nColor & 0xFF000000) == 0x08000000 )
+ rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
+ }
+}
+
+} // namespace
+
+void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
+{
+ maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE;
+ lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
+ lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
+ ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false );
+
+ maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE;
+ lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
+ ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
+}
+
+bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
+{
+ return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
+}
+
+void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString )
+ {
+ const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
+ if( rFormatRuns.empty() )
+ GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
+ else
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
+ }
+}
+
+void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString )
+ {
+ String aLabel = maTextData.mxString->GetText();
+ if( maTextData.maData.mnShortcut > 0 )
+ {
+ xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
+ if( nPos != STRING_NOTFOUND )
+ aLabel.Insert( '~', nPos );
+ }
+ rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel );
+ }
+ ConvertFont( rPropSet );
+}
+
+SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const
+{
+ // do not call DoPreProcessSdrObj() from base class (to skip text processing)
+ ProcessControl( *this );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ /* Horizontal text alignment. For unknown reason, the property type is a
+ simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
+ sal_Int16 nHorAlign = 1;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
+ case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
+ case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
+ }
+ rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign );
+
+ // vertical text alignment
+ namespace csss = ::com::sun::star::style;
+ csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
+ case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
+ case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
+ }
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign );
+
+ // always wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
+
+ // default button
+ bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton );
+
+ // button type (flags cannot be combined in OOo)
+ namespace cssa = ::com::sun::star::awt;
+ cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
+ if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) )
+ eButtonType = cssa::PushButtonType_OK;
+ else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) )
+ eButtonType = cssa::PushButtonType_CANCEL;
+ else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) )
+ eButtonType = cssa::PushButtonType_HELP;
+ // property type is short, not enum
+ rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) );
+}
+
+OUString XclImpButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
+}
+
+XclTbxEventType XclImpButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
+ mnCheckBoxFlags( 0 )
+{
+}
+
+void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 20 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
+}
+
+void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJCBLS:
+ // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
+ rStrm >> mnState;
+ rStrm.Ignore( 4 );
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
+ break;
+ case EXC_ID_OBJCBLSFMLA:
+ ReadCellLinkFormula( rStrm, false );
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ // state
+ bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
+ sal_Int16 nApiState = 0;
+ switch( mnState )
+ {
+ case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
+ case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
+ case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
+ }
+ if( bSupportsTristate )
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 );
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState );
+
+ // box style
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
+ rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect );
+
+ // do not wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
+
+ // #i40279# always centered vertically
+ namespace csss = ::com::sun::star::style;
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE );
+
+ // background color
+ if( maFillData.IsFilled() )
+ {
+ sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() );
+ rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor );
+ }
+}
+
+OUString XclImpCheckBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
+}
+
+XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) :
+ XclImpCheckBoxObj( rRoot ),
+ mnNextInGroup( 0 ),
+ mnFirstInGroup( 1 )
+{
+}
+
+void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 32 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA;
+ rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup;
+}
+
+void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJRBODATA:
+ rStrm >> mnNextInGroup >> mnFirstInGroup;
+ break;
+ default:
+ XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ XclImpCheckBoxObj::DoProcessControl( rPropSet );
+ // TODO: grouping
+ XclImpOptionButtonObj* pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( mnNextInGroup ).get() );
+ if ( ( pTbxObj && pTbxObj->mnFirstInGroup ) )
+ {
+ // Group has terminated
+ // traverse each RadioButton in group and
+ // a) apply the groupname
+ // b) propagate the linked cell from the lead radiobutton
+ // c) apply the correct Ref value
+ XclImpOptionButtonObj* pLeader = pTbxObj;
+ ;
+ sal_Int32 nRefVal = 1;
+ OSL_TRACE( "0x%x start group ", pLeader->GetObjId()/*.mnObjId */);
+ do
+ {
+
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( pTbxObj->mxShape );
+ if ( xCtrlModel.is() )
+ {
+ ScfPropertySet aProps( xCtrlModel );
+ rtl::OUString sGroupName = rtl::OUString::valueOf( static_cast< sal_Int32 >( pLeader->GetDffShapeId() ) );
+
+ aProps.SetStringProperty( CREATE_OUSTRING( "GroupName" ), sGroupName );
+ aProps.SetStringProperty( CREATE_OUSTRING( "RefValue" ), rtl::OUString::valueOf( nRefVal++ ) );
+ if ( pLeader->HasCellLink() && !pTbxObj->HasCellLink() )
+ {
+ // propagate cell link info
+ pTbxObj->mxCellLink.reset( new ScAddress( *pLeader->mxCellLink.get() ) );
+ pTbxObj->ApplySheetLinkProps();
+ }
+ pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( pTbxObj->mnNextInGroup ).get() );
+ }
+ else
+ pTbxObj = NULL;
+ } while ( pTbxObj && !( pTbxObj->mnFirstInGroup == 1 ) );
+ }
+ else
+ {
+ // not the leader? try and find it
+ }
+}
+
+OUString XclImpOptionButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
+}
+
+XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_ACTION;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+
+ // text alignment (always top/left aligned)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
+ namespace csss = ::com::sun::star::style;
+ rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP );
+
+ // always wrap text automatically
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
+}
+
+OUString XclImpLabelObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
+}
+
+XclTbxEventType XclImpLabelObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnGroupBoxFlags( 0 )
+{
+}
+
+void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 26 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
+}
+
+void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJGBODATA:
+ rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+}
+
+OUString XclImpGroupBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
+}
+
+XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot )
+{
+}
+
+void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // label and text formatting
+ ConvertLabel( rPropSet );
+}
+
+OUString XclImpDialogObj::DoGetServiceName() const
+{
+ // dialog frame faked by a groupbox
+ return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
+}
+
+XclTbxEventType XclImpDialogObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_MOUSE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnContentType( EXC_OBJ_EDIT_TEXT ),
+ mnMultiLine( 0 ),
+ mnScrollBar( 0 ),
+ mnListBoxObjId( 0 )
+{
+}
+
+bool XclImpEditObj::IsNumeric() const
+{
+ return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE);
+}
+
+void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 10 );
+ rStrm >> maTextData.maData.mnFlags;
+ rStrm.Ignore( 14 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ rStrm >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
+}
+
+void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJEDODATA:
+ rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ if( maTextData.mxString )
+ {
+ OUString aText = maTextData.mxString->GetText();
+ if( IsNumeric() )
+ {
+ // TODO: OUString::toDouble() does not handle local decimal separator
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 );
+ }
+ else
+ {
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 );
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 );
+ }
+ }
+ ConvertFont( rPropSet );
+}
+
+OUString XclImpEditObj::DoGetServiceName() const
+{
+ return IsNumeric() ?
+ CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
+ CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
+}
+
+XclTbxEventType XclImpEditObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_TEXT;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) :
+ XclImpTbxObjBase( rRoot ),
+ mnValue( 0 ),
+ mnMin( 0 ),
+ mnMax( 100 ),
+ mnStep( 1 ),
+ mnPageStep( 10 ),
+ mnOrient( 0 ),
+ mnThumbWidth( 1 ),
+ mnScrollFlags( 0 )
+{
+}
+
+void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 4 );
+ rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags;
+}
+
+void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJSBS:
+ ReadSbs( rStrm );
+ break;
+ case EXC_ID_OBJSBSFMLA:
+ ReadCellLinkFormula( rStrm, false );
+ break;
+ default:
+ XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot )
+{
+}
+
+void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+}
+
+void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep );
+
+ // Excel spin buttons always vertical
+ rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL );
+}
+
+OUString XclImpSpinButtonObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
+}
+
+XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_VALUE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot )
+{
+}
+
+void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+}
+
+void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep );
+ rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep );
+ rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
+ rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient );
+}
+
+OUString XclImpScrollBarObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
+}
+
+XclTbxEventType XclImpScrollBarObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_VALUE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) :
+ XclImpTbxObjScrollableBase( rRoot ),
+ mnEntryCount( 0 ),
+ mnSelEntry( 0 ),
+ mnListFlags( 0 ),
+ mnEditObjId( 0 ),
+ mbHasDefFontIdx( false )
+{
+}
+
+void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm )
+{
+ ReadSourceRangeFormula( rStrm, true );
+ rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId;
+}
+
+void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const
+{
+ // border style
+ namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
+ sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
+ rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder );
+
+ // font formatting
+ if( mbHasDefFontIdx )
+ GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx );
+ else
+ GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjListBase( rRoot )
+{
+}
+
+void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft )
+{
+ sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft;
+ ReadLbsData( rStrm );
+ DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
+ "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
+ while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) )
+ maSelection.push_back( rStrm.ReaduInt8() );
+}
+
+void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ rStrm.Ignore( 18 );
+ rStrm >> maTextData.maData.mnDefFontIdx;
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
+ mbHasDefFontIdx = true;
+}
+
+void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJLBSDATA:
+ ReadFullLbsData( rStrm, nSubRecSize );
+ break;
+ default:
+ XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // listbox formatting
+ SetBoxFormatting( rPropSet );
+
+ // selection type
+ sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
+ bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel );
+
+ // selection (do not set, if listbox is linked to a cell)
+ if( !HasCellLink() )
+ {
+ ScfInt16Vec aSelVec;
+
+ // multi selection: API expects sequence of list entry indexes
+ if( bMultiSel )
+ for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt )
+ if( *aIt != 0 )
+ aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) );
+ // single selection: mnSelEntry is one-based, API expects zero-based
+ else if( mnSelEntry > 0 )
+ aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
+
+ if( !aSelVec.empty() )
+ {
+ Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) );
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
+ }
+ }
+}
+
+OUString XclImpListBoxObj::DoGetServiceName() const
+{
+ return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+}
+
+XclTbxEventType XclImpListBoxObj::DoGetEventType() const
+{
+ return EXC_TBX_EVENT_CHANGE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) :
+ XclImpTbxObjListBase( rRoot ),
+ mnLeft( 0 ),
+ mnTop( 0 ),
+ mnRight( 0 ),
+ mnBottom( 0 ),
+ mnDropDownFlags( 0 ),
+ mnLineCount( 0 ),
+ mnMinWidth( 0 )
+{
+}
+
+sal_uInt16 XclImpDropDownObj::GetDropDownType() const
+{
+ return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
+}
+
+void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm )
+{
+ ReadLbsData( rStrm );
+ rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen;
+ maTextData.ReadByteString( rStrm );
+ // dropdowns of auto-filters have 'simple' style, they don't have a text area
+ if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE )
+ SetProcessSdrObj( false );
+}
+
+void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
+{
+ ReadFrameData( rStrm );
+ ReadSbs( rStrm );
+ rStrm.Ignore( 18 );
+ rStrm >> maTextData.maData.mnDefFontIdx;
+ rStrm.Ignore( 14 );
+ rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom;
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
+ ReadCellLinkFormula( rStrm, true );
+ ReadFullLbsData( rStrm );
+ mbHasDefFontIdx = true;
+}
+
+void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJLBSDATA:
+ ReadFullLbsData( rStrm );
+ break;
+ default:
+ XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const
+{
+ // dropdown listbox formatting
+ SetBoxFormatting( rPropSet );
+ // enable dropdown button
+ rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
+ // dropdown line count
+ rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount );
+
+ if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX )
+ {
+ // text of editable combobox
+ if( maTextData.mxString )
+ rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() );
+ }
+ else
+ {
+ // selection (do not set, if dropdown is linked to a cell)
+ if( !HasCellLink() && (mnSelEntry > 0) )
+ {
+ Sequence< sal_Int16 > aSelSeq( 1 );
+ aSelSeq[ 0 ] = mnSelEntry - 1;
+ rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
+ }
+ }
+}
+
+OUString XclImpDropDownObj::DoGetServiceName() const
+{
+ return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ?
+ CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
+ CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+}
+
+XclTbxEventType XclImpDropDownObj::DoGetEventType() const
+{
+ return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) :
+ XclImpRectObj( rRoot ),
+ XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ),
+ mnStorageId( 0 ),
+ mnCtlsStrmPos( 0 ),
+ mnCtlsStrmSize( 0 ),
+ mbEmbedded( false ),
+ mbLinked( false ),
+ mbSymbol( false ),
+ mbControl( false ),
+ mbUseCtlsStrm( false )
+{
+ SetAreaObj( true );
+ SetSimpleMacro( false );
+ SetCustomDffObj( true );
+}
+
+String XclImpPictureObj::GetOleStorageName() const
+{
+ String aStrgName;
+ if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
+ {
+ aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED;
+ static const sal_Char spcHexChars[] = "0123456789ABCDEF";
+ for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
+ aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) );
+ }
+ return aStrgName;
+}
+
+void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ ReadMacro3( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+}
+
+void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ ReadMacro4( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+}
+
+void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
+{
+ sal_uInt16 nLinkSize;
+ ReadFrameData( rStrm );
+ rStrm.Ignore( 6 );
+ rStrm >> nLinkSize;
+ rStrm.Ignore( 2 );
+ ReadFlags3( rStrm );
+ rStrm.Ignore( 4 );
+ ReadName5( rStrm, nNameLen );
+ ReadMacro5( rStrm, nMacroSize );
+ ReadPictFmla( rStrm, nLinkSize );
+
+ if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
+ {
+ // page background is stored as hidden picture with name "__BkgndObj"
+ if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
+ GetPageSettings().ReadImgData( rStrm );
+ else
+ maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+ }
+}
+
+void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
+{
+ switch( nSubRecId )
+ {
+ case EXC_ID_OBJFLAGS:
+ ReadFlags8( rStrm );
+ break;
+ case EXC_ID_OBJPICTFMLA:
+ ReadPictFmla( rStrm, rStrm.ReaduInt16() );
+ break;
+ default:
+ XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
+ }
+}
+
+SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
+{
+ // try to create an OLE object or form control
+ SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
+
+ // no OLE - create a plain picture from IMGDATA record data
+ if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) )
+ {
+ xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) );
+ ConvertRectStyle( *xSdrObj );
+ }
+
+ rDffConv.Progress();
+ return xSdrObj.release();
+}
+
+String XclImpPictureObj::GetObjName() const
+{
+ if( IsOcxControl() )
+ {
+ String sName( GetObjectManager().GetOleNameOverride( GetTab(), GetObjId() ) );
+ if ( sName.Len() > 0 )
+ return sName;
+ }
+ return XclImpDrawObjBase::GetObjName();
+}
+
+void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
+{
+ if( IsOcxControl() )
+ {
+ // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
+ ProcessControl( *this );
+ }
+ else if( mbEmbedded || mbLinked )
+ {
+ // trace missing "printable" feature
+ XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+
+ SfxObjectShell* pDocShell = GetDocShell();
+ SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
+ if( pOleSdrObj && pDocShell )
+ {
+ comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer();
+ Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
+ OUString aOldName( pOleSdrObj->GetPersistName() );
+
+ /* The object persistence should be already in the storage, but
+ the object still might not be inserted into the container. */
+ if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
+ {
+ if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
+ // filter code is allowed to call the following method
+ rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
+ }
+ else
+ {
+ /* If the object is still not in container it must be inserted
+ there, the name must be generated in this case. */
+ OUString aNewName;
+ rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
+ if( aOldName != aNewName )
+ // SetPersistName, not SetName
+ pOleSdrObj->SetPersistName( aNewName );
+ }
+ }
+ }
+}
+
+void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
+}
+
+void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
+ mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL );
+ mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM );
+ DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
+ SetProcessSdrObj( mbControl || !mbUseCtlsStrm );
+}
+
+void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
+{
+ sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize;
+ if( nLinkSize >= 6 )
+ {
+ sal_uInt16 nFmlaSize;
+ rStrm >> nFmlaSize;
+ DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
+ // BIFF3/BIFF4 do not support storages, nothing to do here
+ if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
+ {
+ rStrm.Ignore( 4 );
+ sal_uInt8 nToken;
+ rStrm >> nToken;
+
+ // different processing for linked vs. embedded OLE objects
+ if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
+ {
+ mbLinked = true;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF5:
+ {
+ sal_Int16 nRefIdx;
+ sal_uInt16 nNameIdx;
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nNameIdx;
+ rStrm.Ignore( 12 );
+ const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
+ if( pExtName && pExtName->IsOLE() )
+ mnStorageId = pExtName->nStorageId;
+ }
+ break;
+ case EXC_BIFF8:
+ {
+ sal_uInt16 nXti, nExtName;
+ rStrm >> nXti >> nExtName;
+ const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
+ if( pExtName && (pExtName->GetType() == xlExtOLE) )
+ mnStorageId = pExtName->GetStorageId();
+ }
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ }
+ else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) )
+ {
+ mbEmbedded = true;
+ DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
+ rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
+ if( nFmlaSize & 1 )
+ rStrm.Ignore( 1 ); // padding byte
+
+ // a class name may follow inside the picture link
+ if( rStrm.GetRecPos() + 2 <= nLinkEnd )
+ {
+ sal_uInt16 nLen;
+ rStrm >> nLen;
+ if( nLen > 0 )
+ maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
+ }
+ }
+ // else: ignore other formulas, e.g. pictures linked to cell ranges
+ }
+ }
+
+ // seek behind picture link data
+ rStrm.Seek( nLinkEnd );
+
+ // read additional data for embedded OLE objects following the picture link
+ if( IsOcxControl() )
+ {
+ // #i26521# form controls to be ignored
+ if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) )
+ {
+ SetProcessSdrObj( false );
+ return;
+ }
+
+ if( rStrm.GetRecLeft() <= 8 ) return;
+
+ // position and size of control data in 'Ctls' stream
+ mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() );
+ mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() );
+
+ if( rStrm.GetRecLeft() <= 8 ) return;
+
+ // additional string (16-bit characters), e.g. for progress bar control
+ sal_uInt32 nAddStrSize;
+ rStrm >> nAddStrSize;
+ DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
+ if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
+ {
+ rStrm.Ignore( nAddStrSize );
+ // cell link and source range
+ ReadCellLinkFormula( rStrm, true );
+ ReadSourceRangeFormula( rStrm, true );
+ }
+ }
+ else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
+ {
+ rStrm >> mnStorageId;
+ }
+}
+
+// DFF stream conversion ======================================================
+
+void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags )
+{
+ if( nDffShapeId > 0 )
+ {
+ maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
+ maSdrObjMap[ &rSdrObj ] = nDffShapeId;
+ }
+}
+
+void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj )
+{
+ // remove info of passed object from the maps
+ XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
+ if( aIt != maSdrObjMap.end() )
+ {
+ maSdrInfoMap.erase( aIt->second );
+ maSdrObjMap.erase( aIt );
+ }
+
+ // remove info of all child objects of a group object
+ if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
+ {
+ if( SdrObjList* pSubList = pGroupObj->GetSubList() )
+ {
+ // iterate flat over the list because this function already works recursively
+ SdrObjListIter aObjIt( *pSubList, IM_FLAT );
+ for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
+ RemoveSdrObjectInfo( *pChildObj );
+ }
+ }
+}
+
+void XclImpSolverContainer::UpdateConnectorRules()
+{
+ for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
+ {
+ UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
+ UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
+ UpdateConnection( pRule->nShapeC, pRule->pCObj );
+ }
+}
+
+void XclImpSolverContainer::RemoveConnectorRules()
+{
+ // base class from SVX uses plain untyped tools/List
+ for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
+ delete pRule;
+ aCList.Clear();
+
+ maSdrInfoMap.clear();
+ maSdrObjMap.clear();
+}
+
+SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule()
+{
+ return static_cast< SvxMSDffConnectorRule* >( aCList.First() );
+}
+
+SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule()
+{
+ return static_cast< SvxMSDffConnectorRule* >( aCList.Next() );
+}
+
+void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags )
+{
+ XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
+ if( aIt != maSdrInfoMap.end() )
+ {
+ rpSdrObj = aIt->second.mpSdrObj;
+ if( pnDffFlags )
+ *pnDffFlags = aIt->second.mnDffFlags;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
+ SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ),
+ XclImpRoot( rRoot )
+{
+ SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL );
+}
+
+XclImpSimpleDffConverter::~XclImpSimpleDffConverter()
+{
+}
+
+bool XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex, Color& rColor ) const
+{
+ ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) );
+
+ if( nColor == COL_AUTO )
+ return 0;
+
+ rColor.SetColor( nColor );
+ return 1;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConvData::XclImpDffConvData(
+ XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) :
+ mrDrawing( rDrawing ),
+ mrSdrModel( rSdrModel ),
+ mrSdrPage( rSdrPage ),
+ mnLastCtrlIndex( -1 ),
+ mbHasCtrlForm( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
+ XclImpSimpleDffConverter( rRoot, rDffStrm ),
+ SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ),
+ maStdFormName( CREATE_OUSTRING( "Standard" ) ),
+ mnOleImpFlags( 0 )
+{
+ if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
+ {
+ if( pFilterOpt->IsMathType2Math() )
+ mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH;
+ if( pFilterOpt->IsWinWord2Writer() )
+ mnOleImpFlags |= OLE_WINWORD_2_STARWRITER;
+ if( pFilterOpt->IsPowerPoint2Impress() )
+ mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS;
+ }
+
+ // try to open the 'Ctls' storage stream containing OCX control properties
+ mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
+
+ // default text margin (convert EMU to drawing layer units)
+ mnDefTextMargin = EXC_OBJ_TEXT_MARGIN;
+ ScaleEmu( mnDefTextMargin );
+}
+
+XclImpDffConverter::~XclImpDffConverter()
+{
+}
+
+String XclImpObjectManager::GetOleNameOverride( SCTAB nTab, sal_uInt16 nObjId )
+{
+ rtl::OUString sOleName;
+ String sCodeName = GetExtDocOptions().GetCodeName( nTab );
+
+ if ( mxOleCtrlNameOverride->hasByName( sCodeName ) )
+ {
+ Reference< XIndexContainer > xIdToOleName;
+ mxOleCtrlNameOverride->getByName( sCodeName ) >>= xIdToOleName;
+ xIdToOleName->getByIndex( nObjId ) >>= sOleName;
+ }
+ OSL_TRACE("XclImpObjectManager::GetOleNameOverride tab %d, ( module %s ) object id ( %d ) is %s", nTab,
+ rtl::OUStringToOString( sCodeName, RTL_TEXTENCODING_UTF8 ).getStr(), nObjId,
+ rtl::OUStringToOString( sOleName, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ return sOleName;
+}
+
+void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize )
+{
+ mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) );
+ mxProgress->AddSegment( nProgressSize );
+ mxProgress->Activate();
+}
+
+void XclImpDffConverter::Progress( sal_Size nDelta )
+{
+ DBG_ASSERT( mxProgress, "XclImpDffConverter::Progress - invalid call, no progress bar" );
+ mxProgress->Progress( nDelta );
+}
+
+void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage )
+{
+ XclImpDffConvDataRef xConvData( new XclImpDffConvData( rDrawing, rSdrModel, rSdrPage ) );
+ maDataStack.push_back( xConvData );
+ SetModel( &xConvData->mrSdrModel, 1440 );
+}
+
+void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj )
+{
+ if( rDrawObj.IsProcessSdrObj() )
+ {
+ if( const XclObjAnchor* pAnchor = rDrawObj.GetAnchor() )
+ {
+ Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false );
+ if( rDrawObj.IsValidSize( aAnchorRect ) )
+ {
+ // CreateSdrObject() recursively creates embedded child objects
+ SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) );
+ if( xSdrObj.is() )
+ rDrawObj.PreProcessSdrObject( *this, *xSdrObj );
+ // call InsertSdrObject() also, if SdrObject is missing
+ InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() );
+ }
+ }
+ }
+}
+
+void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs )
+{
+ SdrPage& rSdrPage = GetConvData().mrSdrPage;
+ for( XclImpDrawObjVector::const_iterator aIt = rDrawObjs.begin(), aEnd = rDrawObjs.end(); aIt != aEnd; ++aIt )
+ ProcessObject( rSdrPage, **aIt );
+}
+
+void XclImpDffConverter::ProcessDrawing( SvStream& rDffStrm )
+{
+ rDffStrm.Seek( STREAM_SEEK_TO_END );
+ if( rDffStrm.Tell() > 0 )
+ {
+ rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ DBG_ASSERT( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" );
+ if( aHeader.nRecType == DFF_msofbtDgContainer )
+ ProcessDgContainer( rDffStrm, aHeader );
+ }
+}
+
+void XclImpDffConverter::FinalizeDrawing()
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
+ maDataStack.pop_back();
+ // restore previous model at core DFF converter
+ if( !maDataStack.empty() )
+ SetModel( &maDataStack.back()->mrSdrModel, 1440 );
+}
+
+SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect )
+{
+ SdrObjectPtr xSdrObj;
+
+ OUString aServiceName = rTbxObj.GetServiceName();
+ if( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try
+ {
+ // create the form control from scratch
+ Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
+ // set controls form, needed in virtual function InsertControl()
+ InitControlForm();
+ // try to insert the control into the form
+ ::com::sun::star::awt::Size aDummySize;
+ Reference< XShape > xShape;
+ XclImpDffConvData& rConvData = GetConvData();
+ if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, sal_True ) )
+ {
+ xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
+ // try to attach a macro to the control
+ ScriptEventDescriptor aDescriptor;
+ if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
+ {
+ Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW );
+ xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ return xSdrObj.release();
+}
+
+SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect )
+{
+ SdrObjectPtr xSdrObj;
+
+ if( SupportsOleObjects() )
+ {
+ if( rPicObj.IsOcxControl() )
+ {
+ if( mxCtlsStrm.Is() ) try
+ {
+ /* set controls form, needed in virtual function InsertControl()
+ called from ReadOCXExcelKludgeStream() */
+ InitControlForm();
+ // seek to stream position of the extra data for this control
+ mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() );
+ // read from mxCtlsStrm into xShape, insert the control model into the form
+ Reference< XShape > xShape;
+ if( GetConvData().mxCtrlForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, sal_True ) )
+ xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ else
+ {
+ SfxObjectShell* pDocShell = GetDocShell();
+ SotStorageRef xSrcStrg = GetRootStorage();
+ String aStrgName = rPicObj.GetOleStorageName();
+ if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) )
+ {
+ // first try to resolve graphic from DFF storage
+ Graphic aGraphic;
+ Rectangle aVisArea;
+ if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) )
+ {
+ // if not found, use graphic from object (imported from IMGDATA record)
+ aGraphic = rPicObj.GetGraphic();
+ aVisArea = rPicObj.GetVisArea();
+ }
+ if( aGraphic.GetType() != GRAPHIC_NONE )
+ {
+ ErrCode nError = ERRCODE_NONE;
+ namespace cssea = ::com::sun::star::embed::Aspects;
+ sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
+ xSdrObj.reset( CreateSdrOLEFromStorage(
+ aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic,
+ rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) );
+ }
+ }
+ }
+ }
+
+ return xSdrObj.release();
+}
+
+bool XclImpDffConverter::SupportsOleObjects() const
+{
+ return GetConvData().mrDrawing.SupportsOleObjects();
+}
+
+// virtual functions ----------------------------------------------------------
+
+void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm,
+ DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData )
+{
+ // find the OBJ record data related to the processed shape
+ XclImpDffConvData& rConvData = GetConvData();
+ if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() )
+ {
+ DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
+ XclObjAnchor aAnchor;
+ rHeader.SeekToContent( rDffStrm );
+ rDffStrm.SeekRel( 2 ); // flags
+ rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
+ pDrawObj->SetAnchor( aAnchor );
+ rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true );
+ rObjData.bChildAnchor = sal_True;
+ }
+}
+
+SdrObject* XclImpDffConverter::ProcessObj( SvStream& rDffStrm, DffObjData& rDffObjData,
+ void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
+{
+ XclImpDffConvData& rConvData = GetConvData();
+
+ /* pOldSdrObj passes a generated SdrObject. This function owns this object
+ and can modify it. The function has either to return it back to caller
+ or to delete it by itself. */
+ SdrObjectPtr xSdrObj( pOldSdrObj );
+
+ // find the OBJ record data related to the processed shape
+ XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd );
+ const Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
+
+ // Do not process the global page group shape (flag SP_FPATRIARCH)
+ bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH );
+ if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
+ return 0; // simply return, xSdrObj will be destroyed
+
+ /* Pass pointer to top-level object back to caller. If the processed
+ object is embedded in a group, the pointer is already set to the
+ top-level parent object. */
+ XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData );
+ bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj;
+ if( ppTopLevelObj && bIsTopLevel )
+ *ppTopLevelObj = xDrawObj.get();
+
+ // connectors don't have to be area objects
+ if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
+ xDrawObj->SetAreaObj( false );
+
+ /* Check for valid size for all objects. Needed to ignore lots of invisible
+ phantom objects from deleted rows or columns (for performance reasons).
+ #i30816# Include objects embedded in groups.
+ #i58780# Ignore group shapes, size is not initialized. */
+ bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
+ if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
+ return 0; // simply return, xSdrObj will be destroyed
+
+ // set shape information from DFF stream
+ String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
+ String aHyperlink = ReadHlinkProperty( rDffStrm );
+ bool bVisible = !GetPropertyBool( DFF_Prop_fHidden );
+ bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
+ xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
+
+ /* Connect textbox data (string, alignment, text orientation) to object.
+ don't ask for a text-ID, DFF export doesn't set one. */
+ if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
+ if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) )
+ pTextObj->SetTextData( *pTextData );
+
+ // copy line and fill formatting of TBX form controls from DFF properties
+ if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
+ pTbxObj->SetDffProperties( *this );
+
+ // try to create a custom SdrObject that overwrites the passed object
+ SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) );
+ if( xNewSdrObj.is() )
+ xSdrObj.reset( xNewSdrObj.release() );
+
+ // process the SdrObject
+ if( xSdrObj.is() )
+ {
+ // filled without color -> set system window color
+ if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) )
+ xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
+
+ // additional processing on the SdrObject
+ xDrawObj->PreProcessSdrObject( *this, *xSdrObj );
+
+ /* If the SdrObject will not be inserted into the draw page, delete it
+ here. Happens e.g. for notes: The PreProcessSdrObject() call above
+ has inserted the note into the document, and the SdrObject is not
+ needed anymore. */
+ if( !xDrawObj->IsInsertSdrObj() )
+ xSdrObj.reset();
+ }
+
+ if( xSdrObj.is() )
+ {
+ /* Store the relation between shape ID and SdrObject for connectors.
+ Must be done here (and not in InsertSdrObject() function),
+ otherwise all SdrObjects embedded in groups would be lost. */
+ rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
+
+ /* If the drawing object is embedded in a group object, call
+ PostProcessSdrObject() here. For top-level objects this will be
+ done automatically in InsertSdrObject() but grouped shapes are
+ inserted into their groups somewhere in the SvxMSDffManager base
+ class without chance of notification. Unfortunately, now this is
+ called before the object is really inserted into its group object,
+ but that should not have any effect for grouped objects. */
+ if( !bIsTopLevel )
+ xDrawObj->PostProcessSdrObject( *this, *xSdrObj );
+ }
+
+ return xSdrObj.release();
+}
+
+sal_uLong XclImpDffConverter::Calc_nBLIPPos( sal_uLong /*nOrgVal*/, sal_uLong nStreamPos ) const
+{
+ return nStreamPos + 4;
+}
+
+sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp,
+ const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
+ sal_Bool /*bFloatingCtrl*/ )
+{
+ if( GetDocShell() ) try
+ {
+ XclImpDffConvData& rConvData = GetConvData();
+ Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW );
+ Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
+
+ // create the control shape
+ Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW );
+ Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
+
+ // insert the new control into the form
+ sal_Int32 nNewIndex = xFormIC->getCount();
+ xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
+ // on success: store new index of the control for later use (macro events)
+ rConvData.mnLastCtrlIndex = nNewIndex;
+
+ // set control model at control shape and pass back shape to caller
+ xCtrlShape->setControl( xCtrlModel );
+ if( pxShape ) *pxShape = xShape;
+ return sal_True;
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" );
+ }
+
+ return false;
+}
+
+// private --------------------------------------------------------------------
+
+XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData()
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
+ return *maDataStack.back();
+}
+
+const XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() const
+{
+ DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
+ return *maDataStack.back();
+}
+
+String XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const
+{
+ /* Reads hyperlink data from a complex DFF property. Contents of this
+ property are equal to the HLINK record, import of this record is
+ implemented in class XclImpHyperlink. This function has to create an
+ instance of the XclImpStream class to be able to reuse the
+ functionality of XclImpHyperlink. */
+ String aString;
+ sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
+ if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
+ {
+ // create a faked BIFF record that can be read by XclImpStream class
+ SvMemoryStream aMemStream;
+ aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
+
+ // copy from DFF stream to memory stream
+ ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
+ sal_uInt8* pnData = &aBuffer.front();
+ if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize )
+ {
+ aMemStream.Write( pnData, nBufferSize );
+
+ // create BIFF import stream to be able to use XclImpHyperlink class
+ XclImpStream aXclStrm( aMemStream, GetRoot() );
+ if( aXclStrm.StartNextRecord() )
+ aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
+ }
+ }
+ return aString;
+}
+
+void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
+{
+ sal_Size nEndPos = rDgHeader.GetRecEndFilePos();
+ while( rDffStrm.Tell() < nEndPos )
+ {
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ switch( aHeader.nRecType )
+ {
+ case DFF_msofbtSolverContainer:
+ ProcessSolverContainer( rDffStrm, aHeader );
+ break;
+ case DFF_msofbtSpgrContainer:
+ ProcessShGrContainer( rDffStrm, aHeader );
+ break;
+ default:
+ aHeader.SeekToEndOfRecord( rDffStrm );
+ }
+ }
+ // seek to end of drawing page container
+ rDgHeader.SeekToEndOfRecord( rDffStrm );
+
+ // #i12638# #i37900# connector rules
+ XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont;
+ rSolverCont.UpdateConnectorRules();
+ SolveSolver( rSolverCont );
+ rSolverCont.RemoveConnectorRules();
+}
+
+void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
+{
+ sal_Size nEndPos = rShGrHeader.GetRecEndFilePos();
+ while( rDffStrm.Tell() < nEndPos )
+ {
+ DffRecordHeader aHeader;
+ rDffStrm >> aHeader;
+ switch( aHeader.nRecType )
+ {
+ case DFF_msofbtSpgrContainer:
+ case DFF_msofbtSpContainer:
+ ProcessShContainer( rDffStrm, aHeader );
+ break;
+ default:
+ aHeader.SeekToEndOfRecord( rDffStrm );
+ }
+ }
+ // seek to end of shape group container
+ rShGrHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
+{
+ // solver container wants to read the solver container header again
+ rSolverHeader.SeekToBegOfRecord( rDffStrm );
+ // read the entire solver container
+ rDffStrm >> GetConvData().maSolverCont;
+ // seek to end of solver container
+ rSolverHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
+{
+ rShHeader.SeekToBegOfRecord( rDffStrm );
+ Rectangle aDummy;
+ const XclImpDrawObjBase* pDrawObj = 0;
+ /* The call to ImportObj() creates and returns a new SdrObject for the
+ processed shape. We take ownership of the returned object here. If the
+ shape is a group object, all embedded objects are created recursively,
+ and the returned group object contains them all. ImportObj() calls the
+ virtual functions ProcessClientAnchor2() and ProcessObj() and writes
+ the pointer to the related draw object data (OBJ record) into pDrawObj. */
+ SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) );
+ if( pDrawObj && xSdrObj.is() )
+ InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() );
+ rShHeader.SeekToEndOfRecord( rDffStrm );
+}
+
+void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )
+{
+ XclImpDffConvData& rConvData = GetConvData();
+ /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
+ states to skip insertion), the object is automatically deleted. */
+ SdrObjectPtr xSdrObj( pSdrObj );
+ if( xSdrObj.is() && rDrawObj.IsInsertSdrObj() )
+ {
+ rObjList.NbcInsertObject( xSdrObj.release() );
+ // callback to drawing manager for e.g. tracking of used sheet area
+ rConvData.mrDrawing.OnObjectInserted( rDrawObj );
+ // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
+ rDrawObj.PostProcessSdrObject( *this, *pSdrObj );
+ }
+ /* SdrObject still here? Insertion failed, remove data from shape ID map.
+ The SdrObject will be destructed then. */
+ if( xSdrObj.is() )
+ rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
+}
+
+void XclImpDffConverter::InitControlForm()
+{
+ XclImpDffConvData& rConvData = GetConvData();
+ if( rConvData.mbHasCtrlForm )
+ return;
+
+ rConvData.mbHasCtrlForm = true;
+ if( SupportsOleObjects() ) try
+ {
+ Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW );
+ Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW );
+ // find or create the Standard form used to insert the imported controls
+ if( xFormsNC->hasByName( maStdFormName ) )
+ {
+ xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm;
+ }
+ else if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
+ xFormsNC->insertByName( maStdFormName, Any( rConvData.mxCtrlForm ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// Drawing manager ============================================================
+
+XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) :
+ XclImpRoot( rRoot ),
+ mbOleObjs( bOleObjects )
+{
+}
+
+XclImpDrawing::~XclImpDrawing()
+{
+}
+
+Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm )
+{
+ Graphic aGraphic;
+ sal_uInt16 nFormat, nEnv;
+ sal_uInt32 nDataSize;
+ rStrm >> nFormat >> nEnv >> nDataSize;
+ if( nDataSize <= rStrm.GetRecLeft() )
+ {
+ switch( nFormat )
+ {
+ case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rRoot, rStrm ); break;
+ case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break;
+ default: DBG_ERRORFILE( "XclImpDrawing::ReadImgData - unknown image format" );
+ }
+ }
+ return aGraphic;
+}
+
+void XclImpDrawing::ReadObj( XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj;
+
+ /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
+ records. In this case, the OBJ records are in BIFF5 format. Do a sanity
+ check here that there is no DFF data loaded before. */
+ DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
+ if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
+ {
+ case EXC_BIFF3:
+ xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm );
+ break;
+ case EXC_BIFF4:
+ xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm );
+ break;
+ case EXC_BIFF5:
+ case EXC_BIFF8:
+ xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+
+ if( xDrawObj )
+ {
+ // insert into maRawObjs or into the last open group object
+ maRawObjs.InsertGrouped( xDrawObj );
+ // to be able to find objects by ID
+ maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
+ }
+}
+
+void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ // disable internal CONTINUE handling
+ rStrm.ResetRecord( false );
+ // read leading MSODRAWING record
+ ReadDffRecord( rStrm );
+
+ // read following drawing records, but do not start following unrelated record
+ bool bLoop = true;
+ while( bLoop ) switch( rStrm.GetNextRecId() )
+ {
+ case EXC_ID_MSODRAWING:
+ case EXC_ID_MSODRAWINGSEL:
+ case EXC_ID_CONT:
+ rStrm.StartNextRecord();
+ ReadDffRecord( rStrm );
+ break;
+ case EXC_ID_OBJ:
+ rStrm.StartNextRecord();
+ ReadObj8( rStrm );
+ break;
+ case EXC_ID_TXO:
+ rStrm.StartNextRecord();
+ ReadTxo( rStrm );
+ break;
+ default:
+ bLoop = false;
+ }
+
+ // re-enable internal CONTINUE handling
+ rStrm.ResetRecord( true );
+}
+
+XclImpDrawObjRef XclImpDrawing::FindDrawObj( const DffRecordHeader& rHeader ) const
+{
+ /* maObjMap stores objects by position of the client data (OBJ record) in
+ the DFF stream, which is always behind shape start position of the
+ passed header. The function upper_bound() finds the first element in
+ the map whose key is greater than the start position of the header. Its
+ end position is used to test whether the found object is really related
+ to the shape. */
+ XclImpDrawObjRef xDrawObj;
+ XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
+ if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
+ xDrawObj = aIt->second;
+ return xDrawObj;
+}
+
+XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const
+{
+ XclImpDrawObjRef xDrawObj;
+ XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId );
+ if( aIt != maObjMapId.end() )
+ xDrawObj = aIt->second;
+ return xDrawObj;
+}
+
+const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHeader ) const
+{
+ /* maTextMap stores textbox data by position of the client data (TXO
+ record) in the DFF stream, which is always behind shape start position
+ of the passed header. The function upper_bound() finds the first
+ element in the map whose key is greater than the start position of the
+ header. Its end position is used to test whether the found object is
+ really related to the shape. */
+ XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
+ if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
+ return aIt->second.get();
+ return 0;
+}
+
+void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId )
+{
+ maSkipObjs.push_back( nObjId );
+}
+
+sal_Size XclImpDrawing::GetProgressSize() const
+{
+ sal_Size nProgressSize = maRawObjs.GetProgressSize();
+ for( XclImpObjMap::const_iterator aIt = maObjMap.begin(), aEnd = maObjMap.end(); aIt != aEnd; ++aIt )
+ nProgressSize += aIt->second->GetProgressSize();
+ return nProgressSize;
+}
+
+void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage )
+{
+ //rhbz#636521, disable undo during conversion. faster, smaller and stops
+ //temp objects being inserted into the undo list
+ bool bOrigUndoStatus = rSdrModel.IsUndoEnabled();
+ rSdrModel.EnableUndo(false);
+ // register this drawing manager at the passed (global) DFF manager
+ rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage );
+ // process list of objects to be skipped
+ for( ScfUInt16Vec::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt )
+ if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aIt ).get() )
+ pDrawObj->SetProcessSdrObj( false );
+ // process drawing objects without DFF data
+ rDffConv.ProcessDrawing( maRawObjs );
+ // process all objects in the DFF stream
+ rDffConv.ProcessDrawing( maDffStrm );
+ // unregister this drawing manager at the passed (global) DFF manager
+ rDffConv.FinalizeDrawing();
+ rSdrModel.EnableUndo(bOrigUndoStatus);
+}
+
+// protected ------------------------------------------------------------------
+
+void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj )
+{
+ DBG_ASSERT( rxDrawObj, "XclImpDrawing::AppendRawObject - unexpected empty reference" );
+ maRawObjs.push_back( rxDrawObj );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper
+{
+ // extract graphic data from IMGDATA and following CONTINUE records
+ rStrm.Ignore( 8 );
+ SvMemoryStream aMemStrm;
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ // import the graphic from memory stream
+ GDIMetaFile aGDIMetaFile;
+ if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) )
+ rGraphic = aGDIMetaFile;
+}
+
+void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper
+{
+ // extract graphic data from IMGDATA and following CONTINUE records
+ SvMemoryStream aMemStrm;
+
+ /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
+ DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
+ pixel depth = 32 bit. After that, 3 unused bytes are added before the
+ actual pixel data. This does even confuse Excel 5 and later, which
+ cannot read the image data correctly. */
+ if( rRoot.GetBiff() <= EXC_BIFF4 )
+ {
+ rStrm.PushPosition();
+ sal_uInt32 nHdrSize;
+ sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
+ rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth;
+ if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
+ {
+ rStrm.Ignore( 3 );
+ aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth;
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+ }
+ rStrm.PopPosition();
+ }
+
+ // no special handling above -> just copy the remaining record data
+ if( aMemStrm.Tell() == 0 )
+ rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
+
+ // import the graphic from memory stream
+ aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ Bitmap aBitmap;
+ if( aBitmap.Read( aMemStrm, false ) ) // read DIB without file header
+ rGraphic = aBitmap;
+}
+
+void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm )
+{
+ maDffStrm.Seek( STREAM_SEEK_TO_END );
+ rStrm.CopyRecordToStream( maDffStrm );
+}
+
+void XclImpDrawing::ReadObj8( XclImpStream& rStrm )
+{
+ XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm );
+ // store the new object in the internal containers
+ maObjMap[ maDffStrm.Tell() ] = xDrawObj;
+ maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
+}
+
+void XclImpDrawing::ReadTxo( XclImpStream& rStrm )
+{
+ XclImpObjTextRef xTextData( new XclImpObjTextData );
+ maTextMap[ maDffStrm.Tell() ] = xTextData;
+
+ // 1) read the TXO record
+ xTextData->maData.ReadTxo8( rStrm );
+
+ // 2) first CONTINUE with string
+ xTextData->mxString.reset();
+ bool bValid = true;
+ if( xTextData->maData.mnTextLen > 0 )
+ {
+ bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
+ DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
+ if( bValid )
+ xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) );
+ }
+
+ // 3) second CONTINUE with formatting runs
+ if( xTextData->maData.mnFormatSize > 0 )
+ {
+ bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
+ DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
+ if( bValid )
+ xTextData->ReadFormats( rStrm );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ) :
+ XclImpDrawing( rRoot, true ),
+ maScUsedArea( ScAddress::INITIALIZE_INVALID )
+{
+ maScUsedArea.aStart.SetTab( nScTab );
+ maScUsedArea.aEnd.SetTab( nScTab );
+}
+
+void XclImpSheetDrawing::ReadNote( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ ReadNote3( rStrm );
+ break;
+ case EXC_BIFF8:
+ ReadNote8( rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpSheetDrawing::ReadTabChart( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 );
+ boost::shared_ptr< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) );
+ xChartObj->ReadChartSubStream( rStrm );
+ // insert the chart as raw object without connected DFF data
+ AppendRawObject( xChartObj );
+}
+
+void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv )
+{
+ if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() )
+ if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) )
+ ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
+}
+
+Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const
+{
+ return rAnchor.GetRect( GetRoot(), maScUsedArea.aStart.Tab(), MAP_100TH_MM );
+}
+
+void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj )
+{
+ ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() );
+ if( aScObjArea.IsValid() )
+ maScUsedArea.ExtendTo( aScObjArea );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nTotalLen;
+ rStrm >> aXclPos >> nTotalLen;
+
+ ScAddress aScNotePos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
+ {
+ sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
+ String aNoteText = rStrm.ReadRawByteString( nPartLen );
+ nTotalLen = nTotalLen - nPartLen;
+ while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() )
+ {
+ rStrm >> aXclPos >> nPartLen;
+ DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
+ if( aXclPos.mnRow == 0xFFFF )
+ {
+ DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
+ aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) );
+ nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
+ }
+ else
+ {
+ // seems to be a new note, record already started -> load the note
+ rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
+ ReadNote( rStrm );
+ nTotalLen = 0;
+ }
+ }
+ ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
+ }
+}
+
+void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm )
+{
+ XclAddress aXclPos;
+ sal_uInt16 nFlags, nObjId;
+ rStrm >> aXclPos >> nFlags >> nObjId;
+
+ ScAddress aScNotePos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
+ if( nObjId != EXC_OBJ_INVALID_ID )
+ if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) )
+ pNoteObj->SetNoteData( aScNotePos, nFlags );
+}
+
+// The object manager =========================================================
+
+XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" );
+ maDefObjNames[ EXC_OBJTYPE_LINE ] = ScGlobal::GetRscString( STR_SHAPE_LINE );
+ maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = ScGlobal::GetRscString( STR_SHAPE_RECTANGLE );
+ maDefObjNames[ EXC_OBJTYPE_OVAL ] = ScGlobal::GetRscString( STR_SHAPE_OVAL );
+ maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" );
+ maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" );
+ maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" );
+ maDefObjNames[ EXC_OBJTYPE_BUTTON ] = ScGlobal::GetRscString( STR_FORM_BUTTON );
+ maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" );
+ maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" );
+ maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = ScGlobal::GetRscString( STR_FORM_CHECKBOX );
+ maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = ScGlobal::GetRscString( STR_FORM_OPTIONBUTTON );
+ maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" );
+ maDefObjNames[ EXC_OBJTYPE_LABEL ] = ScGlobal::GetRscString( STR_FORM_LABEL );
+ maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" );
+ maDefObjNames[ EXC_OBJTYPE_SPIN ] = ScGlobal::GetRscString( STR_FORM_SPINNER );
+ maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = ScGlobal::GetRscString( STR_FORM_SCROLLBAR );
+ maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = ScGlobal::GetRscString( STR_FORM_LISTBOX );
+ maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = ScGlobal::GetRscString( STR_FORM_GROUPBOX );
+ maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = ScGlobal::GetRscString( STR_FORM_DROPDOWN );
+ maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" );
+ maDefObjNames[ EXC_OBJTYPE_DRAWING ] = ScGlobal::GetRscString( STR_SHAPE_AUTOSHAPE );
+}
+
+XclImpObjectManager::~XclImpObjectManager()
+{
+}
+
+void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
+ rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
+ maDggStrm.Seek( STREAM_SEEK_TO_END );
+ rStrm.CopyRecordToStream( maDggStrm );
+}
+
+XclImpSheetDrawing& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab )
+{
+ XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ];
+ if( !rxDrawing )
+ rxDrawing.reset( new XclImpSheetDrawing( GetRoot(), nScTab ) );
+ return *rxDrawing;
+}
+
+void XclImpObjectManager::ConvertObjects()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
+
+ // do nothing if the document does not contain a drawing layer
+ if( !GetDoc().GetDrawLayer() )
+ return;
+
+ // get total progress bar size for all sheet drawing managers
+ sal_Size nProgressSize = 0;
+ for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
+ nProgressSize += aIt->second->GetProgressSize();
+ // nothing to do if progress bar is zero (no objects present)
+ if( nProgressSize == 0 )
+ return;
+
+ XclImpDffConverter aDffConv( GetRoot(), maDggStrm );
+ aDffConv.StartProgressBar( nProgressSize );
+ for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
+ aIt->second->ConvertObjects( aDffConv );
+
+ // #i112436# don't call ScChartListenerCollection::SetDirty here,
+ // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
+}
+
+String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const
+{
+ String aDefName;
+ DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
+ if( aIt != maDefObjNames.end() )
+ aDefName.Append( aIt->second );
+ return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId() ) );
+}
+
+ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const
+{
+ XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab );
+ if( aIt != maSheetDrawings.end() )
+ return aIt->second->GetUsedArea();
+ return ScRange( ScAddress::INITIALIZE_INVALID );
+}
+
+// DFF property set helper ====================================================
+
+XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maDffConv( rRoot, maDummyStrm )
+{
+}
+
+void XclImpDffPropSet::Read( XclImpStream& rStrm )
+{
+ sal_uInt32 nPropSetSize;
+
+ rStrm.PushPosition();
+ rStrm.Ignore( 4 );
+ rStrm >> nPropSetSize;
+ rStrm.PopPosition();
+
+ mxMemStrm.reset( new SvMemoryStream );
+ rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
+ mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ maDffConv.ReadPropSet( *mxMemStrm, 0 );
+}
+
+sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const
+{
+ return maDffConv.GetPropertyValue( nPropId, nDefault );
+}
+
+void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const
+{
+ if( mxMemStrm.get() )
+ maDffConv.ApplyAttributes( *mxMemStrm, rItemSet );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet )
+{
+ rPropSet.Read( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xiformula.cxx b/sc/source/filter/excel/xiformula.cxx
new file mode 100644
index 000000000000..c9927ff570fd
--- /dev/null
+++ b/sc/source/filter/excel/xiformula.cxx
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sc.hxx"
+#include "xiformula.hxx"
+#include "rangelst.hxx"
+#include "xistream.hxx"
+
+#include "excform.hxx"
+
+// Formula compiler ===========================================================
+
+/** Implementation class of the export formula compiler. */
+class XclImpFmlaCompImpl : protected XclImpRoot, protected XclTokenArrayHelper
+{
+public:
+ explicit XclImpFmlaCompImpl( const XclImpRoot& rRoot );
+
+ /** Creates a range list from the passed Excel token array. */
+ void CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm );
+
+ const ScTokenArray* CreateFormula( XclFormulaType eType, const XclTokenArray& rXclTokArr );
+
+ // ------------------------------------------------------------------------
+private:
+ XclFunctionProvider maFuncProv; /// Excel function data provider.
+ const XclBiff meBiff; /// Cached BIFF version to save GetBiff() calls.
+};
+
+// ----------------------------------------------------------------------------
+
+XclImpFmlaCompImpl::XclImpFmlaCompImpl( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() )
+{
+}
+
+void XclImpFmlaCompImpl::CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType /*eType*/,
+ const XclTokenArray& rXclTokArr, XclImpStream& /*rStrm*/ )
+{
+ rScRanges.RemoveAll();
+
+ //! evil hack, using old formula import :-)
+ if( !rXclTokArr.Empty() )
+ {
+ SvMemoryStream aMemStrm;
+ aMemStrm << EXC_ID_EOF << rXclTokArr.GetSize();
+ aMemStrm.Write( rXclTokArr.GetData(), rXclTokArr.GetSize() );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ GetOldFmlaConverter().GetAbsRefs( rScRanges, aFmlaStrm, aFmlaStrm.GetRecSize() );
+ }
+}
+
+const ScTokenArray* XclImpFmlaCompImpl::CreateFormula(
+ XclFormulaType /*eType*/, const XclTokenArray& rXclTokArr )
+{
+ if (rXclTokArr.Empty())
+ return NULL;
+
+ // evil hack! are we trying to phase out the old style formula converter ?
+ SvMemoryStream aMemStrm;
+ aMemStrm << EXC_ID_EOF << rXclTokArr.GetSize();
+ aMemStrm.Write( rXclTokArr.GetData(), rXclTokArr.GetSize() );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ const ScTokenArray* pArray = NULL;
+ GetOldFmlaConverter().Reset();
+ GetOldFmlaConverter().Convert(pArray, aFmlaStrm, aFmlaStrm.GetRecSize(), true);
+ return pArray;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpFormulaCompiler::XclImpFormulaCompiler( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mxImpl( new XclImpFmlaCompImpl( rRoot ) )
+{
+}
+
+XclImpFormulaCompiler::~XclImpFormulaCompiler()
+{
+}
+
+void XclImpFormulaCompiler::CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm )
+{
+ mxImpl->CreateRangeList( rScRanges, eType, rXclTokArr, rStrm );
+}
+
+const ScTokenArray* XclImpFormulaCompiler::CreateFormula(
+ XclFormulaType eType, const XclTokenArray& rXclTokArr )
+{
+ return mxImpl->CreateFormula(eType, rXclTokArr);
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xihelper.cxx b/sc/source/filter/excel/xihelper.cxx
new file mode 100644
index 000000000000..7fd1dd17e65a
--- /dev/null
+++ b/sc/source/filter/excel/xihelper.cxx
@@ -0,0 +1,893 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xihelper.hxx"
+#include <svl/itemset.hxx>
+#include <editeng/editobj.hxx>
+#include <tools/urlobj.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include "document.hxx"
+#include "cell.hxx"
+#include "rangelst.hxx"
+#include "editutil.hxx"
+#include "attrib.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+
+#include "excform.hxx"
+
+// Excel->Calc cell address/range conversion ==================================
+
+namespace {
+
+/** Fills the passed Calc address with the passed Excel cell coordinates without checking any limits. */
+inline void lclFillAddress( ScAddress& rScPos, sal_uInt16 nXclCol, sal_uInt32 nXclRow, SCTAB nScTab )
+{
+ rScPos.SetCol( static_cast< SCCOL >( nXclCol ) );
+ rScPos.SetRow( static_cast< SCROW >( nXclRow ) );
+ rScPos.SetTab( nScTab );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpAddressConverter::XclImpAddressConverter( const XclImpRoot& rRoot ) :
+ XclAddressConverterBase( rRoot.GetTracer(), rRoot.GetScMaxPos() )
+{
+}
+
+// cell address ---------------------------------------------------------------
+
+bool XclImpAddressConverter::CheckAddress( const XclAddress& rXclPos, bool bWarn )
+{
+ bool bValidCol = rXclPos.mnCol <= mnMaxCol;
+ bool bValidRow = rXclPos.mnRow <= mnMaxRow;
+ bool bValid = bValidCol && bValidRow;
+ if( !bValid && bWarn )
+ {
+ mbColTrunc |= !bValidCol;
+ mbRowTrunc |= !bValidRow;
+ mrTracer.TraceInvalidAddress( ScAddress(
+ static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), 0 ), maMaxPos );
+ }
+ return bValid;
+}
+
+bool XclImpAddressConverter::ConvertAddress( ScAddress& rScPos,
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
+{
+ bool bValid = CheckAddress( rXclPos, bWarn );
+ if( bValid )
+ lclFillAddress( rScPos, rXclPos.mnCol, rXclPos.mnRow, nScTab );
+ return bValid;
+}
+
+ScAddress XclImpAddressConverter::CreateValidAddress(
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn )
+{
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( !ConvertAddress( aScPos, rXclPos, nScTab, bWarn ) )
+ {
+ aScPos.SetCol( static_cast< SCCOL >( ::std::min( rXclPos.mnCol, mnMaxCol ) ) );
+ aScPos.SetRow( static_cast< SCROW >( ::std::min( rXclPos.mnRow, mnMaxRow ) ) );
+ aScPos.SetTab( limit_cast< SCTAB >( nScTab, 0, maMaxPos.Tab() ) );
+ }
+ return aScPos;
+}
+
+// cell range -----------------------------------------------------------------
+
+bool XclImpAddressConverter::ConvertRange( ScRange& rScRange,
+ const XclRange& rXclRange, SCTAB nScTab1, SCTAB nScTab2, bool bWarn )
+{
+ // check start position
+ bool bValidStart = CheckAddress( rXclRange.maFirst, bWarn );
+ if( bValidStart )
+ {
+ lclFillAddress( rScRange.aStart, rXclRange.maFirst.mnCol, rXclRange.maFirst.mnRow, nScTab1 );
+
+ // check & correct end position
+ sal_uInt16 nXclCol2 = rXclRange.maLast.mnCol;
+ sal_uInt32 nXclRow2 = rXclRange.maLast.mnRow;
+ if( !CheckAddress( rXclRange.maLast, bWarn ) )
+ {
+ nXclCol2 = ::std::min( nXclCol2, mnMaxCol );
+ nXclRow2 = ::std::min( nXclRow2, mnMaxRow );
+ }
+ lclFillAddress( rScRange.aEnd, nXclCol2, nXclRow2, nScTab2 );
+ }
+ return bValidStart;
+}
+
+// cell range list ------------------------------------------------------------
+
+void XclImpAddressConverter::ConvertRangeList( ScRangeList& rScRanges,
+ const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn )
+{
+ rScRanges.RemoveAll();
+ for( XclRangeList::const_iterator aIt = rXclRanges.begin(), aEnd = rXclRanges.end(); aIt != aEnd; ++aIt )
+ {
+ ScRange aScRange( ScAddress::UNINITIALIZED );
+ if( ConvertRange( aScRange, *aIt, nScTab, nScTab, bWarn ) )
+ rScRanges.Append( aScRange );
+ }
+}
+
+// String->EditEngine conversion ==============================================
+
+namespace {
+
+EditTextObject* lclCreateTextObject( const XclImpRoot& rRoot,
+ const XclImpString& rString, XclFontItemType eType, sal_uInt16 nXFIndex )
+{
+ EditTextObject* pTextObj = 0;
+
+ const XclImpXFBuffer& rXFBuffer = rRoot.GetXFBuffer();
+ const XclImpFont* pFirstFont = rXFBuffer.GetFont( nXFIndex );
+ bool bFirstEscaped = pFirstFont && pFirstFont->HasEscapement();
+
+ if( rString.IsRich() || bFirstEscaped )
+ {
+ const XclImpFontBuffer& rFontBuffer = rRoot.GetFontBuffer();
+ const XclFormatRunVec& rFormats = rString.GetFormats();
+
+ ScEditEngineDefaulter& rEE = (eType == EXC_FONTITEM_NOTE) ?
+ static_cast< ScEditEngineDefaulter& >( rRoot.GetDoc().GetNoteEngine() ) : rRoot.GetEditEngine();
+ rEE.SetText( rString.GetText() );
+
+ SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
+ if( bFirstEscaped )
+ rFontBuffer.FillToItemSet( aItemSet, eType, rXFBuffer.GetFontIndex( nXFIndex ) );
+ ESelection aSelection;
+
+ XclFormatRun aNextRun;
+ XclFormatRunVec::const_iterator aIt = rFormats.begin();
+ XclFormatRunVec::const_iterator aEnd = rFormats.end();
+
+ if( aIt != aEnd )
+ aNextRun = *aIt++;
+ else
+ aNextRun.mnChar = 0xFFFF;
+
+ xub_StrLen nLen = rString.GetText().Len();
+ for( sal_uInt16 nChar = 0; nChar < nLen; ++nChar )
+ {
+ // reached new different formatted text portion
+ if( nChar >= aNextRun.mnChar )
+ {
+ // send items to edit engine
+ rEE.QuickSetAttribs( aItemSet, aSelection );
+
+ // start new item set
+ aItemSet.ClearItem();
+ rFontBuffer.FillToItemSet( aItemSet, eType, aNextRun.mnFontIdx );
+
+ // read new formatting information
+ if( aIt != aEnd )
+ aNextRun = *aIt++;
+ else
+ aNextRun.mnChar = 0xFFFF;
+
+ // reset selection start to current position
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ // set end of selection to current position
+ if( rString.GetText().GetChar( nChar ) == '\n' )
+ {
+ ++aSelection.nEndPara;
+ aSelection.nEndPos = 0;
+ }
+ else
+ ++aSelection.nEndPos;
+ }
+
+ // send items of last text portion to edit engine
+ rEE.QuickSetAttribs( aItemSet, aSelection );
+
+ pTextObj = rEE.CreateTextObject();
+ }
+
+ return pTextObj;
+}
+
+} // namespace
+
+EditTextObject* XclImpStringHelper::CreateTextObject(
+ const XclImpRoot& rRoot, const XclImpString& rString )
+{
+ return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, 0 );
+}
+
+ScBaseCell* XclImpStringHelper::CreateCell(
+ const XclImpRoot& rRoot, const XclImpString& rString, sal_uInt16 nXFIndex )
+{
+ ScBaseCell* pCell = 0;
+
+ if( rString.GetText().Len() )
+ {
+ ::std::auto_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
+ ScDocument& rDoc = rRoot.GetDoc();
+
+ if( pTextObj.get() )
+ // ScEditCell creates own copy of text object
+ pCell = new ScEditCell( pTextObj.get(), &rDoc, rRoot.GetEditEngine().GetEditTextObjectPool() );
+ else
+ pCell = ScBaseCell::CreateTextCell( rString.GetText(), &rDoc );
+ }
+
+ return pCell;
+}
+
+// Header/footer conversion ===================================================
+
+XclImpHFConverter::XclImpHFPortionInfo::XclImpHFPortionInfo() :
+ mnHeight( 0 ),
+ mnMaxLineHt( 0 )
+{
+ maSel.nStartPara = maSel.nEndPara = 0;
+ maSel.nStartPos = maSel.nEndPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpHFConverter::XclImpHFConverter( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mrEE( rRoot.GetHFEditEngine() ),
+ mxFontData( new XclFontData ),
+ meCurrObj( EXC_HF_CENTER )
+{
+}
+
+XclImpHFConverter::~XclImpHFConverter()
+{
+}
+
+void XclImpHFConverter::ParseString( const String& rHFString )
+{
+ // edit engine objects
+ mrEE.SetText( EMPTY_STRING );
+ maInfos.clear();
+ maInfos.resize( EXC_HF_PORTION_COUNT );
+ meCurrObj = EXC_HF_CENTER;
+
+ // parser temporaries
+ maCurrText.Erase();
+ String aReadFont; // current font name
+ String aReadStyle; // current font style
+ sal_uInt16 nReadHeight = 0; // current font height
+ ResetFontData();
+
+ /** State of the parser. */
+ enum XclHFParserState
+ {
+ xlPSText, /// Read text, search for functions.
+ xlPSFunc, /// Read function (token following a '&').
+ xlPSFont, /// Read font name ('&' is followed by '"', reads until next '"' or ',').
+ xlPSFontStyle, /// Read font style name (font part after ',', reads until next '"').
+ xlPSHeight /// Read font height ('&' is followed by num. digits, reads until non-digit).
+ } eState = xlPSText;
+
+ const sal_Unicode* pChar = rHFString.GetBuffer();
+ const sal_Unicode* pNull = pChar + rHFString.Len(); // pointer to teminating null char
+ while( *pChar )
+ {
+ switch( eState )
+ {
+
+// --- read text character ---
+
+ case xlPSText:
+ {
+ switch( *pChar )
+ {
+ case '&': // new command
+ InsertText();
+ eState = xlPSFunc;
+ break;
+ case '\n': // line break
+ InsertText();
+ InsertLineBreak();
+ break;
+ default:
+ maCurrText += *pChar;
+ }
+ }
+ break;
+
+// --- read control sequence ---
+
+ case xlPSFunc:
+ {
+ eState = xlPSText;
+ switch( *pChar )
+ {
+ case '&': maCurrText += '&'; break; // the '&' character
+
+ case 'L': SetNewPortion( EXC_HF_LEFT ); break; // Left portion
+ case 'C': SetNewPortion( EXC_HF_CENTER ); break; // Center portion
+ case 'R': SetNewPortion( EXC_HF_RIGHT ); break; // Right portion
+
+ case 'P': InsertField( SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD ) ); break; // page
+ case 'N': InsertField( SvxFieldItem( SvxPagesField(), EE_FEATURE_FIELD ) ); break; // page count
+ case 'D': InsertField( SvxFieldItem( SvxDateField(), EE_FEATURE_FIELD ) ); break; // date
+ case 'T': InsertField( SvxFieldItem( SvxTimeField(), EE_FEATURE_FIELD ) ); break; // time
+ case 'A': InsertField( SvxFieldItem( SvxTableField(), EE_FEATURE_FIELD ) ); break; // table name
+
+ case 'Z': // file path
+ InsertField( SvxFieldItem( SvxExtFileField(), EE_FEATURE_FIELD ) ); // convert to full name
+ if( (pNull - pChar >= 2) && (*(pChar + 1) == '&') && (*(pChar + 2) == 'F') )
+ {
+ // &Z&F found - ignore the &F part
+ pChar += 2;
+ }
+ break;
+ case 'F': // file name
+ InsertField( SvxFieldItem( SvxExtFileField( EMPTY_STRING, SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT ), EE_FEATURE_FIELD ) );
+ break;
+
+ case 'U': // underline
+ SetAttribs();
+ mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_SINGLE) ?
+ EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_SINGLE;
+ break;
+ case 'E': // double underline
+ SetAttribs();
+ mxFontData->mnUnderline = (mxFontData->mnUnderline == EXC_FONTUNDERL_DOUBLE) ?
+ EXC_FONTUNDERL_NONE : EXC_FONTUNDERL_DOUBLE;
+ break;
+ case 'S': // strikeout
+ SetAttribs();
+ mxFontData->mbStrikeout = !mxFontData->mbStrikeout;
+ break;
+ case 'X': // superscript
+ SetAttribs();
+ mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUPER) ?
+ EXC_FONTESC_NONE : EXC_FONTESC_SUPER;
+ break;
+ case 'Y': // subsrcipt
+ SetAttribs();
+ mxFontData->mnEscapem = (mxFontData->mnEscapem == EXC_FONTESC_SUB) ?
+ EXC_FONTESC_NONE : EXC_FONTESC_SUB;
+ break;
+
+ case '\"': // font name
+ aReadFont.Erase();
+ aReadStyle.Erase();
+ eState = xlPSFont;
+ break;
+ default:
+ if( ('0' <= *pChar) && (*pChar <= '9') ) // font size
+ {
+ nReadHeight = *pChar - '0';
+ eState = xlPSHeight;
+ }
+ }
+ }
+ break;
+
+// --- read font name ---
+
+ case xlPSFont:
+ {
+ switch( *pChar )
+ {
+ case '\"':
+ --pChar;
+ // run through
+ case ',':
+ eState = xlPSFontStyle;
+ break;
+ default:
+ aReadFont += *pChar;
+ }
+ }
+ break;
+
+// --- read font style ---
+
+ case xlPSFontStyle:
+ {
+ switch( *pChar )
+ {
+ case '\"':
+ SetAttribs();
+ if( aReadFont.Len() )
+ mxFontData->maName = aReadFont;
+ mxFontData->maStyle = aReadStyle;
+ eState = xlPSText;
+ break;
+ default:
+ aReadStyle += *pChar;
+ }
+ }
+ break;
+
+// --- read font height ---
+
+ case xlPSHeight:
+ {
+ if( ('0' <= *pChar) && (*pChar <= '9') )
+ {
+ if( nReadHeight != 0xFFFF )
+ {
+ nReadHeight *= 10;
+ nReadHeight += (*pChar - '0');
+ if( nReadHeight > 1600 ) // max 1600pt = 32000twips
+ nReadHeight = 0xFFFF;
+ }
+ }
+ else
+ {
+ if( (nReadHeight != 0) && (nReadHeight != 0xFFFF) )
+ {
+ SetAttribs();
+ mxFontData->mnHeight = nReadHeight * 20;
+ }
+ --pChar;
+ eState = xlPSText;
+ }
+ }
+ break;
+ }
+ ++pChar;
+ }
+
+ // finalize
+ CreateCurrObject();
+ maInfos[ EXC_HF_LEFT ].mnHeight += GetMaxLineHeight( EXC_HF_LEFT );
+ maInfos[ EXC_HF_CENTER ].mnHeight += GetMaxLineHeight( EXC_HF_CENTER );
+ maInfos[ EXC_HF_RIGHT ].mnHeight += GetMaxLineHeight( EXC_HF_RIGHT );
+}
+
+void XclImpHFConverter::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const
+{
+ ScPageHFItem aHFItem( nWhichId );
+ if( maInfos[ EXC_HF_LEFT ].mxObj.get() )
+ aHFItem.SetLeftArea( *maInfos[ EXC_HF_LEFT ].mxObj );
+ if( maInfos[ EXC_HF_CENTER ].mxObj.get() )
+ aHFItem.SetCenterArea( *maInfos[ EXC_HF_CENTER ].mxObj );
+ if( maInfos[ EXC_HF_RIGHT ].mxObj.get() )
+ aHFItem.SetRightArea( *maInfos[ EXC_HF_RIGHT ].mxObj );
+ rItemSet.Put( aHFItem );
+}
+
+sal_Int32 XclImpHFConverter::GetTotalHeight() const
+{
+ return ::std::max( maInfos[ EXC_HF_LEFT ].mnHeight,
+ ::std::max( maInfos[ EXC_HF_CENTER ].mnHeight, maInfos[ EXC_HF_RIGHT ].mnHeight ) );
+}
+
+// private --------------------------------------------------------------------
+
+sal_uInt16 XclImpHFConverter::GetMaxLineHeight( XclImpHFPortion ePortion ) const
+{
+ sal_uInt16 nMaxHt = maInfos[ ePortion ].mnMaxLineHt;
+ return (nMaxHt == 0) ? mxFontData->mnHeight : nMaxHt;
+}
+
+sal_uInt16 XclImpHFConverter::GetCurrMaxLineHeight() const
+{
+ return GetMaxLineHeight( meCurrObj );
+}
+
+void XclImpHFConverter::UpdateMaxLineHeight( XclImpHFPortion ePortion )
+{
+ sal_uInt16& rnMaxHt = maInfos[ ePortion ].mnMaxLineHt;
+ rnMaxHt = ::std::max( rnMaxHt, mxFontData->mnHeight );
+}
+
+void XclImpHFConverter::UpdateCurrMaxLineHeight()
+{
+ UpdateMaxLineHeight( meCurrObj );
+}
+
+void XclImpHFConverter::SetAttribs()
+{
+ ESelection& rSel = GetCurrSel();
+ if( (rSel.nStartPara != rSel.nEndPara) || (rSel.nStartPos != rSel.nEndPos) )
+ {
+ SfxItemSet aItemSet( mrEE.GetEmptyItemSet() );
+ XclImpFont aFont( GetRoot(), *mxFontData );
+ aFont.FillToItemSet( aItemSet, EXC_FONTITEM_HF );
+ mrEE.QuickSetAttribs( aItemSet, rSel );
+ rSel.nStartPara = rSel.nEndPara;
+ rSel.nStartPos = rSel.nEndPos;
+ }
+}
+
+void XclImpHFConverter::ResetFontData()
+{
+ if( const XclImpFont* pFirstFont = GetFontBuffer().GetFont( EXC_FONT_APP ) )
+ *mxFontData = pFirstFont->GetFontData();
+ else
+ {
+ mxFontData->Clear();
+ mxFontData->mnHeight = 200;
+ }
+}
+
+void XclImpHFConverter::InsertText()
+{
+ if( maCurrText.Len() )
+ {
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertText( maCurrText, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ rSel.nEndPos = rSel.nEndPos + maCurrText.Len();
+ maCurrText.Erase();
+ UpdateCurrMaxLineHeight();
+ }
+}
+
+void XclImpHFConverter::InsertField( const SvxFieldItem& rFieldItem )
+{
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertField( rFieldItem, ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ ++rSel.nEndPos;
+ UpdateCurrMaxLineHeight();
+}
+
+void XclImpHFConverter::InsertLineBreak()
+{
+ ESelection& rSel = GetCurrSel();
+ mrEE.QuickInsertText( String( '\n' ), ESelection( rSel.nEndPara, rSel.nEndPos, rSel.nEndPara, rSel.nEndPos ) );
+ ++rSel.nEndPara;
+ rSel.nEndPos = 0;
+ GetCurrInfo().mnHeight += GetCurrMaxLineHeight();
+ GetCurrInfo().mnMaxLineHt = 0;
+}
+
+void XclImpHFConverter::CreateCurrObject()
+{
+ InsertText();
+ SetAttribs();
+ GetCurrObj().reset( mrEE.CreateTextObject() );
+}
+
+void XclImpHFConverter::SetNewPortion( XclImpHFPortion eNew )
+{
+ if( eNew != meCurrObj )
+ {
+ CreateCurrObject();
+ meCurrObj = eNew;
+ if( GetCurrObj().get() )
+ mrEE.SetText( *GetCurrObj() );
+ else
+ mrEE.SetText( EMPTY_STRING );
+ ResetFontData();
+ }
+}
+
+// URL conversion =============================================================
+
+namespace {
+
+void lclAppendUrlChar( String& rUrl, sal_Unicode cChar )
+{
+ // encode special characters
+ switch( cChar )
+ {
+ case '#': rUrl.AppendAscii( "%23" ); break;
+ case '%': rUrl.AppendAscii( "%25" ); break;
+ default: rUrl.Append( cChar );
+ }
+}
+
+} // namespace
+
+void XclImpUrlHelper::DecodeUrl(
+ String& rUrl, String& rTabName, bool& rbSameWb,
+ const XclImpRoot& rRoot, const String& rEncodedUrl )
+{
+ enum
+ {
+ xlUrlInit, /// Initial state, read string mode character.
+ xlUrlPath, /// Read URL path.
+ xlUrlFileName, /// Read file name.
+ xlUrlSheetName, /// Read sheet name.
+ xlUrlRaw /// Raw mode. No control characters will occur.
+ } eState = xlUrlInit;
+
+ bool bEncoded = true;
+ rbSameWb = false;
+
+ sal_Unicode cCurrDrive = 0;
+ String aDosBase( INetURLObject( rRoot.GetBasePath() ).getFSysPath( INetURLObject::FSYS_DOS ) );
+ if( (aDosBase.Len() > 2) && aDosBase.EqualsAscii( ":\\", 1, 2 ) )
+ cCurrDrive = aDosBase.GetChar( 0 );
+
+ const sal_Unicode* pChar = rEncodedUrl.GetBuffer();
+ while( *pChar )
+ {
+ switch( eState )
+ {
+
+// --- first character ---
+
+ case xlUrlInit:
+ {
+ switch( *pChar )
+ {
+ case EXC_URLSTART_ENCODED:
+ eState = xlUrlPath;
+ break;
+ case EXC_URLSTART_SELF:
+ case EXC_URLSTART_SELFENCODED:
+ rbSameWb = true;
+ eState = xlUrlSheetName;
+ break;
+ case '[':
+ bEncoded = false;
+ eState = xlUrlFileName;
+ break;
+ default:
+ bEncoded = false;
+ lclAppendUrlChar( rUrl, *pChar );
+ eState = xlUrlPath;
+ }
+ }
+ break;
+
+// --- URL path ---
+
+ case xlUrlPath:
+ {
+ switch( *pChar )
+ {
+ case EXC_URL_DOSDRIVE:
+ {
+ if( *(pChar + 1) )
+ {
+ ++pChar;
+ if( *pChar == '@' )
+ rUrl.AppendAscii( "\\\\" );
+ else
+ {
+ lclAppendUrlChar( rUrl, *pChar );
+ rUrl.AppendAscii( ":\\" );
+ }
+ }
+ else
+ rUrl.AppendAscii( "<NULL-DRIVE!>" );
+ }
+ break;
+ case EXC_URL_DRIVEROOT:
+ if( cCurrDrive )
+ {
+ lclAppendUrlChar( rUrl, cCurrDrive );
+ rUrl.Append( ':' );
+ }
+ // run through
+ case EXC_URL_SUBDIR:
+ if( bEncoded )
+ rUrl.Append( '\\' );
+ else // control character in raw name -> DDE link
+ {
+ rUrl.Append( EXC_DDE_DELIM );
+ eState = xlUrlRaw;
+ }
+ break;
+ case EXC_URL_PARENTDIR:
+ rUrl.AppendAscii( "..\\" );
+ break;
+ case EXC_URL_RAW:
+ {
+ if( *(pChar + 1) )
+ {
+ xub_StrLen nLen = *++pChar;
+ for( xub_StrLen nChar = 0; (nChar < nLen) && *(pChar + 1); ++nChar )
+ lclAppendUrlChar( rUrl, *++pChar );
+// rUrl.Append( ':' );
+ }
+ }
+ break;
+ case '[':
+ eState = xlUrlFileName;
+ break;
+ default:
+ lclAppendUrlChar( rUrl, *pChar );
+ }
+ }
+ break;
+
+// --- file name ---
+
+ case xlUrlFileName:
+ {
+ switch( *pChar )
+ {
+ case ']': eState = xlUrlSheetName; break;
+ default: lclAppendUrlChar( rUrl, *pChar );
+ }
+ }
+ break;
+
+// --- sheet name ---
+
+ case xlUrlSheetName:
+ rTabName.Append( *pChar );
+ break;
+
+// --- raw read mode ---
+
+ case xlUrlRaw:
+ lclAppendUrlChar( rUrl, *pChar );
+ break;
+ }
+
+ ++pChar;
+ }
+}
+
+void XclImpUrlHelper::DecodeUrl(
+ String& rUrl, bool& rbSameWb, const XclImpRoot& rRoot, const String& rEncodedUrl )
+{
+ String aTabName;
+ DecodeUrl( rUrl, aTabName, rbSameWb, rRoot, rEncodedUrl );
+ DBG_ASSERT( !aTabName.Len(), "XclImpUrlHelper::DecodeUrl - sheet name ignored" );
+}
+
+bool XclImpUrlHelper::DecodeLink( String& rApplic, String& rTopic, const String rEncUrl )
+{
+ xub_StrLen nPos = rEncUrl.Search( EXC_DDE_DELIM );
+ if( (nPos != STRING_NOTFOUND) && (0 < nPos) && (nPos + 1 < rEncUrl.Len()) )
+ {
+ rApplic = rEncUrl.Copy( 0, nPos );
+ rTopic = rEncUrl.Copy( nPos + 1 );
+ return true;
+ }
+ return false;
+}
+
+// Cached Values ==============================================================
+
+XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm ) :
+ mfValue( 0.0 ),
+ mnBoolErr( 0 )
+{
+ rStrm >> mnType;
+ switch( mnType )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ rStrm.Ignore( 8 );
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ rStrm >> mfValue;
+ break;
+ case EXC_CACHEDVAL_STRING:
+ mxStr.reset( new String( rStrm.ReadUniString() ) );
+ break;
+ case EXC_CACHEDVAL_BOOL:
+ case EXC_CACHEDVAL_ERROR:
+ {
+ double fVal;
+ rStrm >> mnBoolErr;
+ rStrm.Ignore( 7 );
+
+ const ScTokenArray* pScTokArr = rStrm.GetRoot().GetOldFmlaConverter().GetBoolErr(
+ XclTools::ErrorToEnum( fVal, mnType == EXC_CACHEDVAL_ERROR, mnBoolErr ) );
+ if( pScTokArr )
+ mxTokArr.reset( pScTokArr->Clone() );
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpCachedValue::XclImpCachedValue - unknown data type" );
+ }
+}
+
+XclImpCachedValue::~XclImpCachedValue()
+{
+}
+
+sal_uInt16 XclImpCachedValue::GetScError() const
+{
+ return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : 0;
+}
+
+// Matrix Cached Values ==============================================================
+
+XclImpCachedMatrix::XclImpCachedMatrix( XclImpStream& rStrm ) :
+ mnScCols( 0 ),
+ mnScRows( 0 )
+{
+ mnScCols = rStrm.ReaduInt8();
+ mnScRows = rStrm.ReaduInt16();
+
+ if( rStrm.GetRoot().GetBiff() <= EXC_BIFF5 )
+ {
+ // in BIFF2-BIFF7: 256 columns represented by 0 columns
+ if( mnScCols == 0 )
+ mnScCols = 256;
+ }
+ else
+ {
+ // in BIFF8: columns and rows decreaed by 1
+ ++mnScCols;
+ ++mnScRows;
+ }
+
+ for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
+ for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
+ maValueList.push_back( new XclImpCachedValue( rStrm ) );
+}
+
+XclImpCachedMatrix::~XclImpCachedMatrix()
+{
+}
+
+ScMatrixRef XclImpCachedMatrix::CreateScMatrix() const
+{
+ ScMatrixRef xScMatrix;
+ DBG_ASSERT( mnScCols * mnScRows == maValueList.size(), "XclImpCachedMatrix::CreateScMatrix - element count mismatch" );
+ if( mnScCols && mnScRows && static_cast< sal_uLong >( mnScCols * mnScRows ) <= maValueList.size() )
+ {
+ xScMatrix = new ScMatrix( mnScCols, mnScRows );
+ XclImpValueList::const_iterator itValue = maValueList.begin();
+ for( SCSIZE nScRow = 0; nScRow < mnScRows; ++nScRow )
+ {
+ for( SCSIZE nScCol = 0; nScCol < mnScCols; ++nScCol )
+ {
+ switch( itValue->GetType() )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ // Excel shows 0.0 here, not an empty cell
+ xScMatrix->PutEmpty( nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ xScMatrix->PutDouble( itValue->GetValue(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_STRING:
+ xScMatrix->PutString( itValue->GetString(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_BOOL:
+ xScMatrix->PutBoolean( itValue->GetBool(), nScCol, nScRow );
+ break;
+ case EXC_CACHEDVAL_ERROR:
+ xScMatrix->PutError( itValue->GetScError(), nScCol, nScRow );
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpCachedMatrix::CreateScMatrix - unknown value type" );
+ xScMatrix->PutEmpty( nScCol, nScRow );
+ }
+ ++itValue;
+ }
+ }
+ }
+ return xScMatrix;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
new file mode 100644
index 000000000000..492fe5d2033c
--- /dev/null
+++ b/sc/source/filter/excel/xilink.cxx
@@ -0,0 +1,952 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xilink.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "scextopt.hxx"
+#include "tablink.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiname.hxx"
+#include "excform.hxx"
+#include "tokenarray.hxx"
+#include "externalrefmgr.hxx"
+
+#include <vector>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+using ::std::vector;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+
+// ============================================================================
+// *** Helper classes ***
+// ============================================================================
+
+// Cached external cells ======================================================
+
+/**
+ * Contains the address and value of an external referenced cell.
+ * Note that this is non-copyable, so cannot be used in most stl/boost containers.
+ */
+class XclImpCrn : public XclImpCachedValue
+{
+public:
+ /** Reads a cached value and stores it with its cell address. */
+ explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
+
+ const XclAddress& GetAddress() const;
+
+private:
+ XclAddress maXclPos; /// Excel position of the cached cell.
+};
+
+// Sheet in an external document ==============================================
+
+/** Contains the name and sheet index of one sheet in an external document. */
+class XclImpSupbookTab
+{
+public:
+ /** Stores the sheet name and marks the sheet index as invalid.
+ The sheet index is set while creating the Calc sheet with CreateTable(). */
+ explicit XclImpSupbookTab( const String& rTabName );
+ ~XclImpSupbookTab();
+
+ inline const String& GetTabName() const { return maTabName; }
+
+ /** Reads a CRN record (external referenced cell) at the specified address. */
+ void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
+
+ void LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
+
+private:
+ typedef boost::shared_ptr< XclImpCrn > XclImpCrnRef;
+ typedef std::vector< XclImpCrnRef > XclImpCrnList;
+
+ XclImpCrnList maCrnList; /// List of CRN records (cached cell values).
+ String maTabName; /// Name of the external sheet.
+ SCTAB mnScTab; /// New sheet index in Calc document.
+};
+
+// External document (SUPBOOK) ================================================
+
+/** This class represents an external linked document (record SUPBOOK).
+ @descr Contains a list of all referenced sheets in the document. */
+class XclImpSupbook : protected XclImpRoot
+{
+public:
+ /** Reads the SUPBOOK record from stream. */
+ explicit XclImpSupbook( XclImpStream& rStrm );
+
+ /** Reads an XCT record (count of following CRNs and current sheet). */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record (external referenced cell). */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns the SUPBOOK record type. */
+ inline XclSupbookType GetType() const { return meType; }
+
+ /** Returns the URL of the external document. */
+ inline const String& GetXclUrl() const { return maXclUrl; }
+
+ /** Returns the external name specified by an index from the Excel document (one-based). */
+ const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
+ /** Tries to decode the URL to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rDoc ) const;
+ /** Returns the specified macro name (1-based) or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
+
+ const String& GetTabName( sal_uInt16 nXtiTab ) const;
+
+ sal_uInt16 GetTabCount() const;
+
+ void LoadCachedValues();
+
+private:
+ typedef boost::ptr_vector< XclImpSupbookTab > XclImpSupbookTabList;
+ typedef boost::ptr_vector< XclImpExtName > XclImpExtNameList;
+
+ XclImpSupbookTabList maSupbTabList; /// All sheet names of the document.
+ XclImpExtNameList maExtNameList; /// All external names of the document.
+ String maXclUrl; /// URL of the external document (Excel mode).
+ String maFilterName; /// Detected filer name.
+ String maFilterOpt; /// Detected filer options.
+ XclSupbookType meType; /// Type of the supbook record.
+ sal_uInt16 mnSBTab; /// Current Excel sheet index from SUPBOOK for XCT/CRN records.
+};
+
+// Import link manager ========================================================
+
+/** Contains the SUPBOOK index and sheet indexes of an external link.
+ @descr It is possible to enter a formula like =SUM(Sheet1:Sheet3!A1),
+ therefore here occurs a sheet range. */
+struct XclImpXti
+{
+ sal_uInt16 mnSupbook; /// Index to SUPBOOK record.
+ sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK.
+ sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK.
+ inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {}
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti )
+{
+ return rStrm >> rXti.mnSupbook >> rXti.mnSBTabFirst >> rXti.mnSBTabLast;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Implementation of the link manager. */
+class XclImpLinkManagerImpl : protected XclImpRoot
+{
+public:
+ explicit XclImpLinkManagerImpl( const XclImpRoot& rRoot );
+
+ /** Reads the EXTERNSHEET record. */
+ void ReadExternsheet( XclImpStream& rStrm );
+ /** Reads a SUPBOOK record. */
+ void ReadSupbook( XclImpStream& rStrm );
+ /** Reads an XCT record and appends it to the current SUPBOOK. */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+ /** Returns the Calc sheet index range of the specified XTI entry.
+ @return true = XTI data found, returned sheet index range is valid. */
+ bool GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
+ sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified external name or 0 on error. */
+ const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
+
+ /** Returns the absolute file URL of a supporting workbook specified by
+ the index. */
+ const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
+
+ const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
+
+ /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified macro name or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
+
+private:
+ /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */
+ const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified SUPBOOK (external document). */
+ const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const;
+
+ void LoadCachedValues();
+
+private:
+ typedef ::std::vector< XclImpXti > XclImpXtiVector;
+ typedef boost::ptr_vector< XclImpSupbook > XclImpSupbookList;
+
+ XclImpXtiVector maXtiList; /// List of all XTI structures.
+ XclImpSupbookList maSupbookList; /// List of external documents.
+ bool mbCreated; /// true = Calc sheets already created.
+};
+
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+// Excel sheet indexes ========================================================
+
+// original Excel sheet names -------------------------------------------------
+
+void XclImpTabInfo::AppendXclTabName( const String& rXclTabName, SCTAB nScTab )
+{
+ maTabNames[ rXclTabName ] = nScTab;
+}
+
+void XclImpTabInfo::InsertScTab( SCTAB nScTab )
+{
+ for( XclTabNameMap::iterator aIt = maTabNames.begin(), aEnd = maTabNames.end(); aIt != aEnd; ++aIt )
+ if( aIt->second >= nScTab )
+ ++aIt->second;
+}
+
+SCTAB XclImpTabInfo::GetScTabFromXclName( const String& rXclTabName ) const
+{
+ XclTabNameMap::const_iterator aIt = maTabNames.find( rXclTabName );
+ return (aIt != maTabNames.end()) ? aIt->second : SCTAB_INVALID;
+}
+
+// record creation order - TABID record ---------------------------------------
+
+void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ rStrm.EnableDecryption();
+ sal_Size nReadCount = rStrm.GetRecLeft() / 2;
+ DBG_ASSERT( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
+ maTabIdVec.clear();
+ maTabIdVec.reserve( nReadCount );
+ for( sal_Size nIndex = 0; rStrm.IsValid() && (nIndex < nReadCount); ++nIndex )
+ // zero index is not allowed in BIFF8, but it seems that it occurs in real life
+ maTabIdVec.push_back( rStrm.ReaduInt16() );
+ }
+}
+
+sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId ) const
+{
+ sal_uInt16 nReturn = 0;
+ for( ScfUInt16Vec::const_iterator aIt = maTabIdVec.begin(), aEnd = maTabIdVec.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nValue = *aIt;
+ if( nValue == nCreatedId )
+ return nReturn;
+ if( nValue <= nMaxTabId )
+ ++nReturn;
+ }
+ return 0;
+}
+
+// External names =============================================================
+
+XclImpExtName::MOper::MOper(XclImpStream& rStrm) :
+ mxCached(new ScMatrix(0,0))
+{
+ SCSIZE nLastCol = rStrm.ReaduInt8();
+ SCSIZE nLastRow = rStrm.ReaduInt16();
+ mxCached->Resize(nLastCol+1, nLastRow+1);
+ for (SCSIZE nRow = 0; nRow <= nLastRow; ++nRow)
+ {
+ for (SCSIZE nCol = 0; nCol <= nLastCol; ++nCol)
+ {
+ sal_uInt8 nOp;
+ rStrm >> nOp;
+ switch (nOp)
+ {
+ case 0x01:
+ {
+ double fVal = rStrm.ReadDouble();
+ mxCached->PutDouble(fVal, nCol, nRow);
+ }
+ break;
+ case 0x02:
+ {
+ OUString aStr = rStrm.ReadUniString();
+ mxCached->PutString(aStr, nCol, nRow);
+ }
+ break;
+ case 0x04:
+ {
+ bool bVal = rStrm.ReaduInt8();
+ mxCached->PutBoolean(bVal, nCol, nRow);
+ rStrm.Ignore(7);
+ }
+ break;
+ case 0x10:
+ {
+ sal_uInt8 nErr = rStrm.ReaduInt8();
+ // TODO: Map the error code from xls to calc.
+ mxCached->PutError(nErr, nCol, nRow);
+ rStrm.Ignore(7);
+ }
+ break;
+ default:
+ rStrm.Ignore(8);
+ }
+ }
+ }
+}
+
+const ScMatrix& XclImpExtName::MOper::GetCache() const
+{
+ return *mxCached;
+}
+
+XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, XclSupbookType eSubType, ExcelToSc* pFormulaConv ) :
+ mpMOper(NULL)
+{
+ sal_uInt16 nFlags;
+ sal_uInt8 nLen;
+
+ rStrm >> nFlags >> mnStorageId >> nLen ;
+ maName = rStrm.ReadUniString( nLen );
+ if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
+ {
+ if( eSubType == EXC_SBTYPE_ADDIN )
+ {
+ meType = xlExtAddIn;
+ maName = rStrm.GetRoot().GetScAddInName( maName );
+ }
+ else if ( (eSubType == EXC_SBTYPE_EUROTOOL) &&
+ maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
+ meType = xlExtEuroConvert;
+ else
+ {
+ meType = xlExtName;
+ ScfTools::ConvertToScDefinedName( maName );
+ }
+ }
+ else
+ {
+ meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE );
+ }
+
+ switch (meType)
+ {
+ case xlExtDDE:
+ if (rStrm.GetRecLeft() > 1)
+ mxDdeMatrix.reset(new XclImpCachedMatrix(rStrm));
+ break;
+ case xlExtName:
+ // TODO: For now, only global external names are supported. In future
+ // we should extend this to supporting per-sheet external names.
+ if (mnStorageId == 0)
+ {
+ if (pFormulaConv)
+ {
+ const ScTokenArray* pArray = NULL;
+ sal_uInt16 nFmlaLen;
+ rStrm >> nFmlaLen;
+ vector<String> aTabNames;
+ sal_uInt16 nCount = rSupbook.GetTabCount();
+ aTabNames.reserve(nCount);
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ aTabNames.push_back(rSupbook.GetTabName(i));
+
+ pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
+ if (pArray)
+ mxArray.reset(pArray->Clone());
+ }
+ }
+ break;
+ case xlExtOLE:
+ mpMOper = new MOper(rStrm);
+ break;
+ default:
+ ;
+ }
+}
+
+XclImpExtName::~XclImpExtName()
+{
+ delete mpMOper;
+}
+
+void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, const String& rTopic ) const
+{
+ ScMatrixRef xResults;
+ if( mxDdeMatrix.get() )
+ xResults = mxDdeMatrix->CreateScMatrix();
+ rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
+}
+
+void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
+{
+ if (!mxArray.get())
+ return;
+
+ ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
+ pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
+}
+
+namespace {
+
+/**
+ * Decompose the name into sheet name and range name. An OLE link name is
+ * always formatted like this [ !Sheet1!R1C1:R5C2 ] and it always uses R1C1
+ * notation.
+ */
+bool extractSheetAndRange(const OUString& rName, OUString& rSheet, OUString& rRange)
+{
+ sal_Int32 n = rName.getLength();
+ const sal_Unicode* p = rName.getStr();
+ OUStringBuffer aBuf;
+ bool bInSheet = true;
+ for (sal_Int32 i = 0; i < n; ++i, ++p)
+ {
+ if (i == 0)
+ {
+ // first character must be '!'.
+ if (*p != '!')
+ return false;
+ continue;
+ }
+
+ if (*p == '!')
+ {
+ // sheet name to range separator.
+ if (!bInSheet)
+ return false;
+ rSheet = aBuf.makeStringAndClear();
+ bInSheet = false;
+ continue;
+ }
+
+ aBuf.append(*p);
+ }
+
+ rRange = aBuf.makeStringAndClear();
+ return true;
+}
+
+}
+
+bool XclImpExtName::CreateOleData(ScDocument& rDoc, const OUString& rUrl,
+ sal_uInt16& rFileId, OUString& rTabName, ScRange& rRange) const
+{
+ if (!mpMOper)
+ return false;
+
+ OUString aSheet, aRangeStr;
+ if (!extractSheetAndRange(maName, aSheet, aRangeStr))
+ return false;
+
+ ScRange aRange;
+ sal_uInt16 nRes = aRange.ParseAny(aRangeStr, &rDoc, formula::FormulaGrammar::CONV_XL_R1C1);
+ if ((nRes & SCA_VALID) != SCA_VALID)
+ return false;
+
+ if (aRange.aStart.Tab() != aRange.aEnd.Tab())
+ // We don't support multi-sheet range for this.
+ return false;
+
+ const ScMatrix& rCache = mpMOper->GetCache();
+ SCSIZE nC, nR;
+ rCache.GetDimensions(nC, nR);
+ if (!nC || !nR)
+ // cache matrix is empty.
+ return false;
+
+ ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl);
+ ScExternalRefCache::TableTypeRef xTab = pRefMgr->getCacheTable(nFileId, aSheet, true, NULL);
+ if (!xTab)
+ // cache table creation failed.
+ return false;
+
+ xTab->setWholeTableCached();
+ for (SCSIZE i = 0; i < nR; ++i)
+ {
+ for (SCSIZE j = 0; j < nC; ++j)
+ {
+ SCCOL nCol = aRange.aStart.Col() + j;
+ SCROW nRow = aRange.aStart.Row() + i;
+
+ ScMatrixValue aVal = rCache.Get(j, i);
+ switch (aVal.nType)
+ {
+ case SC_MATVAL_BOOLEAN:
+ {
+ bool b = aVal.GetBoolean();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ case SC_MATVAL_VALUE:
+ {
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(aVal.fVal));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ case SC_MATVAL_STRING:
+ {
+ const String& rStr = aVal.GetString();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
+ xTab->setCell(nCol, nRow, pToken, 0, false);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ rFileId = nFileId;
+ rTabName = aSheet;
+ rRange = aRange;
+ return true;
+}
+
+bool XclImpExtName::HasFormulaTokens() const
+{
+ return (mxArray.get() != NULL);
+}
+
+// Cached external cells ======================================================
+
+XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
+ XclImpCachedValue( rStrm ),
+ maXclPos( rXclPos )
+{
+}
+
+const XclAddress& XclImpCrn::GetAddress() const
+{
+ return maXclPos;
+}
+
+// Sheet in an external document ==============================================
+
+XclImpSupbookTab::XclImpSupbookTab( const String& rTabName ) :
+ maTabName( rTabName ),
+ mnScTab( SCTAB_INVALID )
+{
+}
+
+XclImpSupbookTab::~XclImpSupbookTab()
+{
+}
+
+void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
+{
+ XclImpCrnRef crnRef( new XclImpCrn(rStrm, rXclPos) );
+ maCrnList.push_back( crnRef );
+}
+
+void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
+{
+ if (maCrnList.empty())
+ return;
+
+ for (XclImpCrnList::iterator itCrnRef = maCrnList.begin(); itCrnRef != maCrnList.end(); ++itCrnRef)
+ {
+ const XclImpCrn* const pCrn = itCrnRef->get();
+ const XclAddress& rAddr = pCrn->GetAddress();
+ switch (pCrn->GetType())
+ {
+ case EXC_CACHEDVAL_BOOL:
+ {
+ bool b = pCrn->GetBool();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
+ }
+ break;
+ case EXC_CACHEDVAL_DOUBLE:
+ {
+ double f = pCrn->GetValue();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(f));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
+ }
+ break;
+ case EXC_CACHEDVAL_ERROR:
+ {
+ double fError = XclTools::ErrorToDouble( pCrn->GetXclError() );
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(fError));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
+ }
+ break;
+ case EXC_CACHEDVAL_STRING:
+ {
+ const String& rStr = pCrn->GetString();
+ ScExternalRefCache::TokenRef pToken(new formula::FormulaStringToken(rStr));
+ pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken, 0, false);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+// External document (SUPBOOK) ================================================
+
+XclImpSupbook::XclImpSupbook( XclImpStream& rStrm ) :
+ XclImpRoot( rStrm.GetRoot() ),
+ meType( EXC_SBTYPE_UNKNOWN ),
+ mnSBTab( EXC_TAB_DELETED )
+{
+ sal_uInt16 nSBTabCnt;
+ rStrm >> nSBTabCnt;
+
+ if( rStrm.GetRecLeft() == 2 )
+ {
+ switch( rStrm.ReaduInt16() )
+ {
+ case EXC_SUPB_SELF: meType = EXC_SBTYPE_SELF; break;
+ case EXC_SUPB_ADDIN: meType = EXC_SBTYPE_ADDIN; break;
+ default: DBG_ERRORFILE( "XclImpSupbook::XclImpSupbook - unknown special SUPBOOK type" );
+ }
+ return;
+ }
+
+ String aEncUrl( rStrm.ReadUniString() );
+ bool bSelf = false;
+ XclImpUrlHelper::DecodeUrl( maXclUrl, bSelf, GetRoot(), aEncUrl );
+
+ if( maXclUrl.EqualsIgnoreCaseAscii( "\010EUROTOOL.XLA" ) )
+ {
+ meType = EXC_SBTYPE_EUROTOOL;
+ maSupbTabList.push_back( new XclImpSupbookTab( maXclUrl ) );
+ }
+ else if( nSBTabCnt )
+ {
+ meType = EXC_SBTYPE_EXTERN;
+ for( sal_uInt16 nSBTab = 0; nSBTab < nSBTabCnt; ++nSBTab )
+ {
+ String aTabName( rStrm.ReadUniString() );
+ maSupbTabList.push_back( new XclImpSupbookTab( aTabName ) );
+ }
+ }
+ else
+ {
+ meType = EXC_SBTYPE_SPECIAL;
+ // create dummy list entry
+ maSupbTabList.push_back( new XclImpSupbookTab( maXclUrl ) );
+ }
+}
+
+void XclImpSupbook::ReadXct( XclImpStream& rStrm )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> mnSBTab;
+}
+
+void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
+{
+ if (mnSBTab >= maSupbTabList.size())
+ return;
+ XclImpSupbookTab& rSbTab = maSupbTabList[mnSBTab];
+ sal_uInt8 nXclColLast, nXclColFirst;
+ sal_uInt16 nXclRow;
+ rStrm >> nXclColLast >> nXclColFirst >> nXclRow;
+
+ for( sal_uInt8 nXclCol = nXclColFirst; (nXclCol <= nXclColLast) && (rStrm.GetRecLeft() > 1); ++nXclCol )
+ rSbTab.ReadCrn( rStrm, XclAddress( nXclCol, nXclRow ) );
+}
+
+void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ maExtNameList.push_back( new XclImpExtName( *this, rStrm, meType, pFormulaConv ) );
+}
+
+const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
+{
+ DBG_ASSERT( nXclIndex > 0, "XclImpSupbook::GetExternName - index must be >0" );
+ if (meType == EXC_SBTYPE_SELF || nXclIndex > maExtNameList.size())
+ return NULL;
+ return &maExtNameList[nXclIndex-1];
+}
+
+bool XclImpSupbook::GetLinkData( String& rApplic, String& rTopic ) const
+{
+ return (meType == EXC_SBTYPE_SPECIAL) && XclImpUrlHelper::DecodeLink( rApplic, rTopic, maXclUrl );
+}
+
+const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
+{
+ DBG_ASSERT( nXclNameIdx > 0, "XclImpSupbook::GetMacroName - index must be >0" );
+ const XclImpName* pName = (meType == EXC_SBTYPE_SELF) ? GetNameManager().GetName( nXclNameIdx ) : 0;
+ return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
+}
+
+const String& XclImpSupbook::GetTabName( sal_uInt16 nXtiTab ) const
+{
+ if (nXtiTab >= maSupbTabList.size())
+ return EMPTY_STRING;
+ return maSupbTabList[nXtiTab].GetTabName();
+}
+
+sal_uInt16 XclImpSupbook::GetTabCount() const
+{
+ return ulimit_cast<sal_uInt16>(maSupbTabList.size());
+}
+
+void XclImpSupbook::LoadCachedValues()
+{
+ if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
+ return;
+
+ String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
+
+ ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
+ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
+
+ for (XclImpSupbookTabList::iterator itTab = maSupbTabList.begin(); itTab != maSupbTabList.end(); ++itTab)
+ {
+ const String& rTabName = itTab->GetTabName();
+ ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
+ itTab->LoadCachedValues(pCacheTable);
+ pCacheTable->setWholeTableCached();
+ }
+}
+
+// Import link manager ========================================================
+
+XclImpLinkManagerImpl::XclImpLinkManagerImpl( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mbCreated( false )
+{
+}
+
+void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
+{
+ sal_uInt16 nXtiCount;
+ rStrm >> nXtiCount;
+ DBG_ASSERT( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" );
+ nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 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. */
+ XclImpXtiVector aNewEntries( nXtiCount );
+ for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt )
+ rStrm >> *aIt;
+ maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() );
+
+ LoadCachedValues();
+}
+
+void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
+{
+ maSupbookList.push_back( new XclImpSupbook( rStrm ) );
+}
+
+void XclImpLinkManagerImpl::ReadXct( XclImpStream& rStrm )
+{
+ if( !maSupbookList.empty() )
+ maSupbookList.back().ReadXct( rStrm );
+}
+
+void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
+{
+ if( !maSupbookList.empty() )
+ maSupbookList.back().ReadCrn( rStrm );
+}
+
+void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ if( !maSupbookList.empty() )
+ maSupbookList.back().ReadExternname( rStrm, pFormulaConv );
+}
+
+bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook && (pSupbook->GetType() == EXC_SBTYPE_SELF);
+}
+
+bool XclImpLinkManagerImpl::GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
+{
+ if( const XclImpXti* pXti = GetXti( nXtiIndex ) )
+ {
+ if (!maSupbookList.empty() && (pXti->mnSupbook < maSupbookList.size()) )
+ {
+ rnFirstScTab = pXti->mnSBTabFirst;
+ rnLastScTab = pXti->mnSBTabLast;
+ return true;
+ }
+ }
+ return false;
+}
+
+const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
+}
+
+const String* XclImpLinkManagerImpl::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* p = GetSupbook( nXtiIndex );
+ if (!p)
+ return NULL;
+ return &p->GetXclUrl();
+}
+
+const String& XclImpLinkManagerImpl::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
+{
+ const XclImpSupbook* p = GetSupbook(nXti);
+ return p ? p->GetTabName(nXtiTab) : EMPTY_STRING;
+}
+
+bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
+ return pSupbook && pSupbook->GetLinkData( rApplic, rTopic );
+}
+
+const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
+{
+ const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
+ return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
+}
+
+const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
+{
+ return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
+}
+
+const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
+{
+ if ( maSupbookList.empty() )
+ return NULL;
+ const XclImpXti* pXti = GetXti( nXtiIndex );
+ if (!pXti || pXti->mnSupbook >= maSupbookList.size())
+ return NULL;
+ return &(maSupbookList.at( pXti->mnSupbook ));
+}
+
+void XclImpLinkManagerImpl::LoadCachedValues()
+{
+ // Read all CRN records which can be accessed via XclImpSupbook, and store
+ // the cached values to the external reference manager.
+ for (XclImpSupbookList::iterator itSupbook = maSupbookList.begin(); itSupbook != maSupbookList.end(); ++itSupbook)
+ itSupbook->LoadCachedValues();
+}
+
+// ============================================================================
+
+XclImpLinkManager::XclImpLinkManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mxImpl( new XclImpLinkManagerImpl( rRoot ) )
+{
+}
+
+XclImpLinkManager::~XclImpLinkManager()
+{
+}
+
+void XclImpLinkManager::ReadExternsheet( XclImpStream& rStrm )
+{
+ mxImpl->ReadExternsheet( rStrm );
+}
+
+void XclImpLinkManager::ReadSupbook( XclImpStream& rStrm )
+{
+ mxImpl->ReadSupbook( rStrm );
+}
+
+void XclImpLinkManager::ReadXct( XclImpStream& rStrm )
+{
+ mxImpl->ReadXct( rStrm );
+}
+
+void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
+{
+ mxImpl->ReadCrn( rStrm );
+}
+
+void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+{
+ mxImpl->ReadExternname( rStrm, pFormulaConv );
+}
+
+bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->IsSelfRef( nXtiIndex );
+}
+
+bool XclImpLinkManager::GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetScTabRange( rnFirstScTab, rnLastScTab, nXtiIndex );
+}
+
+const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const
+{
+ return mxImpl->GetExternName( nXtiIndex, nExtName );
+}
+
+const String* XclImpLinkManager::GetSupbookUrl( sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetSupbookUrl(nXtiIndex);
+}
+
+const String& XclImpLinkManager::GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const
+{
+ return mxImpl->GetSupbookTabName(nXti, nXtiTab);
+}
+
+bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
+{
+ return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
+}
+
+const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const
+{
+ return mxImpl->GetMacroName( nExtSheet, nExtName );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx
new file mode 100644
index 000000000000..8a80f5217dc1
--- /dev/null
+++ b/sc/source/filter/excel/xiname.cxx
@@ -0,0 +1,279 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiname.hxx"
+#include "rangenam.hxx"
+#include "xistream.hxx"
+
+// for formula compiler
+#include "excform.hxx"
+// for filter manager
+#include "excimp8.hxx"
+#include "scextopt.hxx"
+#include "document.hxx"
+// ============================================================================
+// *** Implementation ***
+// ============================================================================
+
+XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) :
+ XclImpRoot( rStrm.GetRoot() ),
+ mpScData( 0 ),
+ mcBuiltIn( EXC_BUILTIN_UNKNOWN ),
+ mnScTab( SCTAB_MAX ),
+ mbFunction( false ),
+ mbVBName( false )
+{
+ ExcelToSc& rFmlaConv = GetOldFmlaConverter();
+
+ // 1) *** read data from stream *** ---------------------------------------
+
+ sal_uInt16 nFlags = 0, nFmlaSize = 0, nExtSheet = EXC_NAME_GLOBAL, nXclTab = EXC_NAME_GLOBAL;
+ sal_uInt8 nNameLen = 0, nShortCut;
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ {
+ sal_uInt8 nFlagsBiff2;
+ rStrm >> nFlagsBiff2;
+ rStrm.Ignore( 1 );
+ rStrm >> nShortCut >> nNameLen;
+ nFmlaSize = rStrm.ReaduInt8();
+ ::set_flag( nFlags, EXC_NAME_FUNC, ::get_flag( nFlagsBiff2, EXC_NAME2_FUNC ) );
+ }
+ break;
+
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ {
+ rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize;
+ }
+ break;
+
+ case EXC_BIFF5:
+ case EXC_BIFF8:
+ {
+ rStrm >> nFlags >> nShortCut >> nNameLen >> nFmlaSize >> nExtSheet >> nXclTab;
+ rStrm.Ignore( 4 );
+ }
+ break;
+
+ default: DBG_ERROR_BIFF();
+ }
+
+ if( GetBiff() <= EXC_BIFF5 )
+ maXclName = rStrm.ReadRawByteString( nNameLen );
+ else
+ maXclName = rStrm.ReadUniString( nNameLen );
+
+ // 2) *** convert sheet index and name *** --------------------------------
+
+ // functions and VBA
+ mbFunction = ::get_flag( nFlags, EXC_NAME_FUNC );
+ mbVBName = ::get_flag( nFlags, EXC_NAME_VB );
+
+ // get built-in name, or convert characters invalid in Calc
+ bool bBuiltIn = ::get_flag( nFlags, EXC_NAME_BUILTIN );
+
+ // special case for BIFF5 filter range - name appears as plain text without built-in flag
+ if( (GetBiff() == EXC_BIFF5) && (maXclName == XclTools::GetXclBuiltInDefName( EXC_BUILTIN_FILTERDATABASE )) )
+ {
+ bBuiltIn = true;
+ maXclName.Assign( EXC_BUILTIN_FILTERDATABASE );
+ }
+
+ // convert Excel name to Calc name
+ if( mbVBName )
+ {
+ // VB macro name
+ maScName = maXclName;
+ }
+ else if( bBuiltIn )
+ {
+ // built-in name
+ if( maXclName.Len() )
+ mcBuiltIn = maXclName.GetChar( 0 );
+ if( mcBuiltIn == '?' ) // NUL character is imported as '?'
+ mcBuiltIn = '\0';
+ maScName = XclTools::GetBuiltInDefName( mcBuiltIn );
+ }
+ else
+ {
+ // any other name
+ maScName = maXclName;
+ ScfTools::ConvertToScDefinedName( maScName );
+ }
+ rtl::OUString aRealOrigName = maScName;
+
+ // add index for local names
+ if( nXclTab != EXC_NAME_GLOBAL )
+ {
+ sal_uInt16 nUsedTab = (GetBiff() == EXC_BIFF8) ? nXclTab : nExtSheet;
+ // do not rename sheet-local names by default, this breaks VBA scripts
+// maScName.Append( '_' ).Append( String::CreateFromInt32( nUsedTab ) );
+ // TODO: may not work for BIFF5, handle skipped sheets (all BIFF)
+ mnScTab = static_cast< SCTAB >( nUsedTab - 1 );
+ }
+
+ // 3) *** convert the name definition formula *** -------------------------
+
+ rFmlaConv.Reset();
+ const ScTokenArray* pTokArr = 0; // pointer to token array, owned by rFmlaConv
+ RangeType nNameType = RT_NAME;
+
+ if( ::get_flag( nFlags, EXC_NAME_BIG ) )
+ {
+ // special, unsupported name
+ rFmlaConv.GetDummy( pTokArr );
+ }
+ else if( bBuiltIn )
+ {
+ SCsTAB const nLocalTab = (nXclTab == EXC_NAME_GLOBAL) ? SCTAB_MAX : (nXclTab - 1);
+
+ // --- print ranges or title ranges ---
+ rStrm.PushPosition();
+ switch( mcBuiltIn )
+ {
+ case EXC_BUILTIN_PRINTAREA:
+ if( rFmlaConv.Convert( GetPrintAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
+ nNameType |= RT_PRINTAREA;
+ break;
+ case EXC_BUILTIN_PRINTTITLES:
+ if( rFmlaConv.Convert( GetTitleAreaBuffer(), rStrm, nFmlaSize, nLocalTab, FT_RangeName ) == ConvOK )
+ nNameType |= RT_COLHEADER | RT_ROWHEADER;
+ break;
+ }
+ rStrm.PopPosition();
+
+ // --- name formula ---
+ // JEG : double check this. It is clearly false for normal names
+ // but some of the builtins (sheettitle?) might be able to handle arrays
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, false, FT_RangeName );
+
+ // --- auto or advanced filter ---
+ if( (GetBiff() == EXC_BIFF8) && pTokArr && bBuiltIn )
+ {
+ ScRange aRange;
+ if( pTokArr->IsReference( aRange ) )
+ {
+ switch( mcBuiltIn )
+ {
+ case EXC_BUILTIN_FILTERDATABASE:
+ GetFilterManager().Insert( &GetOldRoot(), aRange);
+ break;
+ case EXC_BUILTIN_CRITERIA:
+ GetFilterManager().AddAdvancedRange( aRange );
+ nNameType |= RT_CRITERIA;
+ break;
+ case EXC_BUILTIN_EXTRACT:
+ if( pTokArr->IsValidReference( aRange ) )
+ GetFilterManager().AddExtractPos( aRange );
+ break;
+ }
+ }
+ }
+ }
+ else if( nFmlaSize > 0 )
+ {
+ // regular defined name
+ rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize, true, FT_RangeName );
+ }
+
+ // 4) *** create a defined name in the Calc document *** ------------------
+
+ // do not ignore hidden names (may be regular names created by VBA scripts)
+ if( pTokArr /*&& (bBuiltIn || !::get_flag( nFlags, EXC_NAME_HIDDEN ))*/ && !mbFunction && !mbVBName )
+ {
+ // create the Calc name data
+ ScRangeData* pData = new ScRangeData( GetDocPtr(), maScName, *pTokArr, ScAddress(), nNameType );
+ pData->GuessPosition(); // calculate base position for relative refs
+ pData->SetIndex( nXclNameIdx ); // used as unique identifier in formulas
+ if (nXclTab == EXC_NAME_GLOBAL)
+ GetDoc().GetRangeName()->insert(pData);
+ else
+ {
+ ScRangeName* pLocalNames = GetDoc().GetRangeName(mnScTab);
+ if (pLocalNames)
+ pLocalNames->insert(pData);
+
+ if (GetBiff() == EXC_BIFF8)
+ {
+ ScRange aRange;
+ // discard deleted ranges ( for the moment at least )
+ if ( pData->IsValidReference( aRange ) )
+ {
+ GetExtDocOptions().GetOrCreateTabSettings( nXclTab );
+ }
+ }
+ }
+ mpScData = pData; // cache for later use
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpNameManager::ReadName( XclImpStream& rStrm )
+{
+ sal_uLong nCount = maNameList.size();
+ if( nCount < 0xFFFF )
+ maNameList.push_back( new XclImpName( rStrm, static_cast< sal_uInt16 >( nCount + 1 ) ) );
+}
+
+const XclImpName* XclImpNameManager::FindName( const String& rXclName, SCTAB nScTab ) const
+{
+ const XclImpName* pGlobalName = 0; // a found global name
+ const XclImpName* pLocalName = 0; // a found local name
+ for( XclImpNameList::const_iterator itName = maNameList.begin(); itName != maNameList.end() && !pLocalName; ++itName )
+ {
+ if( itName->GetXclName() == rXclName )
+ {
+ if( itName->GetScTab() == nScTab )
+ pLocalName = &(*itName);
+ else if( itName->IsGlobal() )
+ pGlobalName = &(*itName);
+ }
+ }
+ return pLocalName ? pLocalName : pGlobalName;
+}
+
+const XclImpName* XclImpNameManager::GetName( sal_uInt16 nXclNameIdx ) const
+{
+ DBG_ASSERT( nXclNameIdx > 0, "XclImpNameManager::GetName - index must be >0" );
+ return ( nXclNameIdx > maNameList.size() ) ? NULL : &(maNameList.at( nXclNameIdx - 1 ));
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xipage.cxx b/sc/source/filter/excel/xipage.cxx
new file mode 100644
index 000000000000..f40743c52146
--- /dev/null
+++ b/sc/source/filter/excel/xipage.cxx
@@ -0,0 +1,392 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xipage.hxx"
+#include <svl/itemset.hxx>
+#include <vcl/graph.hxx>
+#include "scitems.hxx"
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include "document.hxx"
+#include "stlsheet.hxx"
+#include "attrib.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xiescher.hxx"
+
+// Page settings ==============================================================
+
+XclImpPageSettings::XclImpPageSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ Initialize();
+}
+
+void XclImpPageSettings::Initialize()
+{
+ maData.SetDefaults();
+ mbValidPaper = false;
+}
+
+void XclImpPageSettings::ReadSetup( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF4 );
+ if( GetBiff() < EXC_BIFF4 )
+ return;
+
+ // BIFF4 - BIFF8
+ sal_uInt16 nFlags;
+ rStrm >> maData.mnPaperSize >> maData.mnScaling >> maData.mnStartPage
+ >> maData.mnFitToWidth >> maData.mnFitToHeight >> nFlags;
+
+ mbValidPaper = maData.mbValid = !::get_flag( nFlags, EXC_SETUP_INVALID );
+ maData.mbPrintInRows = ::get_flag( nFlags, EXC_SETUP_INROWS );
+ maData.mbPortrait = ::get_flag( nFlags, EXC_SETUP_PORTRAIT );
+ maData.mbBlackWhite = ::get_flag( nFlags, EXC_SETUP_BLACKWHITE );
+ maData.mbManualStart = true;
+
+ // new in BIFF5 - BIFF8
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ rStrm >> maData.mnHorPrintRes >> maData.mnVerPrintRes
+ >> maData.mfHeaderMargin >> maData.mfFooterMargin >> maData.mnCopies;
+
+ maData.mbDraftQuality = ::get_flag( nFlags, EXC_SETUP_DRAFT );
+ maData.mbPrintNotes = ::get_flag( nFlags, EXC_SETUP_PRINTNOTES );
+ maData.mbManualStart = ::get_flag( nFlags, EXC_SETUP_STARTPAGE );
+ }
+}
+
+void XclImpPageSettings::ReadMargin( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_LEFTMARGIN: rStrm >> maData.mfLeftMargin; break;
+ case EXC_ID_RIGHTMARGIN: rStrm >> maData.mfRightMargin; break;
+ case EXC_ID_TOPMARGIN: rStrm >> maData.mfTopMargin; break;
+ case EXC_ID_BOTTOMMARGIN: rStrm >> maData.mfBottomMargin; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadMargin - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadCenter( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 ); // read it anyway
+ bool bCenter = (rStrm.ReaduInt16() != 0);
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HCENTER: maData.mbHorCenter = bCenter; break;
+ case EXC_ID_VCENTER: maData.mbVerCenter = bCenter; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadCenter - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadHeaderFooter( XclImpStream& rStrm )
+{
+ String aString;
+ if( rStrm.GetRecLeft() )
+ aString = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
+
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HEADER: maData.maHeader = aString; break;
+ case EXC_ID_FOOTER: maData.maFooter = aString; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadHeaderFooter - unknown record" );
+ }
+}
+
+void XclImpPageSettings::ReadPageBreaks( XclImpStream& rStrm )
+{
+ ScfUInt16Vec* pVec = 0;
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_HORPAGEBREAKS: pVec = &maData.maHorPageBreaks; break;
+ case EXC_ID_VERPAGEBREAKS: pVec = &maData.maVerPageBreaks; break;
+ default: DBG_ERRORFILE( "XclImpPageSettings::ReadPageBreaks - unknown record" );
+ }
+
+ if( pVec )
+ {
+ bool bIgnore = GetBiff() == EXC_BIFF8; // ignore start/end columns or rows in BIFF8
+
+ sal_uInt16 nCount, nBreak;
+ rStrm >> nCount;
+ pVec->clear();
+ pVec->reserve( nCount );
+
+ while( nCount-- )
+ {
+ rStrm >> nBreak;
+ if( nBreak )
+ pVec->push_back( nBreak );
+ if( bIgnore )
+ rStrm.Ignore( 4 );
+ }
+ }
+}
+
+void XclImpPageSettings::ReadPrintHeaders( XclImpStream& rStrm )
+{
+ maData.mbPrintHeadings = (rStrm.ReaduInt16() != 0);
+}
+
+void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm )
+{
+ maData.mbPrintGrid = (rStrm.ReaduInt16() != 0);
+}
+
+void XclImpPageSettings::ReadImgData( XclImpStream& rStrm )
+{
+ Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
+ if( aGraphic.GetType() != GRAPHIC_NONE )
+ maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) );
+}
+
+void XclImpPageSettings::SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait )
+{
+ maData.mnPaperSize = nXclPaperSize;
+ maData.mbPortrait = bPortrait;
+ mbValidPaper = true;
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+void lclPutMarginItem( SfxItemSet& rItemSet, sal_uInt16 nRecId, double fMarginInch )
+{
+ sal_uInt16 nMarginTwips = XclTools::GetTwipsFromInch( fMarginInch );
+ switch( nRecId )
+ {
+ case EXC_ID_TOPMARGIN:
+ case EXC_ID_BOTTOMMARGIN:
+ {
+ SvxULSpaceItem aItem( GETITEM( rItemSet, SvxULSpaceItem, ATTR_ULSPACE ) );
+ if( nRecId == EXC_ID_TOPMARGIN )
+ aItem.SetUpperValue( nMarginTwips );
+ else
+ aItem.SetLowerValue( nMarginTwips );
+ rItemSet.Put( aItem );
+ }
+ break;
+ case EXC_ID_LEFTMARGIN:
+ case EXC_ID_RIGHTMARGIN:
+ {
+ SvxLRSpaceItem aItem( GETITEM( rItemSet, SvxLRSpaceItem, ATTR_LRSPACE ) );
+ if( nRecId == EXC_ID_LEFTMARGIN )
+ aItem.SetLeftValue( nMarginTwips );
+ else
+ aItem.SetRightValue( nMarginTwips );
+ rItemSet.Put( aItem );
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclImpPageSettings::SetMarginItem - unknown record id" );
+ }
+}
+
+} // namespace
+
+void XclImpPageSettings::Finalize()
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // *** create page style sheet ***
+
+ String aStyleName( RTL_CONSTASCII_USTRINGPARAM( "PageStyle_" ) );
+ String aTableName;
+ if( GetDoc().GetName( nScTab, aTableName ) )
+ aStyleName.Append( aTableName );
+ else
+ aStyleName.Append( String::CreateFromInt32( nScTab + 1 ) );
+
+ ScStyleSheet& rStyleSheet = ScfTools::MakePageStyleSheet( GetStyleSheetPool(), aStyleName, false );
+ SfxItemSet& rItemSet = rStyleSheet.GetItemSet();
+
+ // *** page settings ***
+
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_TOPDOWN, !maData.mbPrintInRows ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HORCENTER, maData.mbHorCenter ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_VERCENTER, maData.mbVerCenter ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_HEADERS, maData.mbPrintHeadings ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_GRID, maData.mbPrintGrid ), true );
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_PAGE_NOTES, maData.mbPrintNotes ), true );
+
+ sal_uInt16 nStartPage = maData.mbManualStart ? maData.mnStartPage : 0;
+ ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, nStartPage ), true );
+
+ if( maData.mxBrushItem.get() )
+ rItemSet.Put( *maData.mxBrushItem );
+
+ if( mbValidPaper )
+ {
+ SvxPageItem aPageItem( GETITEM( rItemSet, SvxPageItem, ATTR_PAGE ) );
+ aPageItem.SetLandscape( !maData.mbPortrait );
+ rItemSet.Put( aPageItem );
+ ScfTools::PutItem( rItemSet, SvxSizeItem( ATTR_PAGE_SIZE, maData.GetScPaperSize() ), true );
+ }
+
+ if( maData.mbFitToPages )
+ rItemSet.Put( ScPageScaleToItem( maData.mnFitToWidth, maData.mnFitToHeight ) );
+ else if( maData.mbValid )
+ rItemSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, maData.mnScaling ) );
+
+ // *** margin preparations ***
+
+ double fLeftMargin = maData.mfLeftMargin;
+ double fRightMargin = maData.mfRightMargin;
+ double fTopMargin = maData.mfTopMargin;
+ double fBottomMargin = maData.mfBottomMargin;
+ // distances between header/footer and page area
+ double fHeaderHeight = 0.0;
+ double fHeaderDist = 0.0;
+ double fFooterHeight = 0.0;
+ double fFooterDist = 0.0;
+ // in Calc, "header/footer left/right margin" is X distance between header/footer and page margin
+ double fHdrLeftMargin = maData.mfHdrLeftMargin - maData.mfLeftMargin;
+ double fHdrRightMargin = maData.mfHdrRightMargin - maData.mfRightMargin;
+ double fFtrLeftMargin = maData.mfFtrLeftMargin - maData.mfLeftMargin;
+ double fFtrRightMargin = maData.mfFtrRightMargin - maData.mfRightMargin;
+
+ // *** header and footer ***
+
+ XclImpHFConverter aHFConv( GetRoot() );
+
+ // header
+ bool bHasHeader = (maData.maHeader.Len() != 0);
+ SvxSetItem aHdrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_HEADERSET ) );
+ SfxItemSet& rHdrItemSet = aHdrSetItem.GetItemSet();
+ rHdrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasHeader ) );
+ if( bHasHeader )
+ {
+ aHFConv.ParseString( maData.maHeader );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERLEFT );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_HEADERRIGHT );
+ // #i23296# In Calc, "top margin" is distance to header
+ fTopMargin = maData.mfHeaderMargin;
+ // Calc uses distance between header and sheet data area
+ fHeaderHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
+ fHeaderDist = maData.mfTopMargin - maData.mfHeaderMargin - fHeaderHeight;
+ }
+ if( fHeaderDist < 0.0 )
+ {
+ /* #i23296# Header overlays sheet data:
+ -> set fixed header height to get correct sheet data position. */
+ ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
+ // shrink header height
+ long nHdrHeight = XclTools::GetTwipsFromInch( fHeaderHeight + fHeaderDist );
+ ScfTools::PutItem( rHdrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nHdrHeight ) ), true );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, 0.0 );
+ }
+ else
+ {
+ // use dynamic header height
+ ScfTools::PutItem( rHdrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_BOTTOMMARGIN, fHeaderDist );
+ }
+ lclPutMarginItem( rHdrItemSet, EXC_ID_LEFTMARGIN, fHdrLeftMargin );
+ lclPutMarginItem( rHdrItemSet, EXC_ID_RIGHTMARGIN, fHdrRightMargin );
+ rItemSet.Put( aHdrSetItem );
+
+ // footer
+ bool bHasFooter = (maData.maFooter.Len() != 0);
+ SvxSetItem aFtrSetItem( GETITEM( rItemSet, SvxSetItem, ATTR_PAGE_FOOTERSET ) );
+ SfxItemSet& rFtrItemSet = aFtrSetItem.GetItemSet();
+ rFtrItemSet.Put( SfxBoolItem( ATTR_PAGE_ON, bHasFooter ) );
+ if( bHasFooter )
+ {
+ aHFConv.ParseString( maData.maFooter );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERLEFT );
+ aHFConv.FillToItemSet( rItemSet, ATTR_PAGE_FOOTERRIGHT );
+ // #i23296# In Calc, "bottom margin" is distance to footer
+ fBottomMargin = maData.mfFooterMargin;
+ // Calc uses distance between footer and sheet data area
+ fFooterHeight = XclTools::GetInchFromTwips( aHFConv.GetTotalHeight() );
+ fFooterDist = maData.mfBottomMargin - maData.mfFooterMargin - fFooterHeight;
+ }
+ if( fFooterDist < 0.0 )
+ {
+ /* #i23296# Footer overlays sheet data:
+ -> set fixed footer height to get correct sheet data end position. */
+ ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, false ), true );
+ // shrink footer height
+ long nFtrHeight = XclTools::GetTwipsFromInch( fFooterHeight + fFooterDist );
+ ScfTools::PutItem( rFtrItemSet, SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, nFtrHeight ) ), true );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, 0.0 );
+ }
+ else
+ {
+ // use dynamic footer height
+ ScfTools::PutItem( rFtrItemSet, SfxBoolItem( ATTR_PAGE_DYNAMIC, true ), true );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_TOPMARGIN, fFooterDist );
+ }
+ lclPutMarginItem( rFtrItemSet, EXC_ID_LEFTMARGIN, fFtrLeftMargin );
+ lclPutMarginItem( rFtrItemSet, EXC_ID_RIGHTMARGIN, fFtrRightMargin );
+ rItemSet.Put( aFtrSetItem );
+
+ // *** set final margins ***
+
+ lclPutMarginItem( rItemSet, EXC_ID_LEFTMARGIN, fLeftMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_RIGHTMARGIN, fRightMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_TOPMARGIN, fTopMargin );
+ lclPutMarginItem( rItemSet, EXC_ID_BOTTOMMARGIN, fBottomMargin );
+
+ // *** put style sheet into document ***
+
+ rDoc.SetPageStyle( nScTab, rStyleSheet.GetName() );
+
+ // *** page breaks ***
+
+ ScfUInt16Vec::const_iterator aIt, aEnd;
+
+ for( aIt = maData.maHorPageBreaks.begin(), aEnd = maData.maHorPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ SCROW nScRow = static_cast< SCROW >( *aIt );
+ if( nScRow <= MAXROW )
+ rDoc.SetRowBreak(nScRow, nScTab, false, true);
+ }
+
+ for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt )
+ {
+ SCCOL nScCol = static_cast< SCCOL >( *aIt );
+ if( nScCol <= MAXCOL )
+ rDoc.SetColBreak(nScCol, nScTab, false, true);
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
new file mode 100644
index 000000000000..a26b132f198d
--- /dev/null
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -0,0 +1,1678 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xipivot.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+
+#include <tools/datetime.hxx>
+#include <svl/zformat.hxx>
+#include <svl/intitem.hxx>
+
+#include "document.hxx"
+#include "cell.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dpoutputgeometry.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiescher.hxx"
+
+//! TODO ExcelToSc usage
+#include "excform.hxx"
+#include "xltable.hxx"
+
+#include <vector>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
+using ::com::sun::star::sheet::DataPilotFieldSortInfo;
+using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
+using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::std::vector;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+XclImpPCItem::XclImpPCItem( XclImpStream& rStrm )
+{
+ switch( rStrm.GetRecId() )
+ {
+ case EXC_ID_SXDOUBLE: ReadSxdouble( rStrm ); break;
+ case EXC_ID_SXBOOLEAN: ReadSxboolean( rStrm ); break;
+ case EXC_ID_SXERROR: ReadSxerror( rStrm ); break;
+ case EXC_ID_SXINTEGER: ReadSxinteger( rStrm ); break;
+ case EXC_ID_SXSTRING: ReadSxstring( rStrm ); break;
+ case EXC_ID_SXDATETIME: ReadSxdatetime( rStrm ); break;
+ case EXC_ID_SXEMPTY: ReadSxempty( rStrm ); break;
+ default: DBG_ERRORFILE( "XclImpPCItem::XclImpPCItem - unknown record id" );
+ }
+}
+
+namespace {
+
+void lclSetValue( const XclImpRoot& rRoot, const ScAddress& rScPos, double fValue, short nFormatType )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), fValue );
+ sal_uInt32 nScNumFmt = rRoot.GetFormatter().GetStandardFormat( nFormatType, rRoot.GetDocLanguage() );
+ rDoc.ApplyAttr( rScPos.Col(), rScPos.Row(), rScPos.Tab(), SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ) );
+}
+
+} // namespace
+
+void XclImpPCItem::WriteToSource( const XclImpRoot& rRoot, const ScAddress& rScPos ) const
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ if( const String* pText = GetText() )
+ rDoc.SetString( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pText );
+ else if( const double* pfValue = GetDouble() )
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pfValue );
+ else if( const sal_Int16* pnValue = GetInteger() )
+ rDoc.SetValue( rScPos.Col(), rScPos.Row(), rScPos.Tab(), *pnValue );
+ else if( const bool* pbValue = GetBool() )
+ lclSetValue( rRoot, rScPos, *pbValue ? 1.0 : 0.0, NUMBERFORMAT_LOGICAL );
+ else if( const DateTime* pDateTime = GetDateTime() )
+ {
+ // set number format date, time, or date/time, depending on the value
+ double fValue = rRoot.GetDoubleFromDateTime( *pDateTime );
+ double fInt = 0.0;
+ double fFrac = modf( fValue, &fInt );
+ short nFormatType = ((fFrac == 0.0) && (fInt != 0.0)) ? NUMBERFORMAT_DATE :
+ ((fInt == 0.0) ? NUMBERFORMAT_TIME : NUMBERFORMAT_DATETIME);
+ lclSetValue( rRoot, rScPos, fValue, nFormatType );
+ }
+ else if( const sal_uInt16* pnError = GetError() )
+ {
+ double fValue;
+ sal_uInt8 nErrCode = static_cast< sal_uInt8 >( *pnError );
+ const ScTokenArray* pScTokArr = rRoot.GetOldFmlaConverter().GetBoolErr(
+ XclTools::ErrorToEnum( fValue, EXC_BOOLERR_ERROR, nErrCode ) );
+ ScFormulaCell* pCell = new ScFormulaCell( &rDoc, rScPos, pScTokArr );
+ pCell->SetHybridDouble( fValue );
+ rDoc.PutCell( rScPos, pCell );
+ }
+}
+
+void XclImpPCItem::ReadSxdouble( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdouble - wrong record size" );
+ SetDouble( rStrm.ReadDouble() );
+}
+
+void XclImpPCItem::ReadSxboolean( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxboolean - wrong record size" );
+ SetBool( rStrm.ReaduInt16() != 0 );
+}
+
+void XclImpPCItem::ReadSxerror( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxerror - wrong record size" );
+ SetError( rStrm.ReaduInt16() );
+}
+
+void XclImpPCItem::ReadSxinteger( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxinteger - wrong record size" );
+ SetInteger( rStrm.ReadInt16() );
+}
+
+void XclImpPCItem::ReadSxstring( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() >= 3, "XclImpPCItem::ReadSxstring - wrong record size" );
+ SetText( rStrm.ReadUniString() );
+}
+
+void XclImpPCItem::ReadSxdatetime( XclImpStream& rStrm )
+{
+ DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdatetime - wrong record size" );
+ sal_uInt16 nYear, nMonth;
+ sal_uInt8 nDay, nHour, nMin, nSec;
+ rStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+ SetDateTime( DateTime( Date( nDay, nMonth, nYear ), Time( nHour, nMin, nSec ) ) );
+}
+
+void XclImpPCItem::ReadSxempty( XclImpStream& rStrm )
+{
+ (void)rStrm; // avoid compiler warning
+ DBG_ASSERT( rStrm.GetRecSize() == 0, "XclImpPCItem::ReadSxempty - wrong record size" );
+ SetEmpty();
+}
+
+// ============================================================================
+
+XclImpPCField::XclImpPCField( const XclImpRoot& rRoot, XclImpPivotCache& rPCache, sal_uInt16 nFieldIdx ) :
+ XclPCField( EXC_PCFIELD_UNKNOWN, nFieldIdx ),
+ XclImpRoot( rRoot ),
+ mrPCache( rPCache ),
+ mnSourceScCol( -1 ),
+ mbNumGroupInfoRead( false )
+{
+}
+
+XclImpPCField::~XclImpPCField()
+{
+}
+
+// general field/item access --------------------------------------------------
+
+const String& XclImpPCField::GetFieldName( const ScfStringVec& rVisNames ) const
+{
+ if( IsGroupChildField() && (mnFieldIdx < rVisNames.size()) )
+ {
+ const String& rVisName = rVisNames[ mnFieldIdx ];
+ if( rVisName.Len() > 0 )
+ return rVisName;
+ }
+ return maFieldInfo.maName;
+}
+
+const XclImpPCField* XclImpPCField::GetGroupBaseField() const
+{
+ DBG_ASSERT( IsGroupChildField(), "XclImpPCField::GetGroupBaseField - this field type does not have a base field" );
+ return IsGroupChildField() ? mrPCache.GetField( maFieldInfo.mnGroupBase ) : 0;
+}
+
+const XclImpPCItem* XclImpPCField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return (nItemIdx < maItems.size()) ? maItems[ nItemIdx ].get() : 0;
+}
+
+const XclImpPCItem* XclImpPCField::GetLimitItem( sal_uInt16 nItemIdx ) const
+{
+ DBG_ASSERT( nItemIdx < 3, "XclImpPCField::GetLimitItem - invalid item index" );
+ DBG_ASSERT( nItemIdx < maNumGroupItems.size(), "XclImpPCField::GetLimitItem - no item found" );
+ return (nItemIdx < maNumGroupItems.size()) ? maNumGroupItems[ nItemIdx ].get() : 0;
+}
+
+void XclImpPCField::WriteFieldNameToSource( SCCOL nScCol, SCTAB nScTab ) const
+{
+ DBG_ASSERT( HasOrigItems(), "XclImpPCField::WriteFieldNameToSource - only for standard fields" );
+ GetDoc().SetString( nScCol, 0, nScTab, maFieldInfo.maName );
+ mnSourceScCol = nScCol;
+}
+
+void XclImpPCField::WriteOrigItemToSource( SCROW nScRow, SCTAB nScTab, sal_uInt16 nItemIdx ) const
+{
+ if( nItemIdx < maOrigItems.size() )
+ maOrigItems[ nItemIdx ]->WriteToSource( GetRoot(), ScAddress( mnSourceScCol, nScRow, nScTab ) );
+}
+
+void XclImpPCField::WriteLastOrigItemToSource( SCROW nScRow, SCTAB nScTab ) const
+{
+ if( !maOrigItems.empty() )
+ maOrigItems.back()->WriteToSource( GetRoot(), ScAddress( mnSourceScCol, nScRow, nScTab ) );
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPCField::ReadSxfield( XclImpStream& rStrm )
+{
+ rStrm >> maFieldInfo;
+
+ /* Detect the type of this field. This is done very restrictive to detect
+ any unexpected state. */
+ meFieldType = EXC_PCFIELD_UNKNOWN;
+
+ bool bItems = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASITEMS );
+ bool bPostp = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
+ bool bCalced = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_CALCED );
+ bool bChild = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+ bool bNum = ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_NUMGROUP );
+
+ sal_uInt16 nVisC = maFieldInfo.mnVisItems;
+ sal_uInt16 nGroupC = maFieldInfo.mnGroupItems;
+ sal_uInt16 nBaseC = maFieldInfo.mnBaseItems;
+ sal_uInt16 nOrigC = maFieldInfo.mnOrigItems;
+ DBG_ASSERT( nVisC > 0, "XclImpPCField::ReadSxfield - field without visible items" );
+
+ sal_uInt16 nType = maFieldInfo.mnFlags & EXC_SXFIELD_DATA_MASK;
+ bool bType =
+ (nType == EXC_SXFIELD_DATA_STR) ||
+ (nType == EXC_SXFIELD_DATA_INT) ||
+ (nType == EXC_SXFIELD_DATA_DBL) ||
+ (nType == EXC_SXFIELD_DATA_STR_INT) ||
+ (nType == EXC_SXFIELD_DATA_STR_DBL) ||
+ (nType == EXC_SXFIELD_DATA_DATE) ||
+ (nType == EXC_SXFIELD_DATA_DATE_EMP) ||
+ (nType == EXC_SXFIELD_DATA_DATE_NUM) ||
+ (nType == EXC_SXFIELD_DATA_DATE_STR);
+ bool bTypeNone =
+ (nType == EXC_SXFIELD_DATA_NONE);
+ // for now, ignore data type of calculated fields
+ DBG_ASSERT( bCalced || bType || bTypeNone, "XclImpPCField::ReadSxfield - unknown item data type" );
+
+ if( nVisC > 0 || bPostp )
+ {
+ if( bItems && !bPostp )
+ {
+ if( !bCalced )
+ {
+ // 1) standard fields and standard grouping fields
+ if( !bNum )
+ {
+ // 1a) standard field without grouping
+ if( bType && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == nVisC) )
+ meFieldType = EXC_PCFIELD_STANDARD;
+
+ // 1b) standard grouping field
+ else if( bTypeNone && (nGroupC == nVisC) && (nBaseC > 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_STDGROUP;
+ }
+ // 2) numerical grouping fields
+ else if( (nGroupC == nVisC) && (nBaseC == 0) )
+ {
+ // 2a) single num/date grouping field without child grouping field
+ if( !bChild && bType && (nOrigC > 0) )
+ {
+ switch( nType )
+ {
+ case EXC_SXFIELD_DATA_INT:
+ case EXC_SXFIELD_DATA_DBL: meFieldType = EXC_PCFIELD_NUMGROUP; break;
+ case EXC_SXFIELD_DATA_DATE: meFieldType = EXC_PCFIELD_DATEGROUP; break;
+ default: DBG_ERRORFILE( "XclImpPCField::ReadSxfield - numeric group with wrong data type" );
+ }
+ }
+
+ // 2b) first date grouping field with child grouping field
+ else if( bChild && (nType == EXC_SXFIELD_DATA_DATE) && (nOrigC > 0) )
+ meFieldType = EXC_PCFIELD_DATEGROUP;
+
+ // 2c) additional date grouping field
+ else if( bTypeNone && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_DATECHILD;
+ }
+ DBG_ASSERT( meFieldType != EXC_PCFIELD_UNKNOWN, "XclImpPCField::ReadSxfield - invalid standard or grouped field" );
+ }
+
+ // 3) calculated field
+ else
+ {
+ if( !bChild && !bNum && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_CALCED;
+ DBG_ASSERT( meFieldType == EXC_PCFIELD_CALCED, "XclImpPCField::ReadSxfield - invalid calculated field" );
+ }
+ }
+
+ else if( !bItems && bPostp )
+ {
+ // 4) standard field with postponed items
+ if( !bCalced && !bChild && !bNum && bType && (nGroupC == 0) && (nBaseC == 0) && (nOrigC == 0) )
+ meFieldType = EXC_PCFIELD_STANDARD;
+ DBG_ASSERT( meFieldType == EXC_PCFIELD_STANDARD, "XclImpPCField::ReadSxfield - invalid postponed field" );
+ }
+ }
+}
+
+void XclImpPCField::ReadItem( XclImpStream& rStrm )
+{
+ DBG_ASSERT( HasInlineItems() || HasPostponedItems(), "XclImpPCField::ReadItem - field does not expect items" );
+
+ // read the item
+ XclImpPCItemRef xItem( new XclImpPCItem( rStrm ) );
+
+ // try to insert into an item list
+ if( mbNumGroupInfoRead )
+ {
+ // there are 3 items after SXNUMGROUP that contain grouping limits and step count
+ if( maNumGroupItems.size() < 3 )
+ maNumGroupItems.push_back( xItem );
+ else
+ maOrigItems.push_back( xItem );
+ }
+ else if( HasInlineItems() || HasPostponedItems() )
+ {
+ maItems.push_back( xItem );
+ // visible item is original item in standard fields
+ if( IsStandardField() )
+ maOrigItems.push_back( xItem );
+ }
+}
+
+void XclImpPCField::ReadSxnumgroup( XclImpStream& rStrm )
+{
+ DBG_ASSERT( IsNumGroupField() || IsDateGroupField(), "XclImpPCField::ReadSxnumgroup - SXNUMGROUP outside numeric grouping field" );
+ DBG_ASSERT( !mbNumGroupInfoRead, "XclImpPCField::ReadSxnumgroup - multiple SXNUMGROUP records" );
+ DBG_ASSERT( maItems.size() == maFieldInfo.mnGroupItems, "XclImpPCField::ReadSxnumgroup - SXNUMGROUP out of record order" );
+ rStrm >> maNumGroupInfo;
+ mbNumGroupInfoRead = IsNumGroupField() || IsDateGroupField();
+}
+
+void XclImpPCField::ReadSxgroupinfo( XclImpStream& rStrm )
+{
+ DBG_ASSERT( IsStdGroupField(), "XclImpPCField::ReadSxgroupinfo - SXGROUPINFO outside grouping field" );
+ DBG_ASSERT( maGroupOrder.empty(), "XclImpPCField::ReadSxgroupinfo - multiple SXGROUPINFO records" );
+ DBG_ASSERT( maItems.size() == maFieldInfo.mnGroupItems, "XclImpPCField::ReadSxgroupinfo - SXGROUPINFO out of record order" );
+ DBG_ASSERT( (rStrm.GetRecLeft() / 2) == maFieldInfo.mnBaseItems, "XclImpPCField::ReadSxgroupinfo - wrong SXGROUPINFO size" );
+ maGroupOrder.clear();
+ size_t nSize = rStrm.GetRecLeft() / 2;
+ maGroupOrder.resize( nSize, 0 );
+ for( size_t nIdx = 0; nIdx < nSize; ++nIdx )
+ rStrm >> maGroupOrder[ nIdx ];
+}
+
+// grouping -------------------------------------------------------------------
+
+void XclImpPCField::ConvertGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ if( GetFieldName( rVisNames ).Len() > 0 )
+ {
+ if( IsStdGroupField() )
+ ConvertStdGroupField( rSaveData, rVisNames );
+ else if( IsNumGroupField() )
+ ConvertNumGroupField( rSaveData, rVisNames );
+ else if( IsDateGroupField() )
+ ConvertDateGroupField( rSaveData, rVisNames );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpPCField::ConvertStdGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ if( const XclImpPCField* pBaseField = GetGroupBaseField() )
+ {
+ const String& rBaseFieldName = pBaseField->GetFieldName( rVisNames );
+ if( rBaseFieldName.Len() > 0 )
+ {
+ // *** create a ScDPSaveGroupItem for each own item, they collect base item names ***
+ ScDPSaveGroupItemVec aGroupItems;
+ aGroupItems.reserve( maItems.size() );
+ // initialize with own item names
+ for( XclImpPCItemVec::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ aGroupItems.push_back( ScDPSaveGroupItem( (*aIt)->ConvertToText() ) );
+
+ // *** iterate over all base items, set their names at corresponding own items ***
+ for( sal_uInt16 nItemIdx = 0, nItemCount = static_cast< sal_uInt16 >( maGroupOrder.size() ); nItemIdx < nItemCount; ++nItemIdx )
+ if( maGroupOrder[ nItemIdx ] < aGroupItems.size() )
+ if( const XclImpPCItem* pBaseItem = pBaseField->GetItem( nItemIdx ) )
+ if( const XclImpPCItem* pGroupItem = GetItem( maGroupOrder[ nItemIdx ] ) )
+ if( *pBaseItem != *pGroupItem )
+ aGroupItems[ maGroupOrder[ nItemIdx ] ].AddElement( pBaseItem->ConvertToText() );
+
+ // *** create the ScDPSaveGroupDimension object, fill with grouping info ***
+ ScDPSaveGroupDimension aGroupDim( rBaseFieldName, GetFieldName( rVisNames ) );
+ for( ScDPSaveGroupItemVec::const_iterator aIt = aGroupItems.begin(), aEnd = aGroupItems.end(); aIt != aEnd; ++aIt )
+ if( !aIt->IsEmpty() )
+ aGroupDim.AddGroupItem( *aIt );
+ rSaveData.GetDimensionData()->AddGroupDimension( aGroupDim );
+ }
+ }
+}
+
+void XclImpPCField::ConvertNumGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ ScDPNumGroupInfo aNumInfo( GetScNumGroupInfo() );
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), aNumInfo );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+}
+
+void XclImpPCField::ConvertDateGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const
+{
+ ScDPNumGroupInfo aDateInfo( GetScDateGroupInfo() );
+ sal_Int32 nScDateType = maNumGroupInfo.GetScDateType();
+
+ switch( meFieldType )
+ {
+ case EXC_PCFIELD_DATEGROUP:
+ {
+ if( aDateInfo.DateValues )
+ {
+ // special case for days only with step value - create numeric grouping
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), aDateInfo );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+ }
+ else
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim( GetFieldName( rVisNames ), ScDPNumGroupInfo() );
+ aNumGroupDim.SetDateInfo( aDateInfo, nScDateType );
+ rSaveData.GetDimensionData()->AddNumGroupDimension( aNumGroupDim );
+ }
+ }
+ break;
+
+ case EXC_PCFIELD_DATECHILD:
+ {
+ if( const XclImpPCField* pBaseField = GetGroupBaseField() )
+ {
+ const String& rBaseFieldName = pBaseField->GetFieldName( rVisNames );
+ if( rBaseFieldName.Len() > 0 )
+ {
+ ScDPSaveGroupDimension aGroupDim( rBaseFieldName, GetFieldName( rVisNames ) );
+ aGroupDim.SetDateInfo( aDateInfo, nScDateType );
+ rSaveData.GetDimensionData()->AddGroupDimension( aGroupDim );
+ }
+ }
+ }
+ break;
+
+ default:
+ DBG_ERRORFILE( "XclImpPCField::ConvertDateGroupField - unknown date field type" );
+ }
+}
+
+ScDPNumGroupInfo XclImpPCField::GetScNumGroupInfo() const
+{
+ ScDPNumGroupInfo aNumInfo;
+ aNumInfo.Enable = sal_True;
+ aNumInfo.DateValues = false;
+ aNumInfo.AutoStart = sal_True;
+ aNumInfo.AutoEnd = sal_True;
+
+ if( const double* pfMinValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_MIN ) )
+ {
+ aNumInfo.Start = *pfMinValue;
+ aNumInfo.AutoStart = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN );
+ }
+ if( const double* pfMaxValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_MAX ) )
+ {
+ aNumInfo.End = *pfMaxValue;
+ aNumInfo.AutoEnd = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX );
+ }
+ if( const double* pfStepValue = GetNumGroupLimit( EXC_SXFIELD_INDEX_STEP ) )
+ aNumInfo.Step = *pfStepValue;
+
+ return aNumInfo;
+}
+
+ScDPNumGroupInfo XclImpPCField::GetScDateGroupInfo() const
+{
+ ScDPNumGroupInfo aDateInfo;
+ aDateInfo.Enable = sal_True;
+ aDateInfo.DateValues = false;
+ aDateInfo.AutoStart = sal_True;
+ aDateInfo.AutoEnd = sal_True;
+
+ if( const DateTime* pMinDate = GetDateGroupLimit( EXC_SXFIELD_INDEX_MIN ) )
+ {
+ aDateInfo.Start = GetDoubleFromDateTime( *pMinDate );
+ aDateInfo.AutoStart = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMIN );
+ }
+ if( const DateTime* pMaxDate = GetDateGroupLimit( EXC_SXFIELD_INDEX_MAX ) )
+ {
+ aDateInfo.End = GetDoubleFromDateTime( *pMaxDate );
+ aDateInfo.AutoEnd = ::get_flag( maNumGroupInfo.mnFlags, EXC_SXNUMGROUP_AUTOMAX );
+ }
+ // GetDateGroupStep() returns a value for date type "day" in single date groups only
+ if( const sal_Int16* pnStepValue = GetDateGroupStep() )
+ {
+ aDateInfo.Step = *pnStepValue;
+ aDateInfo.DateValues = sal_True;
+ }
+
+ return aDateInfo;
+}
+
+const double* XclImpPCField::GetNumGroupLimit( sal_uInt16 nLimitIdx ) const
+{
+ DBG_ASSERT( IsNumGroupField(), "XclImpPCField::GetNumGroupLimit - only for numeric grouping fields" );
+ if( const XclImpPCItem* pItem = GetLimitItem( nLimitIdx ) )
+ {
+ DBG_ASSERT( pItem->GetDouble(), "XclImpPCField::GetNumGroupLimit - SXDOUBLE item expected" );
+ return pItem->GetDouble();
+ }
+ return 0;
+}
+
+const DateTime* XclImpPCField::GetDateGroupLimit( sal_uInt16 nLimitIdx ) const
+{
+ DBG_ASSERT( IsDateGroupField(), "XclImpPCField::GetDateGroupLimit - only for date grouping fields" );
+ if( const XclImpPCItem* pItem = GetLimitItem( nLimitIdx ) )
+ {
+ DBG_ASSERT( pItem->GetDateTime(), "XclImpPCField::GetDateGroupLimit - SXDATETIME item expected" );
+ return pItem->GetDateTime();
+ }
+ return 0;
+}
+
+const sal_Int16* XclImpPCField::GetDateGroupStep() const
+{
+ // only for single date grouping fields, not for grouping chains
+ if( !IsGroupBaseField() && !IsGroupChildField() )
+ {
+ // only days may have a step value, return 0 for all other date types
+ if( maNumGroupInfo.GetXclDataType() == EXC_SXNUMGROUP_TYPE_DAY )
+ {
+ if( const XclImpPCItem* pItem = GetLimitItem( EXC_SXFIELD_INDEX_STEP ) )
+ {
+ DBG_ASSERT( pItem->GetInteger(), "XclImpPCField::GetDateGroupStep - SXINTEGER item expected" );
+ if( const sal_Int16* pnStep = pItem->GetInteger() )
+ {
+ DBG_ASSERT( *pnStep > 0, "XclImpPCField::GetDateGroupStep - invalid step count" );
+ // return nothing for step count 1 - this is also a standard date group in Excel
+ return (*pnStep > 1) ? pnStep : 0;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+// ============================================================================
+
+XclImpPivotCache::XclImpPivotCache( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maSrcRange( ScAddress::INITIALIZE_INVALID ),
+ mnStrmId( 0 ),
+ mnSrcType( EXC_SXVS_UNKNOWN ),
+ mbSelfRef( false )
+{
+}
+
+XclImpPivotCache::~XclImpPivotCache()
+{
+}
+
+// data access ----------------------------------------------------------------
+
+sal_uInt16 XclImpPivotCache::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFields.size() );
+}
+
+const XclImpPCField* XclImpPivotCache::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPivotCache::ReadSxidstm( XclImpStream& rStrm )
+{
+ rStrm >> mnStrmId;
+}
+
+void XclImpPivotCache::ReadSxvs( XclImpStream& rStrm )
+{
+ rStrm >> mnSrcType;
+ GetTracer().TracePivotDataSource( mnSrcType != EXC_SXVS_SHEET );
+}
+
+void XclImpPivotCache::ReadDconref( XclImpStream& rStrm )
+{
+ /* Read DCONREF only once (by checking maTabName), there may be other
+ DCONREF records in another context. Read reference only if a leading
+ SXVS record is present (by checking mnSrcType). */
+ if( (maTabName.Len() > 0) || (mnSrcType != EXC_SXVS_SHEET) )
+ return;
+
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ aXclRange.Read( rStrm, false );
+ String aEncUrl = rStrm.ReadUniString();
+
+ XclImpUrlHelper::DecodeUrl( maUrl, maTabName, mbSelfRef, GetRoot(), aEncUrl );
+
+ /* Do not convert maTabName to Calc sheet name -> original name is used to
+ find the sheet in the document. Sheet index of source range will be
+ found later in XclImpPivotCache::ReadPivotCacheStream(), because sheet
+ may not exist yet. */
+ if( mbSelfRef )
+ GetAddressConverter().ConvertRange( maSrcRange, aXclRange, 0, 0, true );
+}
+
+void XclImpPivotCache::ReadDConName( XclImpStream& rStrm )
+{
+ maSrcRangeName = rStrm.ReadUniString();
+
+ // This 2-byte value equals the length of string that follows, or if 0 it
+ // indicates that the name has a workbook scope. For now, we only support
+ // internal defined name with a workbook scope.
+ sal_uInt16 nFlag;
+ rStrm >> nFlag;
+ mbSelfRef = (nFlag == 0);
+
+ if (!mbSelfRef)
+ // External name is not supported yet.
+ maSrcRangeName = OUString();
+}
+
+void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm )
+{
+ if( (mnSrcType != EXC_SXVS_SHEET) && (mnSrcType != EXC_SXVS_EXTERN) )
+ return;
+
+ ScDocument& rDoc = GetDoc();
+ SCCOL nFieldScCol = 0; // column index of source data for next field
+ SCROW nItemScRow = 0; // row index of source data for current items
+ SCTAB nScTab = 0; // sheet index of source data
+ bool bGenerateSource = false; // true = write source data from cache to dummy table
+
+ if( mbSelfRef )
+ {
+ if (!maSrcRangeName.getLength())
+ {
+ // try to find internal sheet containing the source data
+ nScTab = GetTabInfo().GetScTabFromXclName( maTabName );
+ if( rDoc.HasTable( nScTab ) )
+ {
+ // set sheet index to source range
+ maSrcRange.aStart.SetTab( nScTab );
+ maSrcRange.aEnd.SetTab( nScTab );
+ }
+ else
+ {
+ // create dummy sheet for deleted internal sheet
+ bGenerateSource = true;
+ }
+ }
+ }
+ else
+ {
+ // create dummy sheet for external sheet
+ bGenerateSource = true;
+ }
+
+ // create dummy sheet for source data from external or deleted sheet
+ if( bGenerateSource )
+ {
+ if( rDoc.GetTableCount() >= MAXTABCOUNT )
+ // cannot create more sheets -> exit
+ return;
+
+ nScTab = rDoc.GetTableCount();
+ rDoc.MakeTable( nScTab );
+ String aDummyName = CREATE_STRING( "DPCache" );
+ if( maTabName.Len() > 0 )
+ aDummyName.Append( '_' ).Append( maTabName );
+ rDoc.CreateValidTabName( aDummyName );
+ rDoc.RenameTab( nScTab, aDummyName );
+ // set sheet index to source range
+ maSrcRange.aStart.SetTab( nScTab );
+ maSrcRange.aEnd.SetTab( nScTab );
+ }
+
+ // open pivot cache storage stream
+ SotStorageRef xSvStrg = OpenStorage( EXC_STORAGE_PTCACHE );
+ SotStorageStreamRef xSvStrm = OpenStream( xSvStrg, ScfTools::GetHexStr( mnStrmId ) );
+ if( !xSvStrm.Is() )
+ return;
+
+ // create Excel record stream object
+ XclImpStream aPCStrm( *xSvStrm, GetRoot() );
+ aPCStrm.CopyDecrypterFrom( rStrm ); // pivot cache streams are encrypted
+
+ XclImpPCFieldRef xCurrField; // current field for new items
+ XclImpPCFieldVec aOrigFields; // all standard fields with inline original items
+ XclImpPCFieldVec aPostpFields; // all standard fields with postponed original items
+ size_t nPostpIdx = 0; // index to current field with postponed items
+ bool bLoop = true; // true = continue loop
+
+ while( bLoop && aPCStrm.StartNextRecord() )
+ {
+ switch( aPCStrm.GetRecId() )
+ {
+ case EXC_ID_EOF:
+ bLoop = false;
+ break;
+
+ case EXC_ID_SXDB:
+ aPCStrm >> maPCInfo;
+ break;
+
+ case EXC_ID_SXFIELD:
+ {
+ xCurrField.reset();
+ sal_uInt16 nNewFieldIdx = GetFieldCount();
+ if( nNewFieldIdx < EXC_PC_MAXFIELDCOUNT )
+ {
+ xCurrField.reset( new XclImpPCField( GetRoot(), *this, nNewFieldIdx ) );
+ maFields.push_back( xCurrField );
+ xCurrField->ReadSxfield( aPCStrm );
+ if( xCurrField->HasOrigItems() )
+ {
+ if( xCurrField->HasPostponedItems() )
+ aPostpFields.push_back( xCurrField );
+ else
+ aOrigFields.push_back( xCurrField );
+ // insert field name into generated source data, field remembers its column index
+ if( bGenerateSource && (nFieldScCol <= MAXCOL) )
+ xCurrField->WriteFieldNameToSource( nFieldScCol++, nScTab );
+ }
+ // do not read items into invalid/postponed fields
+ if( !xCurrField->HasInlineItems() )
+ xCurrField.reset();
+ }
+ }
+ break;
+
+ case EXC_ID_SXINDEXLIST:
+ // read index list and insert all items into generated source data
+ if( bGenerateSource && (nItemScRow <= MAXROW) && (++nItemScRow <= MAXROW) )
+ {
+ for( XclImpPCFieldVec::const_iterator aIt = aOrigFields.begin(), aEnd = aOrigFields.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt16 nItemIdx = (*aIt)->Has16BitIndexes() ? aPCStrm.ReaduInt16() : aPCStrm.ReaduInt8();
+ (*aIt)->WriteOrigItemToSource( nItemScRow, nScTab, nItemIdx );
+ }
+ }
+ xCurrField.reset();
+ break;
+
+ case EXC_ID_SXDOUBLE:
+ case EXC_ID_SXBOOLEAN:
+ case EXC_ID_SXERROR:
+ case EXC_ID_SXINTEGER:
+ case EXC_ID_SXSTRING:
+ case EXC_ID_SXDATETIME:
+ case EXC_ID_SXEMPTY:
+ if( xCurrField ) // inline items
+ {
+ xCurrField->ReadItem( aPCStrm );
+ }
+ else if( !aPostpFields.empty() ) // postponed items
+ {
+ // read postponed item
+ aPostpFields[ nPostpIdx ]->ReadItem( aPCStrm );
+ // write item to source
+ if( bGenerateSource && (nItemScRow <= MAXROW) )
+ {
+ // start new row, if there are only postponed fields
+ if( aOrigFields.empty() && (nPostpIdx == 0) )
+ ++nItemScRow;
+ if( nItemScRow <= MAXROW )
+ aPostpFields[ nPostpIdx ]->WriteLastOrigItemToSource( nItemScRow, nScTab );
+ }
+ // get index of next postponed field
+ ++nPostpIdx;
+ if( nPostpIdx >= aPostpFields.size() )
+ nPostpIdx = 0;
+ }
+ break;
+
+ case EXC_ID_SXNUMGROUP:
+ if( xCurrField )
+ xCurrField->ReadSxnumgroup( aPCStrm );
+ break;
+
+ case EXC_ID_SXGROUPINFO:
+ if( xCurrField )
+ xCurrField->ReadSxgroupinfo( aPCStrm );
+ break;
+
+ // known but ignored records
+ case EXC_ID_SXRULE:
+ case EXC_ID_SXFILT:
+ case EXC_ID_00F5:
+ case EXC_ID_SXNAME:
+ case EXC_ID_SXPAIR:
+ case EXC_ID_SXFMLA:
+ case EXC_ID_SXFORMULA:
+ case EXC_ID_SXDBEX:
+ case EXC_ID_SXFDBTYPE:
+ break;
+
+ default:
+ OSL_TRACE( "XclImpPivotCache::ReadPivotCacheStream - unknown record 0x%04hX", aPCStrm.GetRecId() );
+ }
+ }
+
+ DBG_ASSERT( maPCInfo.mnTotalFields == maFields.size(),
+ "XclImpPivotCache::ReadPivotCacheStream - field count mismatch" );
+
+ if (HasCacheRecords())
+ {
+ SCROW nNewEnd = maSrcRange.aStart.Row() + maPCInfo.mnSrcRecs;
+ maSrcRange.aEnd.SetRow(nNewEnd);
+ }
+
+ // set source range for external source data
+ if( bGenerateSource && (nFieldScCol > 0) )
+ {
+ maSrcRange.aStart.SetCol( 0 );
+ maSrcRange.aStart.SetRow( 0 );
+ // nFieldScCol points to first unused column
+ maSrcRange.aEnd.SetCol( nFieldScCol - 1 );
+ // nItemScRow points to last used row
+ maSrcRange.aEnd.SetRow( nItemScRow );
+ }
+}
+
+bool XclImpPivotCache::HasCacheRecords() const
+{
+ return static_cast<bool>(maPCInfo.mnFlags & EXC_SXDB_SAVEDATA);
+}
+
+bool XclImpPivotCache::IsRefreshOnLoad() const
+{
+ return static_cast<bool>(maPCInfo.mnFlags & EXC_SXDB_REFRESH_LOAD);
+}
+
+bool XclImpPivotCache::IsValid() const
+{
+ if (maSrcRangeName.getLength())
+ return true;
+
+ return maSrcRange.IsValid();
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+XclImpPTItem::XclImpPTItem( const XclImpPCField* pCacheField ) :
+ mpCacheField( pCacheField )
+{
+}
+
+const String* XclImpPTItem::GetItemName() const
+{
+ if( mpCacheField )
+ if( const XclImpPCItem* pCacheItem = mpCacheField->GetItem( maItemInfo.mnCacheIdx ) )
+ //! TODO: use XclImpPCItem::ConvertToText(), if all conversions are available
+ return pCacheItem->IsEmpty() ? &String::EmptyString() : pCacheItem->GetText();
+ return 0;
+}
+
+const String* XclImpPTItem::GetVisItemName() const
+{
+ return maItemInfo.HasVisName() ? maItemInfo.GetVisName() : GetItemName();
+}
+
+void XclImpPTItem::ReadSxvi( XclImpStream& rStrm )
+{
+ rStrm >> maItemInfo;
+}
+
+void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const
+{
+ if( const String* pItemName = GetItemName() )
+ {
+ ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName );
+ rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) );
+ rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) );
+ if (maItemInfo.HasVisName())
+ rMember.SetLayoutName(*maItemInfo.GetVisName());
+ }
+}
+
+// ============================================================================
+
+XclImpPTField::XclImpPTField( const XclImpPivotTable& rPTable, sal_uInt16 nCacheIdx ) :
+ mrPTable( rPTable )
+{
+ maFieldInfo.mnCacheIdx = nCacheIdx;
+}
+
+// general field/item access --------------------------------------------------
+
+const XclImpPCField* XclImpPTField::GetCacheField() const
+{
+ XclImpPivotCacheRef xPCache = mrPTable.GetPivotCache();
+ return xPCache ? xPCache->GetField( maFieldInfo.mnCacheIdx ) : 0;
+}
+
+const String& XclImpPTField::GetFieldName() const
+{
+ const XclImpPCField* pField = GetCacheField();
+ return pField ? pField->GetFieldName( mrPTable.GetVisFieldNames() ) : String::EmptyString();
+}
+
+const String& XclImpPTField::GetVisFieldName() const
+{
+ const String* pVisName = maFieldInfo.GetVisName();
+ return pVisName ? *pVisName : String::EmptyString();
+}
+
+const XclImpPTItem* XclImpPTField::GetItem( sal_uInt16 nItemIdx ) const
+{
+ return (nItemIdx < maItems.size()) ? maItems[ nItemIdx ].get() : 0;
+}
+
+const String* XclImpPTField::GetItemName( sal_uInt16 nItemIdx ) const
+{
+ const XclImpPTItem* pItem = GetItem( nItemIdx );
+ return pItem ? pItem->GetItemName() : 0;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPTField::ReadSxvd( XclImpStream& rStrm )
+{
+ rStrm >> maFieldInfo;
+}
+
+void XclImpPTField::ReadSxvdex( XclImpStream& rStrm )
+{
+ rStrm >> maFieldExtInfo;
+}
+
+void XclImpPTField::ReadSxvi( XclImpStream& rStrm )
+{
+ XclImpPTItemRef xItem( new XclImpPTItem( GetCacheField() ) );
+ maItems.push_back( xItem );
+ xItem->ReadSxvi( rStrm );
+}
+
+// row/column fields ----------------------------------------------------------
+
+void XclImpPTField::ConvertRowColField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_ROWCOL, "XclImpPTField::ConvertRowColField - no row/column field" );
+ // special data orientation field?
+ if( maFieldInfo.mnCacheIdx == EXC_SXIVD_DATA )
+ rSaveData.GetDataLayoutDimension()->SetOrientation( static_cast< sal_uInt16 >( maFieldInfo.GetApiOrient( EXC_SXVD_AXIS_ROWCOL ) ) );
+ else
+ ConvertRCPField( rSaveData );
+}
+
+// page fields ----------------------------------------------------------------
+
+void XclImpPTField::SetPageFieldInfo( const XclPTPageFieldInfo& rPageInfo )
+{
+ maPageInfo = rPageInfo;
+}
+
+void XclImpPTField::ConvertPageField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_PAGE, "XclImpPTField::ConvertPageField - no page field" );
+ if( ScDPSaveDimension* pSaveDim = ConvertRCPField( rSaveData ) )
+ {
+ const String* pName = GetItemName( maPageInfo.mnSelItem );
+ if (pName)
+ {
+ const OUString aName(*pName);
+ pSaveDim->SetCurrentPage(&aName);
+ }
+ }
+}
+
+// hidden fields --------------------------------------------------------------
+
+void XclImpPTField::ConvertHiddenField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( (maFieldInfo.mnAxes & EXC_SXVD_AXIS_ROWCOLPAGE) == 0, "XclImpPTField::ConvertHiddenField - field not hidden" );
+ ConvertRCPField( rSaveData );
+}
+
+// data fields ----------------------------------------------------------------
+
+bool XclImpPTField::HasDataFieldInfo() const
+{
+ return !maDataInfoList.empty();
+}
+
+void XclImpPTField::AddDataFieldInfo( const XclPTDataFieldInfo& rDataInfo )
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::AddDataFieldInfo - no data field" );
+ maDataInfoList.push_back( rDataInfo );
+}
+
+void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const
+{
+ DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::ConvertDataField - no data field" );
+ DBG_ASSERT( !maDataInfoList.empty(), "XclImpPTField::ConvertDataField - no data field info" );
+ if( !maDataInfoList.empty() )
+ {
+ const String& rFieldName = GetFieldName();
+ if( rFieldName.Len() > 0 )
+ {
+ XclPTDataFieldInfoList::const_iterator aIt = maDataInfoList.begin(), aEnd = maDataInfoList.end();
+
+ ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName );
+ ConvertDataField( rSaveDim, *aIt );
+
+ // multiple data fields -> clone dimension
+ for( ++aIt; aIt != aEnd; ++aIt )
+ {
+ ScDPSaveDimension& rDupDim = rSaveData.DuplicateDimension( rSaveDim );
+ ConvertDataFieldInfo( rDupDim, *aIt );
+ }
+ }
+ }
+}
+
+// private --------------------------------------------------------------------
+
+/**
+ * Convert Excel-encoded subtotal name to a Calc-encoded one.
+ */
+static OUString lcl_convertExcelSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (c == sal_Unicode('\\'))
+ {
+ aBuf.append(c);
+ aBuf.append(c);
+ }
+ else
+ aBuf.append(c);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const
+{
+ const String& rFieldName = GetFieldName();
+ if( rFieldName.Len() == 0 )
+ return 0;
+
+ const XclImpPCField* pCacheField = GetCacheField();
+ if( !pCacheField || !pCacheField->IsSupportedField() )
+ return 0;
+
+ ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName );
+
+ // orientation
+ rSaveDim.SetOrientation( static_cast< sal_uInt16 >( maFieldInfo.GetApiOrient( EXC_SXVD_AXIS_ROWCOLPAGE ) ) );
+
+ // general field info
+ ConvertFieldInfo( rSaveDim );
+
+ // visible name
+ if( const String* pVisName = maFieldInfo.GetVisName() )
+ if( pVisName->Len() > 0 )
+ rSaveDim.SetLayoutName( *pVisName );
+
+ // subtotal function(s)
+ XclPTSubtotalVec aSubtotalVec;
+ maFieldInfo.GetSubtotals( aSubtotalVec );
+ if( !aSubtotalVec.empty() )
+ rSaveDim.SetSubTotals( static_cast< long >( aSubtotalVec.size() ), &aSubtotalVec[ 0 ] );
+
+ // sorting
+ DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Field = mrPTable.GetDataFieldName( maFieldExtInfo.mnSortField );
+ aSortInfo.IsAscending = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SORT_ASC );
+ aSortInfo.Mode = maFieldExtInfo.GetApiSortMode();
+ rSaveDim.SetSortInfo( &aSortInfo );
+
+ // auto show
+ DataPilotFieldAutoShowInfo aShowInfo;
+ aShowInfo.IsEnabled = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_AUTOSHOW );
+ aShowInfo.ShowItemsMode = maFieldExtInfo.GetApiAutoShowMode();
+ aShowInfo.ItemCount = maFieldExtInfo.GetApiAutoShowCount();
+ aShowInfo.DataField = mrPTable.GetDataFieldName( maFieldExtInfo.mnShowField );
+ rSaveDim.SetAutoShowInfo( &aShowInfo );
+
+ // layout
+ DataPilotFieldLayoutInfo aLayoutInfo;
+ aLayoutInfo.LayoutMode = maFieldExtInfo.GetApiLayoutMode();
+ aLayoutInfo.AddEmptyLines = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_LAYOUT_BLANK );
+ rSaveDim.SetLayoutInfo( &aLayoutInfo );
+
+ // grouping info
+ pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() );
+
+ // custom subtotal name
+ if (maFieldExtInfo.mpFieldTotalName.get())
+ {
+ OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+ rSaveDim.SetSubtotalName(aSubName);
+ }
+
+ return &rSaveDim;
+}
+
+void XclImpPTField::ConvertFieldInfo( ScDPSaveDimension& rSaveDim ) const
+{
+ rSaveDim.SetShowEmpty( ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL ) );
+ ConvertItems( rSaveDim );
+}
+
+void XclImpPTField::ConvertDataField( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const
+{
+ // orientation
+ rSaveDim.SetOrientation( DataPilotFieldOrientation_DATA );
+ // general field info
+ ConvertFieldInfo( rSaveDim );
+ // extended data field info
+ ConvertDataFieldInfo( rSaveDim, rDataInfo );
+}
+
+void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const
+{
+ // visible name
+ if( const String* pVisName = rDataInfo.GetVisName() )
+ if( pVisName->Len() > 0 )
+ rSaveDim.SetLayoutName( *pVisName );
+
+ // aggregation function
+ rSaveDim.SetFunction( static_cast< sal_uInt16 >( rDataInfo.GetApiAggFunc() ) );
+
+ // result field reference
+ sal_Int32 nRefType = rDataInfo.GetApiRefType();
+ if( nRefType != ::com::sun::star::sheet::DataPilotFieldReferenceType::NONE )
+ {
+ DataPilotFieldReference aFieldRef;
+ aFieldRef.ReferenceType = nRefType;
+
+ if( const XclImpPTField* pRefField = mrPTable.GetField( rDataInfo.mnRefField ) )
+ {
+ aFieldRef.ReferenceField = pRefField->GetFieldName();
+ aFieldRef.ReferenceItemType = rDataInfo.GetApiRefItemType();
+ if( aFieldRef.ReferenceItemType == ::com::sun::star::sheet::DataPilotFieldReferenceItemType::NAMED )
+ if( const String* pRefItemName = pRefField->GetItemName( rDataInfo.mnRefItem ) )
+ aFieldRef.ReferenceItemName = *pRefItemName;
+ }
+
+ rSaveDim.SetReferenceValue( &aFieldRef );
+ }
+}
+
+void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const
+{
+ for( XclImpPTItemVec::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ (*aIt)->ConvertItem( rSaveDim );
+}
+
+// ============================================================================
+
+XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mpDPObj(NULL)
+{
+}
+
+XclImpPivotTable::~XclImpPivotTable()
+{
+}
+
+// cache/field access, misc. --------------------------------------------------
+
+sal_uInt16 XclImpPivotTable::GetFieldCount() const
+{
+ return static_cast< sal_uInt16 >( maFields.size() );
+}
+
+const XclImpPTField* XclImpPivotTable::GetField( sal_uInt16 nFieldIdx ) const
+{
+ return (nFieldIdx == EXC_SXIVD_DATA) ? &maDataOrientField :
+ ((nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0);
+}
+
+XclImpPTField* XclImpPivotTable::GetFieldAcc( sal_uInt16 nFieldIdx )
+{
+ // do not return maDataOrientField
+ return (nFieldIdx < maFields.size()) ? maFields[ nFieldIdx ].get() : 0;
+}
+
+const XclImpPTField* XclImpPivotTable::GetDataField( sal_uInt16 nDataFieldIdx ) const
+{
+ if( nDataFieldIdx < maOrigDataFields.size() )
+ return GetField( maOrigDataFields[ nDataFieldIdx ] );
+ return 0;
+}
+
+const String& XclImpPivotTable::GetDataFieldName( sal_uInt16 nDataFieldIdx ) const
+{
+ if( const XclImpPTField* pField = GetDataField( nDataFieldIdx ) )
+ return pField->GetFieldName();
+ return EMPTY_STRING;
+}
+
+// records --------------------------------------------------------------------
+
+void XclImpPivotTable::ReadSxview( XclImpStream& rStrm )
+{
+ rStrm >> maPTInfo;
+
+ GetAddressConverter().ConvertRange(
+ maOutScRange, maPTInfo.maOutXclRange, GetCurrScTab(), GetCurrScTab(), true );
+
+ mxPCache = GetPivotTableManager().GetPivotCache( maPTInfo.mnCacheIdx );
+ mxCurrField.reset();
+}
+
+void XclImpPivotTable::ReadSxvd( XclImpStream& rStrm )
+{
+ sal_uInt16 nFieldCount = GetFieldCount();
+ if( nFieldCount < EXC_PT_MAXFIELDCOUNT )
+ {
+ // cache index for the field is equal to the SXVD record index
+ mxCurrField.reset( new XclImpPTField( *this, nFieldCount ) );
+ maFields.push_back( mxCurrField );
+ mxCurrField->ReadSxvd( rStrm );
+ // add visible name of new field to list of visible names
+ maVisFieldNames.push_back( mxCurrField->GetVisFieldName() );
+ DBG_ASSERT( maFields.size() == maVisFieldNames.size(),
+ "XclImpPivotTable::ReadSxvd - wrong size of visible name array" );
+ }
+ else
+ mxCurrField.reset();
+}
+
+void XclImpPivotTable::ReadSxvi( XclImpStream& rStrm )
+{
+ if( mxCurrField )
+ mxCurrField->ReadSxvi( rStrm );
+}
+
+void XclImpPivotTable::ReadSxvdex( XclImpStream& rStrm )
+{
+ if( mxCurrField )
+ mxCurrField->ReadSxvdex( rStrm );
+}
+
+void XclImpPivotTable::ReadSxivd( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ // find the index vector to fill (row SXIVD doesn't exist without row fields)
+ ScfUInt16Vec* pFieldVec = 0;
+ if( maRowFields.empty() && (maPTInfo.mnRowFields > 0) )
+ pFieldVec = &maRowFields;
+ else if( maColFields.empty() && (maPTInfo.mnColFields > 0) )
+ pFieldVec = &maColFields;
+
+ // fill the vector from record data
+ if( pFieldVec )
+ {
+ sal_uInt16 nSize = ulimit_cast< sal_uInt16 >( rStrm.GetRecSize() / 2, EXC_PT_MAXROWCOLCOUNT );
+ pFieldVec->reserve( nSize );
+ for( sal_uInt16 nIdx = 0; nIdx < nSize; ++nIdx )
+ {
+ sal_uInt16 nFieldIdx;
+ rStrm >> nFieldIdx;
+ pFieldVec->push_back( nFieldIdx );
+
+ // set orientation at special data orientation field
+ if( nFieldIdx == EXC_SXIVD_DATA )
+ {
+ sal_uInt16 nAxis = (pFieldVec == &maRowFields) ? EXC_SXVD_AXIS_ROW : EXC_SXVD_AXIS_COL;
+ maDataOrientField.SetAxes( nAxis );
+ }
+ }
+ }
+}
+
+void XclImpPivotTable::ReadSxpi( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ sal_uInt16 nSize = ulimit_cast< sal_uInt16 >( rStrm.GetRecSize() / 6 );
+ for( sal_uInt16 nEntry = 0; nEntry < nSize; ++nEntry )
+ {
+ XclPTPageFieldInfo aPageInfo;
+ rStrm >> aPageInfo;
+ if( XclImpPTField* pField = GetFieldAcc( aPageInfo.mnField ) )
+ {
+ maPageFields.push_back( aPageInfo.mnField );
+ pField->SetPageFieldInfo( aPageInfo );
+ }
+ GetCurrSheetDrawing().SetSkipObj( aPageInfo.mnObjId );
+ }
+}
+
+void XclImpPivotTable::ReadSxdi( XclImpStream& rStrm )
+{
+ mxCurrField.reset();
+
+ XclPTDataFieldInfo aDataInfo;
+ rStrm >> aDataInfo;
+ if( XclImpPTField* pField = GetFieldAcc( aDataInfo.mnField ) )
+ {
+ maOrigDataFields.push_back( aDataInfo.mnField );
+ // DataPilot does not support double data fields -> add first appearence to index list only
+ if( !pField->HasDataFieldInfo() )
+ maFiltDataFields.push_back( aDataInfo.mnField );
+ pField->AddDataFieldInfo( aDataInfo );
+ }
+}
+
+void XclImpPivotTable::ReadSxex( XclImpStream& rStrm )
+{
+ rStrm >> maPTExtInfo;
+}
+
+void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ rStrm >> maPTViewEx9Info;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpPivotTable::Convert()
+{
+ if( !mxPCache || !mxPCache->IsValid() )
+ return;
+
+ ScDPSaveData aSaveData;
+
+ // *** global settings ***
+
+ aSaveData.SetRowGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_ROWGRAND ) );
+ aSaveData.SetColumnGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND ) );
+ aSaveData.SetFilterButton( false );
+ aSaveData.SetDrillDown( ::get_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN ) );
+
+ // *** fields ***
+
+ ScfUInt16Vec::const_iterator aIt, aEnd;
+
+ // row fields
+ for( aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertRowColField( aSaveData );
+
+ // column fields
+ for( aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertRowColField( aSaveData );
+
+ // page fields
+ for( aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertPageField( aSaveData );
+
+ // We need to import hidden fields because hidden fields may contain
+ // special settings for subtotals (aggregation function, filters, custom
+ // name etc.) and members (hidden, custom name etc.).
+
+ // hidden fields
+ for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField )
+ if( const XclImpPTField* pField = GetField( nField ) )
+ if( (pField->GetAxes() & EXC_SXVD_AXIS_ROWCOLPAGE) == 0 )
+ pField->ConvertHiddenField( aSaveData );
+
+ // data fields
+ for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt )
+ if( const XclImpPTField* pField = GetField( *aIt ) )
+ pField->ConvertDataField( aSaveData );
+
+ // *** insert into Calc document ***
+
+ // create source descriptor
+ ScSheetSourceDesc aDesc(GetDocPtr());
+ const OUString& rSrcName = mxPCache->GetSourceRangeName();
+ if (rSrcName.getLength())
+ // Range name is the data source.
+ aDesc.SetRangeName(rSrcName);
+ else
+ // Normal cell range.
+ aDesc.SetSourceRange(mxPCache->GetSourceRange());
+
+ // adjust output range to include the page fields
+ ScRange aOutRange( maOutScRange );
+ if( !maPageFields.empty() )
+ {
+ SCsROW nDecRows = ::std::min< SCsROW >( aOutRange.aStart.Row(), maPageFields.size() + 1 );
+ aOutRange.aStart.IncRow( -nDecRows );
+ }
+
+ // create the DataPilot
+ ScDPObject* pDPObj = new ScDPObject( GetDocPtr() );
+ pDPObj->SetName( maPTInfo.maTableName );
+ if (maPTInfo.maDataName.Len() > 0)
+ aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName);
+
+ if (maPTViewEx9Info.maGrandTotalName.Len() > 0)
+ aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName);
+
+ pDPObj->SetSaveData( aSaveData );
+ pDPObj->SetSheetDesc( aDesc );
+ pDPObj->SetOutRange( aOutRange );
+ pDPObj->SetAlive( sal_True );
+ pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 );
+
+ GetDoc().GetDPCollection()->InsertNewTable(pDPObj);
+ mpDPObj = pDPObj;
+
+ ApplyMergeFlags(aOutRange, aSaveData);
+}
+
+void XclImpPivotTable::MaybeRefresh()
+{
+ if (mpDPObj && mxPCache->IsRefreshOnLoad())
+ {
+ // 'refresh table on load' flag is set. Refresh the table now. Some
+ // Excel files contain partial table output when this flag is set.
+ ScRange aOutRange = mpDPObj->GetOutRange();
+ mpDPObj->Output(aOutRange.aStart);
+ }
+}
+
+void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData)
+{
+ // Apply merge flags for varoius datapilot controls.
+
+ ScDPOutputGeometry aGeometry(rOutRange, false, ScDPOutputGeometry::XLS);
+ aGeometry.setColumnFieldCount(maPTInfo.mnColFields);
+ aGeometry.setPageFieldCount(maPTInfo.mnPageFields);
+ aGeometry.setDataFieldCount(maPTInfo.mnDataFields);
+
+ // Excel includes data layout field in the row field count. We need to
+ // subtract it.
+ bool bDataLayout = maPTInfo.mnDataFields > 1;
+ aGeometry.setRowFieldCount(maPTInfo.mnRowFields - static_cast<sal_uInt32>(bDataLayout));
+
+ ScDocument& rDoc = GetDoc();
+
+ vector<ScAddress> aPageBtns;
+ aGeometry.getPageFieldPositions(aPageBtns);
+ vector<ScAddress>::const_iterator itr = aPageBtns.begin(), itrEnd = aPageBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_uInt16 nMFlag = SC_MF_BUTTON;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO);
+ }
+
+ vector<ScAddress> aColBtns;
+ aGeometry.getColumnFieldPositions(aColBtns);
+ itr = aColBtns.begin();
+ itrEnd = aColBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+
+ vector<ScAddress> aRowBtns;
+ aGeometry.getRowFieldPositions(aRowBtns);
+ if (aRowBtns.empty())
+ {
+ if (bDataLayout)
+ {
+ // No row fields, but the data layout button exists.
+ SCROW nRow = aGeometry.getRowFieldHeaderRow();
+ SCCOL nCol = rOutRange.aStart.Col();
+ SCTAB nTab = rOutRange.aStart.Tab();
+ rDoc.ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
+ }
+ }
+ else
+ {
+ itr = aRowBtns.begin();
+ itrEnd = aRowBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+ if (bDataLayout)
+ {
+ --itr; // move back to the last row field position.
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON);
+ }
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+XclImpPivotTableManager::XclImpPivotTableManager( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+XclImpPivotTableManager::~XclImpPivotTableManager()
+{
+}
+
+// pivot cache records --------------------------------------------------------
+
+XclImpPivotCacheRef XclImpPivotTableManager::GetPivotCache( sal_uInt16 nCacheIdx )
+{
+ XclImpPivotCacheRef xPCache;
+ if( nCacheIdx < maPCaches.size() )
+ xPCache = maPCaches[ nCacheIdx ];
+ return xPCache;
+}
+
+void XclImpPivotTableManager::ReadSxidstm( XclImpStream& rStrm )
+{
+ XclImpPivotCacheRef xPCache( new XclImpPivotCache( GetRoot() ) );
+ maPCaches.push_back( xPCache );
+ xPCache->ReadSxidstm( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvs( XclImpStream& rStrm )
+{
+ if( !maPCaches.empty() )
+ maPCaches.back()->ReadSxvs( rStrm );
+}
+
+void XclImpPivotTableManager::ReadDconref( XclImpStream& rStrm )
+{
+ if( !maPCaches.empty() )
+ maPCaches.back()->ReadDconref( rStrm );
+}
+
+void XclImpPivotTableManager::ReadDConName( XclImpStream& rStrm )
+{
+ if( !maPCaches.empty() )
+ maPCaches.back()->ReadDConName( rStrm );
+}
+
+// pivot table records --------------------------------------------------------
+
+void XclImpPivotTableManager::ReadSxview( XclImpStream& rStrm )
+{
+ XclImpPivotTableRef xPTable( new XclImpPivotTable( GetRoot() ) );
+ maPTables.push_back( xPTable );
+ xPTable->ReadSxview( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvd( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvd( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvdex( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvdex( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxivd( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxivd( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxpi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxpi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxdi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxdi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxvi( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxvi( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxex( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxex( rStrm );
+}
+
+void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxViewEx9( rStrm );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm )
+{
+ for( XclImpPivotCacheVec::iterator aIt = maPCaches.begin(), aEnd = maPCaches.end(); aIt != aEnd; ++aIt )
+ (*aIt)->ReadPivotCacheStream( rStrm );
+}
+
+void XclImpPivotTableManager::ConvertPivotTables()
+{
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->Convert();
+}
+
+void XclImpPivotTableManager::MaybeRefreshPivotTables()
+{
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->MaybeRefresh();
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx
new file mode 100644
index 000000000000..9180ed401b62
--- /dev/null
+++ b/sc/source/filter/excel/xiroot.cxx
@@ -0,0 +1,311 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiroot.hxx"
+#include "addincol.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xiformula.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+#include "xistyle.hxx"
+#include "xicontent.hxx"
+#include "xiescher.hxx"
+#include "xipivot.hxx"
+#include "xipage.hxx"
+#include "xiview.hxx"
+
+#include "root.hxx"
+#include "excimp8.hxx"
+
+// Global data ================================================================
+
+XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
+ XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ),
+ mbHasCodePage( false ),
+ mbHasBasic( false )
+{
+}
+
+XclImpRootData::~XclImpRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpRoot::XclImpRoot( XclImpRootData& rImpRootData ) :
+ XclRoot( rImpRootData ),
+ mrImpData( rImpRootData )
+{
+ mrImpData.mxAddrConv.reset( new XclImpAddressConverter( GetRoot() ) );
+ mrImpData.mxFmlaComp.reset( new XclImpFormulaCompiler( GetRoot() ) );
+ mrImpData.mxPalette.reset( new XclImpPalette( GetRoot() ) );
+ mrImpData.mxFontBfr.reset( new XclImpFontBuffer( GetRoot() ) );
+ mrImpData.mxNumFmtBfr.reset( new XclImpNumFmtBuffer( GetRoot() ) );
+ mrImpData.mpXFBfr.reset( new XclImpXFBuffer( GetRoot() ) );
+ mrImpData.mxXFRangeBfr.reset( new XclImpXFRangeBuffer( GetRoot() ) );
+ mrImpData.mxTabInfo.reset( new XclImpTabInfo );
+ mrImpData.mxNameMgr.reset( new XclImpNameManager( GetRoot() ) );
+ mrImpData.mxObjMgr.reset( new XclImpObjectManager( GetRoot() ) );
+
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ mrImpData.mxLinkMgr.reset( new XclImpLinkManager( GetRoot() ) );
+ mrImpData.mxSst.reset( new XclImpSst( GetRoot() ) );
+ mrImpData.mxCondFmtMgr.reset( new XclImpCondFormatManager( GetRoot() ) );
+ mrImpData.mxValidMgr.reset( new XclImpValidationManager( GetRoot() ) );
+ // TODO still in old RootData (deleted by RootData)
+ GetOldRoot().pAutoFilterBuffer = new XclImpAutoFilterBuffer;
+ mrImpData.mxWebQueryBfr.reset( new XclImpWebQueryBuffer( GetRoot() ) );
+ mrImpData.mxPTableMgr.reset( new XclImpPivotTableManager( GetRoot() ) );
+ mrImpData.mxTabProtect.reset( new XclImpSheetProtectBuffer( GetRoot() ) );
+ mrImpData.mxDocProtect.reset( new XclImpDocProtectBuffer( GetRoot() ) );
+ }
+
+ mrImpData.mxPageSett.reset( new XclImpPageSettings( GetRoot() ) );
+ mrImpData.mxDocViewSett.reset( new XclImpDocViewSettings( GetRoot() ) );
+ mrImpData.mxTabViewSett.reset( new XclImpTabViewSettings( GetRoot() ) );
+}
+
+void XclImpRoot::SetCodePage( sal_uInt16 nCodePage )
+{
+ SetTextEncoding( XclTools::GetTextEncoding( nCodePage ) );
+ mrImpData.mbHasCodePage = true;
+}
+
+void XclImpRoot::SetAppFontEncoding( rtl_TextEncoding eAppFontEnc )
+{
+ if( !mrImpData.mbHasCodePage )
+ SetTextEncoding( eAppFontEnc );
+}
+
+void XclImpRoot::InitializeTable( SCTAB nScTab )
+{
+ if( GetBiff() <= EXC_BIFF4 )
+ {
+ GetPalette().Initialize();
+ GetFontBuffer().Initialize();
+ GetNumFmtBuffer().Initialize();
+ GetXFBuffer().Initialize();
+ }
+ GetXFRangeBuffer().Initialize();
+ GetPageSettings().Initialize();
+ GetTabViewSettings().Initialize();
+ // delete the automatically generated codename
+ GetDoc().SetCodeName( nScTab, String::EmptyString() );
+}
+
+void XclImpRoot::FinalizeTable()
+{
+ GetXFRangeBuffer().Finalize();
+ GetOldRoot().pColRowBuff->Convert( GetCurrScTab() );
+ GetPageSettings().Finalize();
+ GetTabViewSettings().Finalize();
+}
+
+XclImpAddressConverter& XclImpRoot::GetAddressConverter() const
+{
+ return *mrImpData.mxAddrConv;
+}
+
+XclImpFormulaCompiler& XclImpRoot::GetFormulaCompiler() const
+{
+ return *mrImpData.mxFmlaComp;
+}
+
+ExcelToSc& XclImpRoot::GetOldFmlaConverter() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pFmlaConverter;
+}
+
+XclImpSst& XclImpRoot::GetSst() const
+{
+ DBG_ASSERT( mrImpData.mxSst, "XclImpRoot::GetSst - invalid call, wrong BIFF" );
+ return *mrImpData.mxSst;
+}
+
+XclImpPalette& XclImpRoot::GetPalette() const
+{
+ return *mrImpData.mxPalette;
+}
+
+XclImpFontBuffer& XclImpRoot::GetFontBuffer() const
+{
+ return *mrImpData.mxFontBfr;
+}
+
+XclImpNumFmtBuffer& XclImpRoot::GetNumFmtBuffer() const
+{
+ return *mrImpData.mxNumFmtBfr;
+}
+
+XclImpXFBuffer& XclImpRoot::GetXFBuffer() const
+{
+ return *mrImpData.mpXFBfr;
+}
+
+XclImpXFRangeBuffer& XclImpRoot::GetXFRangeBuffer() const
+{
+ return *mrImpData.mxXFRangeBfr;
+}
+
+_ScRangeListTabs& XclImpRoot::GetPrintAreaBuffer() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pPrintRanges;
+}
+
+_ScRangeListTabs& XclImpRoot::GetTitleAreaBuffer() const
+{
+ // TODO still in old RootData
+ return *GetOldRoot().pPrintTitles;
+}
+
+XclImpTabInfo& XclImpRoot::GetTabInfo() const
+{
+ return *mrImpData.mxTabInfo;
+}
+
+XclImpNameManager& XclImpRoot::GetNameManager() const
+{
+ return *mrImpData.mxNameMgr;
+}
+
+XclImpLinkManager& XclImpRoot::GetLinkManager() const
+{
+ DBG_ASSERT( mrImpData.mxLinkMgr, "XclImpRoot::GetLinkManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxLinkMgr;
+}
+
+XclImpObjectManager& XclImpRoot::GetObjectManager() const
+{
+ return *mrImpData.mxObjMgr;
+}
+
+XclImpSheetDrawing& XclImpRoot::GetCurrSheetDrawing() const
+{
+ DBG_ASSERT( !IsInGlobals(), "XclImpRoot::GetCurrSheetDrawing - must not be called from workbook globals" );
+ return mrImpData.mxObjMgr->GetSheetDrawing( GetCurrScTab() );
+}
+
+XclImpCondFormatManager& XclImpRoot::GetCondFormatManager() const
+{
+ DBG_ASSERT( mrImpData.mxCondFmtMgr, "XclImpRoot::GetCondFormatManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxCondFmtMgr;
+}
+
+XclImpValidationManager& XclImpRoot::GetValidationManager() const
+{
+ DBG_ASSERT( mrImpData.mxValidMgr, "XclImpRoot::GetValidationManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxValidMgr;
+}
+
+XclImpAutoFilterBuffer& XclImpRoot::GetFilterManager() const
+{
+ // TODO still in old RootData
+ DBG_ASSERT( GetOldRoot().pAutoFilterBuffer, "XclImpRoot::GetFilterManager - invalid call, wrong BIFF" );
+ return *GetOldRoot().pAutoFilterBuffer;
+}
+
+XclImpWebQueryBuffer& XclImpRoot::GetWebQueryBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxWebQueryBfr, "XclImpRoot::GetWebQueryBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxWebQueryBfr;
+}
+
+XclImpPivotTableManager& XclImpRoot::GetPivotTableManager() const
+{
+ DBG_ASSERT( mrImpData.mxPTableMgr, "XclImpRoot::GetPivotTableManager - invalid call, wrong BIFF" );
+ return *mrImpData.mxPTableMgr;
+}
+
+XclImpSheetProtectBuffer& XclImpRoot::GetSheetProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxTabProtect, "XclImpRoot::GetSheetProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxTabProtect;
+}
+
+XclImpDocProtectBuffer& XclImpRoot::GetDocProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxDocProtect, "XclImpRoot::GetDocProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxDocProtect;
+}
+
+XclImpPageSettings& XclImpRoot::GetPageSettings() const
+{
+ return *mrImpData.mxPageSett;
+}
+
+XclImpDocViewSettings& XclImpRoot::GetDocViewSettings() const
+{
+ return *mrImpData.mxDocViewSett;
+}
+
+XclImpTabViewSettings& XclImpRoot::GetTabViewSettings() const
+{
+ return *mrImpData.mxTabViewSett;
+}
+
+String XclImpRoot::GetScAddInName( const String& rXclName ) const
+{
+ String aScName;
+ if( ScGlobal::GetAddInCollection()->GetCalcName( rXclName, aScName ) )
+ return aScName;
+ return rXclName;
+}
+
+void XclImpRoot::ReadCodeName( XclImpStream& rStrm, bool bGlobals )
+{
+ if( mrImpData.mbHasBasic && (GetBiff() == EXC_BIFF8) )
+ {
+ String aName = rStrm.ReadUniString();
+ if( aName.Len() > 0 )
+ {
+ if( bGlobals )
+ {
+ GetExtDocOptions().GetDocSettings().maGlobCodeName = aName;
+ GetDoc().SetCodeName( aName );
+ }
+ else
+ {
+ GetExtDocOptions().SetCodeName( GetCurrScTab(), aName );
+ GetDoc().SetCodeName( GetCurrScTab(), aName );
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
new file mode 100644
index 000000000000..94e8c8cd3ae3
--- /dev/null
+++ b/sc/source/filter/excel/xistream.cxx
@@ -0,0 +1,1142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include "xistream.hxx"
+#include "xlstring.hxx"
+#include "xiroot.hxx"
+
+#include <vector>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+
+using namespace ::com::sun::star;
+
+// ============================================================================
+// Decryption
+// ============================================================================
+
+XclImpDecrypter::XclImpDecrypter() :
+ mnError( EXC_ENCR_ERROR_UNSUPP_CRYPT ),
+ mnOldPos( STREAM_SEEK_TO_END ),
+ mnRecSize( 0 )
+{
+}
+
+XclImpDecrypter::XclImpDecrypter( const XclImpDecrypter& rSrc ) :
+ ::comphelper::IDocPasswordVerifier(),
+ mnError( rSrc.mnError ),
+ mnOldPos( STREAM_SEEK_TO_END ),
+ mnRecSize( 0 )
+{
+}
+
+XclImpDecrypter::~XclImpDecrypter()
+{
+}
+
+XclImpDecrypterRef XclImpDecrypter::Clone() const
+{
+ XclImpDecrypterRef xNewDecr;
+ if( IsValid() )
+ xNewDecr.reset( OnClone() );
+ return xNewDecr;
+}
+
+::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
+{
+ o_rEncryptionData = OnVerifyPassword( rPassword );
+ mnError = o_rEncryptionData.getLength() ? ERRCODE_NONE : ERRCODE_ABORT;
+ return o_rEncryptionData.getLength() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
+{
+ bool bValid = OnVerifyEncryptionData( rEncryptionData );
+ mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT;
+ return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+void XclImpDecrypter::Update( SvStream& rStrm, sal_uInt16 nRecSize )
+{
+ if( IsValid() )
+ {
+ sal_Size nNewPos = rStrm.Tell();
+ if( (mnOldPos != nNewPos) || (mnRecSize != nRecSize) )
+ {
+ OnUpdate( mnOldPos, nNewPos, nRecSize );
+ mnOldPos = nNewPos;
+ mnRecSize = nRecSize;
+ }
+ }
+}
+
+sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = 0;
+ if( pData && nBytes )
+ {
+ if( IsValid() )
+ {
+ Update( rStrm, mnRecSize );
+ nRet = OnRead( rStrm, reinterpret_cast< sal_uInt8* >( pData ), nBytes );
+ mnOldPos = rStrm.Tell();
+ }
+ else
+ nRet = static_cast< sal_uInt16 >( rStrm.Read( pData, nBytes ) );
+ }
+ return nRet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) :
+ mnKey( nKey ),
+ mnHash( nHash )
+{
+}
+
+XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) :
+ XclImpDecrypter( rSrc ),
+ maEncryptionData( rSrc.maEncryptionData ),
+ mnKey( rSrc.mnKey ),
+ mnHash( rSrc.mnHash )
+{
+ if( IsValid() )
+ maCodec.InitCodec( maEncryptionData );
+}
+
+XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const
+{
+ return new XclImpBiff5Decrypter( *this );
+}
+
+uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const ::rtl::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( (sal_uInt8*)aBytePassword.getStr() );
+
+ if ( maCodec.VerifyKey( mnKey, mnHash ) )
+ {
+ maEncryptionData = maCodec.GetEncryptionData();
+
+ // since the export uses Std97 encryption always we have to request it here
+ ::std::vector< sal_uInt16 > aPassVect( 16 );
+ ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
+ for( sal_Int32 nInd = 0; nInd < nLen; ++nInd, ++aIt )
+ *aIt = static_cast< sal_uInt16 >( rPassword.getStr()[nInd] );
+
+ uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
+ OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the senquence!" );
+
+ ::msfilter::MSCodec_Std97 aCodec97;
+ aCodec97.InitKey( &aPassVect.front(), (sal_uInt8*)aDocId.getConstArray() );
+
+ // merge the EncryptionData, there should be no conflicts
+ ::comphelper::SequenceAsHashMap aEncryptionHash( maEncryptionData );
+ aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) );
+ aEncryptionHash >> maEncryptionData;
+ }
+ }
+
+ return maEncryptionData;
+}
+
+bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.getLength() )
+ {
+ // init codec
+ maCodec.InitCodec( rEncryptionData );
+
+ if ( maCodec.VerifyKey( mnKey, mnHash ) )
+ maEncryptionData = rEncryptionData;
+ }
+
+ return maEncryptionData.getLength();
+}
+
+void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize )
+{
+ maCodec.InitCipher();
+ maCodec.Skip( (nNewStrmPos + nRecSize) & 0x0F );
+}
+
+sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = static_cast< sal_uInt16 >( rStrm.Read( pnData, nBytes ) );
+ maCodec.Decode( pnData, nRet );
+ return nRet;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
+ sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
+ maSalt( pnSalt, pnSalt + 16 ),
+ maVerifier( pnVerifier, pnVerifier + 16 ),
+ maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
+{
+}
+
+XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) :
+ XclImpDecrypter( rSrc ),
+ maEncryptionData( rSrc.maEncryptionData ),
+ maSalt( rSrc.maSalt ),
+ maVerifier( rSrc.maVerifier ),
+ maVerifierHash( rSrc.maVerifierHash )
+{
+ if( IsValid() )
+ maCodec.InitCodec( maEncryptionData );
+}
+
+XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const
+{
+ return new XclImpBiff8Decrypter( *this );
+}
+
+uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const ::rtl::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 XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.getLength() )
+ {
+ // init codec
+ maCodec.InitCodec( rEncryptionData );
+
+ if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
+ maEncryptionData = rEncryptionData;
+ }
+
+ return maEncryptionData.getLength();
+}
+
+void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ )
+{
+ if( nNewStrmPos != nOldStrmPos )
+ {
+ sal_uInt32 nOldBlock = GetBlock( nOldStrmPos );
+ sal_uInt16 nOldOffset = GetOffset( nOldStrmPos );
+
+ sal_uInt32 nNewBlock = GetBlock( nNewStrmPos );
+ sal_uInt16 nNewOffset = GetOffset( nNewStrmPos );
+
+ /* Rekey cipher, if block changed or if previous offset in same block. */
+ if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
+ {
+ maCodec.InitCipher( nNewBlock );
+ nOldOffset = 0; // reset nOldOffset for next if() statement
+ }
+
+ /* Seek to correct offset. */
+ if( nNewOffset > nOldOffset )
+ maCodec.Skip( nNewOffset - nOldOffset );
+ }
+}
+
+sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
+{
+ sal_uInt16 nRet = 0;
+
+ sal_uInt8* pnCurrData = pnData;
+ sal_uInt16 nBytesLeft = nBytes;
+ while( nBytesLeft )
+ {
+ sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - GetOffset( rStrm.Tell() );
+ sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
+
+ // read the block from stream
+ nRet = nRet + static_cast< sal_uInt16 >( rStrm.Read( pnCurrData, nDecBytes ) );
+ // decode the block inplace
+ maCodec.Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
+ if( GetOffset( rStrm.Tell() ) == 0 )
+ maCodec.InitCipher( GetBlock( rStrm.Tell() ) );
+
+ pnCurrData += nDecBytes;
+ nBytesLeft = nBytesLeft - nDecBytes;
+ }
+
+ return nRet;
+}
+
+sal_uInt32 XclImpBiff8Decrypter::GetBlock( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
+}
+
+sal_uInt16 XclImpBiff8Decrypter::GetOffset( sal_Size nStrmPos ) const
+{
+ return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
+}
+
+// ============================================================================
+// Stream
+// ============================================================================
+
+XclImpStreamPos::XclImpStreamPos() :
+ mnPos( STREAM_SEEK_TO_BEGIN ),
+ mnNextPos( STREAM_SEEK_TO_BEGIN ),
+ mnCurrSize( 0 ),
+ mnRawRecId( EXC_ID_UNKNOWN ),
+ mnRawRecSize( 0 ),
+ mnRawRecLeft( 0 ),
+ mbValid( false )
+{
+}
+
+void XclImpStreamPos::Set(
+ const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
+ sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
+ bool bValid )
+{
+ mnPos = rStrm.Tell();
+ mnNextPos = nNextPos;
+ mnCurrSize = nCurrSize;
+ mnRawRecId = nRawRecId;
+ mnRawRecSize = nRawRecSize;
+ mnRawRecLeft = nRawRecLeft;
+ mbValid = bValid;
+}
+
+void XclImpStreamPos::Get(
+ SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
+ sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
+ bool& rbValid ) const
+{
+ rStrm.Seek( mnPos );
+ rnNextPos = mnNextPos;
+ rnCurrSize = mnCurrSize;
+ rnRawRecId = mnRawRecId;
+ rnRawRecSize = mnRawRecSize;
+ rnRawRecLeft = mnRawRecLeft;
+ rbValid = mbValid;
+}
+
+// ============================================================================
+
+XclBiff XclImpStream::DetectBiffVersion( SvStream& rStrm )
+{
+ XclBiff eBiff = EXC_BIFF_UNKNOWN;
+
+ rStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ sal_uInt16 nBofId, nBofSize;
+ rStrm >> nBofId >> nBofSize;
+
+ if( (4 <= nBofSize) && (nBofSize <= 16) ) switch( nBofId )
+ {
+ case EXC_ID2_BOF:
+ eBiff = EXC_BIFF2;
+ break;
+ case EXC_ID3_BOF:
+ eBiff = EXC_BIFF3;
+ break;
+ case EXC_ID4_BOF:
+ eBiff = EXC_BIFF4;
+ break;
+ case EXC_ID5_BOF:
+ {
+ sal_uInt16 nVersion;
+ rStrm >> nVersion;
+ // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
+ switch( nVersion & 0xFF00 )
+ {
+ case 0: eBiff = EXC_BIFF5; break; // #i44031# #i62752#
+ case EXC_BOF_BIFF2: eBiff = EXC_BIFF2; break;
+ case EXC_BOF_BIFF3: eBiff = EXC_BIFF3; break;
+ case EXC_BOF_BIFF4: eBiff = EXC_BIFF4; break;
+ case EXC_BOF_BIFF5: eBiff = EXC_BIFF5; break;
+ case EXC_BOF_BIFF8: eBiff = EXC_BIFF8; break;
+ default: OSL_TRACE( "XclImpStream::DetectBiffVersion - unknown BIFF version: 0x%04hX", nVersion );
+ }
+ }
+ break;
+ }
+ return eBiff;
+}
+
+XclImpStream::XclImpStream( SvStream& rInStrm, const XclImpRoot& rRoot, bool bContLookup ) :
+ mrStrm( rInStrm ),
+ mrRoot( rRoot ),
+ mnGlobRecId( EXC_ID_UNKNOWN ),
+ mbGlobValidRec( false ),
+ mbHasGlobPos( false ),
+ mnNextRecPos( STREAM_SEEK_TO_BEGIN ),
+ mnCurrRecSize( 0 ),
+ mnComplRecSize( 0 ),
+ mbHasComplRec( false ),
+ mnRecId( EXC_ID_UNKNOWN ),
+ mnAltContId( EXC_ID_UNKNOWN ),
+ mnRawRecId( EXC_ID_UNKNOWN ),
+ mnRawRecSize( 0 ),
+ mnRawRecLeft( 0 ),
+ mcNulSubst( '?' ),
+ mbCont( bContLookup ),
+ mbUseDecr( false ),
+ mbValidRec( false ),
+ mbValid( false )
+{
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ mnStreamSize = mrStrm.Tell();
+ mrStrm.Seek( STREAM_SEEK_TO_BEGIN );
+ DBG_ASSERT( mnStreamSize < STREAM_SEEK_TO_END, "XclImpStream::XclImpStream - stream error" );
+}
+
+XclImpStream::~XclImpStream()
+{
+}
+
+bool XclImpStream::StartNextRecord()
+{
+ maPosStack.clear();
+
+ /* #i4266# Counter to ignore zero records (id==len==0) (i.e. the application
+ "Crystal Report" writes zero records between other records) */
+ sal_Size nZeroRecCount = 5;
+ bool bIsZeroRec = false;
+
+ do
+ {
+ mbValidRec = ReadNextRawRecHeader();
+ bIsZeroRec = (mnRawRecId == 0) && (mnRawRecSize == 0);
+ if( bIsZeroRec ) --nZeroRecCount;
+ mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
+ }
+ while( mbValidRec && ((mbCont && IsContinueId( mnRawRecId )) || (bIsZeroRec && nZeroRecCount)) );
+
+ mbValidRec = mbValidRec && !bIsZeroRec;
+ mbValid = mbValidRec;
+ SetupRecord();
+
+ return mbValidRec;
+}
+
+bool XclImpStream::StartNextRecord( sal_Size nNextRecPos )
+{
+ mnNextRecPos = nNextRecPos;
+ return StartNextRecord();
+}
+
+void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
+{
+ if( mbValidRec )
+ {
+ maPosStack.clear();
+ RestorePosition( maFirstRec );
+ mnCurrRecSize = mnComplRecSize = mnRawRecSize;
+ mbHasComplRec = !bContLookup;
+ mbCont = bContLookup;
+ mnAltContId = nAltContId;
+ EnableDecryption();
+ }
+}
+
+void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter )
+{
+ mxDecrypter = xDecrypter;
+ EnableDecryption();
+ SetupDecrypter();
+}
+
+void XclImpStream::CopyDecrypterFrom( const XclImpStream& rStrm )
+{
+ XclImpDecrypterRef xNewDecr;
+ if( rStrm.mxDecrypter )
+ xNewDecr = rStrm.mxDecrypter->Clone();
+ SetDecrypter( xNewDecr );
+}
+
+bool XclImpStream::HasValidDecrypter() const
+{
+ return mxDecrypter && mxDecrypter->IsValid();
+}
+
+void XclImpStream::EnableDecryption( bool bEnable )
+{
+ mbUseDecr = bEnable && HasValidDecrypter();
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpStream::PushPosition()
+{
+ maPosStack.push_back( XclImpStreamPos() );
+ StorePosition( maPosStack.back() );
+}
+
+void XclImpStream::PopPosition()
+{
+ DBG_ASSERT( !maPosStack.empty(), "XclImpStream::PopPosition - stack empty" );
+ if( !maPosStack.empty() )
+ {
+ RestorePosition( maPosStack.back() );
+ maPosStack.pop_back();
+ }
+}
+
+void XclImpStream::StoreGlobalPosition()
+{
+ StorePosition( maGlobPos );
+ mnGlobRecId = mnRecId;
+ mbGlobValidRec = mbValidRec;
+ mbHasGlobPos = true;
+}
+
+void XclImpStream::SeekGlobalPosition()
+{
+ DBG_ASSERT( mbHasGlobPos, "XclImpStream::SeekGlobalPosition - no position stored" );
+ if( mbHasGlobPos )
+ {
+ RestorePosition( maGlobPos );
+ mnRecId = mnGlobRecId;
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = !mbCont;
+ mbValidRec = mbGlobValidRec;
+ }
+}
+
+sal_Size XclImpStream::GetRecPos() const
+{
+ return mbValid ? (mnCurrRecSize - mnRawRecLeft) : EXC_REC_SEEK_TO_END;
+}
+
+sal_Size XclImpStream::GetRecSize()
+{
+ if( !mbHasComplRec )
+ {
+ PushPosition();
+ while( JumpToNextContinue() ) ; // JumpToNextContinue() adds up mnCurrRecSize
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = true;
+ PopPosition();
+ }
+ return mnComplRecSize;
+}
+
+sal_Size XclImpStream::GetRecLeft()
+{
+ return mbValid ? (GetRecSize() - GetRecPos()) : 0;
+}
+
+sal_uInt16 XclImpStream::GetNextRecId()
+{
+ sal_uInt16 nRecId = EXC_ID_UNKNOWN;
+ if( mbValidRec )
+ {
+ PushPosition();
+ while( JumpToNextContinue() ) ; // skip following CONTINUE records
+ if( mnNextRecPos < mnStreamSize )
+ {
+ mrStrm.Seek( mnNextRecPos );
+ mrStrm >> nRecId;
+ }
+ PopPosition();
+ }
+ return nRecId;
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpStream& XclImpStream::operator>>( sal_Int8& rnValue )
+{
+ if( EnsureRawReadSize( 1 ) )
+ {
+ if( mbUseDecr )
+ mxDecrypter->Read( mrStrm, &rnValue, 1 );
+ else
+ mrStrm >> rnValue;
+ --mnRawRecLeft;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt8& rnValue )
+{
+ if( EnsureRawReadSize( 1 ) )
+ {
+ if( mbUseDecr )
+ mxDecrypter->Read( mrStrm, &rnValue, 1 );
+ else
+ mrStrm >> rnValue;
+ --mnRawRecLeft;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_Int16& rnValue )
+{
+ if( EnsureRawReadSize( 2 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT16 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 2 );
+ rnValue = static_cast< sal_Int16 >( SVBT16ToShort( pnBuffer ) );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 2;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt16& rnValue )
+{
+ if( EnsureRawReadSize( 2 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT16 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 2 );
+ rnValue = SVBT16ToShort( pnBuffer );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 2;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_Int32& rnValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ rnValue = static_cast< sal_Int32 >( SVBT32ToUInt32( pnBuffer ) );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( sal_uInt32& rnValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ rnValue = SVBT32ToUInt32( pnBuffer );
+ }
+ else
+ mrStrm >> rnValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( float& rfValue )
+{
+ if( EnsureRawReadSize( 4 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT32 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 4 );
+ sal_uInt32 nValue = SVBT32ToUInt32( pnBuffer );
+ memcpy( &rfValue, &nValue, 4 );
+ }
+ else
+ mrStrm >> rfValue;
+ mnRawRecLeft -= 4;
+ }
+ return *this;
+}
+
+XclImpStream& XclImpStream::operator>>( double& rfValue )
+{
+ if( EnsureRawReadSize( 8 ) )
+ {
+ if( mbUseDecr )
+ {
+ SVBT64 pnBuffer;
+ mxDecrypter->Read( mrStrm, pnBuffer, 8 );
+ rfValue = SVBT64ToDouble( pnBuffer );
+ }
+ else
+ mrStrm >> rfValue;
+ mnRawRecLeft -= 8;
+ }
+ return *this;
+}
+
+sal_uInt8 XclImpStream::ReaduInt8()
+{
+ sal_uInt8 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_Int16 XclImpStream::ReadInt16()
+{
+ sal_Int16 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_uInt16 XclImpStream::ReaduInt16()
+{
+ sal_uInt16 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_Int32 XclImpStream::ReadInt32()
+{
+ sal_Int32 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+sal_uInt32 XclImpStream::ReaduInt32()
+{
+ sal_uInt32 nValue(0);
+ operator>>( nValue );
+ return nValue;
+}
+
+double XclImpStream::ReadDouble()
+{
+ double fValue(0.0);
+ operator>>( fValue );
+ return fValue;
+}
+
+sal_Size XclImpStream::Read( void* pData, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( mbValid && pData && (nBytes > 0) )
+ {
+ sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( pData );
+ sal_Size nBytesLeft = nBytes;
+
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
+ sal_uInt16 nReadRet = ReadRawData( pnBuffer, nReadSize );
+ nRet += nReadRet;
+ mbValid = (nReadSize == nReadRet);
+ DBG_ASSERT( mbValid, "XclImpStream::Read - stream read error" );
+ pnBuffer += nReadRet;
+ nBytesLeft -= nReadRet;
+ if( mbValid && (nBytesLeft > 0) )
+ JumpToNextContinue();
+ DBG_ASSERT( mbValid, "XclImpStream::Read - record overread" );
+ }
+ }
+ return nRet;
+}
+
+sal_Size XclImpStream::CopyToStream( SvStream& rOutStrm, sal_Size nBytes )
+{
+ sal_Size nRet = 0;
+ if( mbValid && (nBytes > 0) )
+ {
+ const sal_Size nMaxBuffer = 4096;
+ sal_uInt8* pnBuffer = new sal_uInt8[ ::std::min( nBytes, nMaxBuffer ) ];
+ sal_Size nBytesLeft = nBytes;
+
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_Size nReadSize = ::std::min( nBytesLeft, nMaxBuffer );
+ nRet += Read( pnBuffer, nReadSize );
+ rOutStrm.Write( pnBuffer, nReadSize );
+ nBytesLeft -= nReadSize;
+ }
+
+ delete[] pnBuffer;
+ }
+ return nRet;
+}
+
+sal_Size XclImpStream::CopyRecordToStream( SvStream& rOutStrm )
+{
+ sal_Size nRet = 0;
+ if( mbValidRec )
+ {
+ PushPosition();
+ RestorePosition( maFirstRec );
+ nRet = CopyToStream( rOutStrm, GetRecSize() );
+ PopPosition();
+ }
+ return nRet;
+}
+
+void XclImpStream::Seek( sal_Size nPos )
+{
+ if( mbValidRec )
+ {
+ sal_Size nCurrPos = GetRecPos();
+ if( !mbValid || (nPos < nCurrPos) ) // from invalid state or backward
+ {
+ RestorePosition( maFirstRec );
+ Ignore( nPos );
+ }
+ else if( nPos > nCurrPos ) // forward
+ {
+ Ignore( nPos - nCurrPos );
+ }
+ }
+}
+
+void XclImpStream::Ignore( sal_Size nBytes )
+{
+ // implementation similar to Read(), but without really reading anything
+ sal_Size nBytesLeft = nBytes;
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
+ mrStrm.SeekRel( nReadSize );
+ mnRawRecLeft = mnRawRecLeft - nReadSize;
+ nBytesLeft -= nReadSize;
+ if( nBytesLeft > 0 )
+ JumpToNextContinue();
+ DBG_ASSERT( mbValid, "XclImpStream::Ignore - record overread" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sal_Size XclImpStream::ReadUniStringExtHeader(
+ bool& rb16Bit, bool& rbRich, bool& rbFareast,
+ sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags )
+{
+ DBG_ASSERT( !::get_flag( nFlags, EXC_STRF_UNKNOWN ), "XclImpStream::ReadUniStringExt - unknown flags" );
+ rb16Bit = ::get_flag( nFlags, EXC_STRF_16BIT );
+ rbRich = ::get_flag( nFlags, EXC_STRF_RICH );
+ rbFareast = ::get_flag( nFlags, EXC_STRF_FAREAST );
+ rnFormatRuns = rbRich ? ReaduInt16() : 0;
+ rnExtInf = rbFareast ? ReaduInt32() : 0;
+ return rnExtInf + 4 * rnFormatRuns;
+}
+
+sal_Size XclImpStream::ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags )
+{
+ bool bRich, bFareast;
+ sal_uInt16 nCrun;
+ sal_uInt32 nExtInf;
+ return ReadUniStringExtHeader( rb16Bit, bRich, bFareast, nCrun, nExtInf, nFlags );
+}
+
+// ----------------------------------------------------------------------------
+
+String XclImpStream::ReadRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ String aRet;
+ sal_uInt16 nCharsLeft = nChars;
+ sal_uInt16 nReadSize;
+
+ sal_Unicode* pcBuffer = new sal_Unicode[ nCharsLeft + 1 ];
+
+ while( IsValid() && (nCharsLeft > 0) )
+ {
+ if( b16Bit )
+ {
+ nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
+ DBG_ASSERT( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
+ "XclImpStream::ReadRawUniString - missing a byte" );
+ }
+ else
+ nReadSize = GetMaxRawReadSize( nCharsLeft );
+
+ sal_Unicode* pcUniChar = pcBuffer;
+ sal_Unicode* pcEndChar = pcBuffer + nReadSize;
+
+ if( b16Bit )
+ {
+ sal_uInt16 nReadChar;
+ for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
+ {
+ operator>>( nReadChar );
+ (*pcUniChar) = (nReadChar == EXC_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+ }
+ }
+ else
+ {
+ sal_uInt8 nReadChar;
+ for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
+ {
+ operator>>( nReadChar );
+ (*pcUniChar) = (nReadChar == EXC_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
+ }
+ }
+
+ *pcEndChar = '\0';
+ aRet.Append( pcBuffer );
+
+ nCharsLeft = nCharsLeft - nReadSize;
+ if( nCharsLeft > 0 )
+ JumpToNextStringContinue( b16Bit );
+ }
+
+ delete[] pcBuffer;
+ return aRet;
+}
+
+String XclImpStream::ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
+ String aRet( ReadRawUniString( nChars, b16Bit ) );
+ Ignore( nExtSize );
+ return aRet;
+}
+
+String XclImpStream::ReadUniString( sal_uInt16 nChars )
+{
+ return ReadUniString( nChars, ReaduInt8() );
+}
+
+String XclImpStream::ReadUniString()
+{
+ return ReadUniString( ReaduInt16() );
+}
+
+void XclImpStream::IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ sal_uInt16 nCharsLeft = nChars;
+ sal_uInt16 nReadSize;
+
+ while( IsValid() && (nCharsLeft > 0) )
+ {
+ if( b16Bit )
+ {
+ nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
+ DBG_ASSERT( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
+ "XclImpStream::IgnoreRawUniString - missing a byte" );
+ Ignore( nReadSize * 2 );
+ }
+ else
+ {
+ nReadSize = GetMaxRawReadSize( nCharsLeft );
+ Ignore( nReadSize );
+ }
+
+ nCharsLeft = nCharsLeft - nReadSize;
+ if( nCharsLeft > 0 )
+ JumpToNextStringContinue( b16Bit );
+ }
+}
+
+void XclImpStream::IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
+ IgnoreRawUniString( nChars, b16Bit );
+ Ignore( nExtSize );
+}
+
+void XclImpStream::IgnoreUniString( sal_uInt16 nChars )
+{
+ IgnoreUniString( nChars, ReaduInt8() );
+}
+
+// ----------------------------------------------------------------------------
+
+String XclImpStream::ReadRawByteString( sal_uInt16 nChars )
+{
+ sal_Char* pcBuffer = new sal_Char[ nChars + 1 ];
+ sal_uInt16 nCharsRead = ReadRawData( pcBuffer, nChars );
+ pcBuffer[ nCharsRead ] = '\0';
+ String aRet( pcBuffer, mrRoot.GetTextEncoding() );
+ delete[] pcBuffer;
+ return aRet;
+}
+
+String XclImpStream::ReadByteString( bool b16BitLen )
+{
+ return ReadRawByteString( ReadByteStrLen( b16BitLen ) );
+}
+
+// private --------------------------------------------------------------------
+
+void XclImpStream::StorePosition( XclImpStreamPos& rPos )
+{
+ rPos.Set( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
+}
+
+void XclImpStream::RestorePosition( const XclImpStreamPos& rPos )
+{
+ rPos.Get( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
+ SetupDecrypter();
+}
+
+bool XclImpStream::ReadNextRawRecHeader()
+{
+ mrStrm.Seek( mnNextRecPos );
+ bool bRet = mnNextRecPos + 4 <= mnStreamSize;
+ if( bRet )
+ mrStrm >> mnRawRecId >> mnRawRecSize;
+ return bRet;
+}
+
+void XclImpStream::SetupDecrypter()
+{
+ if( mxDecrypter )
+ mxDecrypter->Update( mrStrm, mnRawRecSize );
+}
+
+void XclImpStream::SetupRawRecord()
+{
+ // pre: mnRawRecSize contains current raw record size
+ // pre: mrStrm points to start of raw record data
+ mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
+ mnRawRecLeft = mnRawRecSize;
+ mnCurrRecSize += mnRawRecSize;
+ SetupDecrypter(); // decrypter works on raw record level
+}
+
+void XclImpStream::SetupRecord()
+{
+ mnRecId = mnRawRecId;
+ mnAltContId = EXC_ID_UNKNOWN;
+ mnCurrRecSize = 0;
+ mnComplRecSize = mnRawRecSize;
+ mbHasComplRec = !mbCont;
+ SetupRawRecord();
+ SetNulSubstChar();
+ EnableDecryption();
+ StorePosition( maFirstRec );
+}
+
+bool XclImpStream::IsContinueId( sal_uInt16 nRecId ) const
+{
+ return (nRecId == EXC_ID_CONT) || (nRecId == mnAltContId);
+}
+
+bool XclImpStream::JumpToNextContinue()
+{
+ mbValid = mbValid && mbCont && ReadNextRawRecHeader() && IsContinueId( mnRawRecId );
+ if( mbValid ) // do not setup a following non-CONTINUE record
+ SetupRawRecord();
+ return mbValid;
+}
+
+bool XclImpStream::JumpToNextStringContinue( bool& rb16Bit )
+{
+ DBG_ASSERT( mnRawRecLeft == 0, "XclImpStream::JumpToNextStringContinue - unexpected garbage" );
+
+ if( mbCont && (GetRecLeft() > 0) )
+ {
+ JumpToNextContinue();
+ }
+ else if( mnRecId == EXC_ID_CONT )
+ {
+ // CONTINUE handling is off, but we have started reading in a CONTINUE record
+ // -> start next CONTINUE for TXO import
+ mbValidRec = ReadNextRawRecHeader() && ((mnRawRecId != 0) || (mnRawRecSize > 0));
+ mbValid = mbValidRec && (mnRawRecId == EXC_ID_CONT);
+ // we really start a new record here - no chance to return to string origin
+ if( mbValid )
+ SetupRecord();
+ }
+ else
+ mbValid = false;
+
+ if( mbValid )
+ rb16Bit = ::get_flag( ReaduInt8(), EXC_STRF_16BIT );
+ return mbValid;
+}
+
+bool XclImpStream::EnsureRawReadSize( sal_uInt16 nBytes )
+{
+ if( mbValid && nBytes )
+ {
+ while( mbValid && !mnRawRecLeft ) JumpToNextContinue();
+ mbValid = mbValid && (nBytes <= mnRawRecLeft);
+ DBG_ASSERT( mbValid, "XclImpStream::EnsureRawReadSize - record overread" );
+ }
+ return mbValid;
+}
+
+sal_uInt16 XclImpStream::GetMaxRawReadSize( sal_Size nBytes ) const
+{
+ return static_cast< sal_uInt16 >( ::std::min< sal_Size >( nBytes, mnRawRecLeft ) );
+}
+
+sal_uInt16 XclImpStream::ReadRawData( void* pData, sal_uInt16 nBytes )
+{
+ DBG_ASSERT( (nBytes <= mnRawRecLeft), "XclImpStream::ReadRawData - record overread" );
+ sal_uInt16 nRet = 0;
+ if( mbUseDecr )
+ nRet = mxDecrypter->Read( mrStrm, pData, nBytes );
+ else
+ nRet = static_cast< sal_uInt16 >( mrStrm.Read( pData, nBytes ) );
+ mnRawRecLeft = mnRawRecLeft - nRet;
+ return nRet;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xistring.cxx b/sc/source/filter/excel/xistring.cxx
new file mode 100644
index 000000000000..c50b0605e3ee
--- /dev/null
+++ b/sc/source/filter/excel/xistring.cxx
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sc.hxx"
+#include "xistring.hxx"
+#include "xlstyle.hxx"
+#include "xistream.hxx"
+#include "xiroot.hxx"
+
+// Byte/Unicode strings =======================================================
+
+/** All allowed flags for import. */
+const XclStrFlags nAllowedFlags = EXC_STR_8BITLENGTH | EXC_STR_SMARTFLAGS | EXC_STR_SEPARATEFORMATS;
+
+// ----------------------------------------------------------------------------
+
+XclImpString::XclImpString()
+{
+}
+
+XclImpString::XclImpString( const String& rString ) :
+ maString( rString )
+{
+}
+
+XclImpString::~XclImpString()
+{
+}
+
+void XclImpString::Read( XclImpStream& rStrm, XclStrFlags nFlags )
+{
+ if( !::get_flag( nFlags, EXC_STR_SEPARATEFORMATS ) )
+ maFormats.clear();
+
+ DBG_ASSERT( (nFlags & ~nAllowedFlags) == 0, "XclImpString::Read - unknown flag" );
+ bool b16BitLen = !::get_flag( nFlags, EXC_STR_8BITLENGTH );
+
+ switch( rStrm.GetRoot().GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ // no integrated formatting in BIFF2-BIFF7
+ maString = rStrm.ReadByteString( b16BitLen );
+ break;
+
+ case EXC_BIFF8:
+ {
+ // --- string header ---
+ sal_uInt16 nChars = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
+ sal_uInt8 nFlagField = 0;
+ if( nChars || !::get_flag( nFlags, EXC_STR_SMARTFLAGS ) )
+ rStrm >> nFlagField;
+
+ bool b16Bit, bRich, bFarEast;
+ sal_uInt16 nRunCount;
+ sal_uInt32 nExtInf;
+ rStrm.ReadUniStringExtHeader( b16Bit, bRich, bFarEast, nRunCount, nExtInf, nFlagField );
+ // ignore the flags, they may be wrong
+
+ // --- character array ---
+ maString = rStrm.ReadRawUniString( nChars, b16Bit );
+
+ // --- formatting ---
+ if( nRunCount > 0 )
+ ReadFormats( rStrm, nRunCount );
+
+ // --- extended (FarEast) information ---
+ rStrm.Ignore( nExtInf );
+ }
+ break;
+
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+void XclImpString::AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx )
+{
+ // #i33341# real life -- same character index may occur several times
+ DBG_ASSERT( rFormats.empty() || (rFormats.back().mnChar <= nChar), "XclImpString::AppendFormat - wrong char order" );
+ if( rFormats.empty() || (rFormats.back().mnChar < nChar) )
+ rFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
+ else
+ rFormats.back().mnFontIdx = nFontIdx;
+}
+
+void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats )
+{
+ bool bBiff8 = rStrm.GetRoot().GetBiff() == EXC_BIFF8;
+ sal_uInt16 nRunCount = bBiff8 ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
+ ReadFormats( rStrm, rFormats, nRunCount );
+}
+
+void XclImpString::ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount )
+{
+ rFormats.clear();
+ rFormats.reserve( nRunCount );
+ /* #i33341# real life -- same character index may occur several times
+ -> use AppendFormat() to validate formats */
+ if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt16 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+ }
+ else
+ {
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt8 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+ }
+}
+
+void XclImpString::ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize )
+{
+ // number of formatting runs, each takes 8 bytes
+ sal_uInt16 nRunCount = nFormatSize / 8;
+ rFormats.clear();
+ rFormats.reserve( nRunCount );
+ for( sal_uInt16 nIdx = 0; nIdx < nRunCount; ++nIdx )
+ {
+ sal_uInt16 nChar, nFontIdx;
+ rStrm >> nChar >> nFontIdx;
+ rStrm.Ignore( 4 );
+ AppendFormat( rFormats, nChar, nFontIdx );
+ }
+}
+
+// String iterator ============================================================
+
+XclImpStringIterator::XclImpStringIterator( const XclImpString& rString ) :
+ mrText( rString.GetText() ),
+ mrFormats( rString.GetFormats() ),
+ mnPortion( 0 ),
+ mnTextBeg( 0 ),
+ mnTextEnd( 0 ),
+ mnFormatsBeg( 0 ),
+ mnFormatsEnd( 0 )
+{
+ // first portion is formatted, adjust vector index to next portion
+ if( !mrFormats.empty() && (mrFormats.front().mnChar == 0) )
+ ++mnFormatsEnd;
+ // find end position of the first portion
+ mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
+ mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
+}
+
+String XclImpStringIterator::GetPortionText() const
+{
+ return String( mrText, mnTextBeg, mnTextEnd - mnTextBeg );
+}
+
+sal_uInt16 XclImpStringIterator::GetPortionFont() const
+{
+ return (mnFormatsBeg < mnFormatsEnd) ? mrFormats[ mnFormatsBeg ].mnFontIdx : EXC_FONT_NOTFOUND;
+}
+
+XclImpStringIterator& XclImpStringIterator::operator++()
+{
+ if( Is() )
+ {
+ ++mnPortion;
+ do
+ {
+ // indexes into vector of formatting runs
+ if( mnFormatsBeg < mnFormatsEnd )
+ ++mnFormatsBeg;
+ if( mnFormatsEnd < mrFormats.size() )
+ ++mnFormatsEnd;
+ // character positions of next portion
+ mnTextBeg = mnTextEnd;
+ mnTextEnd = static_cast< xub_StrLen >( (mnFormatsEnd < mrFormats.size()) ?
+ mrFormats[ mnFormatsEnd ].mnChar : mrText.Len() );
+ }
+ while( Is() && (mnTextBeg == mnTextEnd) );
+ }
+ return *this;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
new file mode 100644
index 000000000000..1f6e680897b5
--- /dev/null
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -0,0 +1,2000 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xistyle.hxx"
+#include <sfx2/printer.hxx>
+#include <sfx2/objsh.hxx>
+#include <svtools/ctrltool.hxx>
+#include <editeng/editobj.hxx>
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escpitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <sal/macros.h>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "attarray.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+#include "xicontent.hxx"
+
+#include "root.hxx"
+#include "colrowst.hxx"
+#include "svl/poolcach.hxx"
+
+#include <list>
+
+using ::std::list;
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+using namespace ::com::sun::star;
+
+typedef ::cppu::WeakImplHelper1< container::XIndexAccess > XIndexAccess_BASE;
+typedef ::std::vector< ColorData > ColorDataVec;
+
+class PaletteIndex : public XIndexAccess_BASE
+{
+public:
+ PaletteIndex( const ColorDataVec& rColorDataTable ) : maColorData( rColorDataTable ) {}
+
+ // Methods XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException)
+ {
+ return maColorData.size();
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ //--Index; // apparently the palette is already 1 based
+ return uno::makeAny( sal_Int32( maColorData[ Index ] ) );
+ }
+
+ // Methods XElementAcess
+ virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
+ {
+ return ::getCppuType( (sal_Int32*)0 );
+ }
+ virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException)
+ {
+ return (maColorData.size() > 0);
+ }
+
+private:
+ ColorDataVec maColorData;
+};
+
+void
+XclImpPalette::ExportPalette()
+{
+ if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
+ {
+ // copy values in color palette
+ sal_Int16 nColors = maColorTable.size();
+ ColorDataVec aColors;
+ aColors.resize( nColors );
+ for( sal_uInt16 nIndex = 0; nIndex < nColors; ++nIndex )
+ aColors[ nIndex ] = GetColorData( nIndex );
+
+ uno::Reference< beans::XPropertySet > xProps( pDocShell->GetModel(), uno::UNO_QUERY );
+ if ( xProps.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndex( new PaletteIndex( aColors ) );
+ xProps->setPropertyValue( CREATE_OUSTRING("ColorPalette"), uno::makeAny( xIndex ) );
+ }
+ }
+
+}
+// PALETTE record - color information =========================================
+
+XclImpPalette::XclImpPalette( const XclImpRoot& rRoot ) :
+ XclDefaultPalette( rRoot ), mrRoot( rRoot )
+{
+}
+
+void XclImpPalette::Initialize()
+{
+ maColorTable.clear();
+}
+
+ColorData XclImpPalette::GetColorData( sal_uInt16 nXclIndex ) const
+{
+ if( nXclIndex >= EXC_COLOR_USEROFFSET )
+ {
+ sal_uInt32 nIx = nXclIndex - EXC_COLOR_USEROFFSET;
+ if( nIx < maColorTable.size() )
+ return maColorTable[ nIx ];
+ }
+ return GetDefColorData( nXclIndex );
+}
+
+::com::sun::star::uno::Sequence< sal_Int32 > XclImpPalette::CreateColorSequence() const
+{
+ sal_Int32 nCount = static_cast< sal_Int32 >( maColorTable.size() );
+ ::com::sun::star::uno::Sequence< sal_Int32 > aSeq( nCount );
+ if( nCount > 0 )
+ {
+ sal_Int32* pnSeqColor = aSeq.getArray();
+ for( ColorDataVec::const_iterator aIt = maColorTable.begin(), aEnd = maColorTable.end(); aIt != aEnd; ++aIt, ++pnSeqColor )
+ *pnSeqColor = static_cast< sal_Int32 >( *aIt );
+ }
+ return aSeq;
+}
+
+void XclImpPalette::ReadPalette( XclImpStream& rStrm )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ DBG_ASSERT( rStrm.GetRecLeft() == static_cast< sal_Size >( 4 * nCount ),
+ "XclImpPalette::ReadPalette - size mismatch" );
+
+ maColorTable.resize( nCount );
+ Color aColor;
+ for( sal_uInt16 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ rStrm >> aColor;
+ maColorTable[ nIndex ] = aColor.GetColor();
+ }
+ ExportPalette();
+}
+
+// FONT record - font information =============================================
+
+XclImpFont::XclImpFont( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mbHasCharSet( false ),
+ mbHasWstrn( true ),
+ mbHasAsian( false ),
+ mbHasCmplx( false )
+{
+ SetAllUsedFlags( false );
+}
+
+XclImpFont::XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData ) :
+ XclImpRoot( rRoot )
+{
+ SetFontData( rFontData, false );
+}
+
+void XclImpFont::SetAllUsedFlags( bool bUsed )
+{
+ mbFontNameUsed = mbHeightUsed = mbColorUsed = mbWeightUsed = mbEscapemUsed =
+ mbUnderlUsed = mbItalicUsed = mbStrikeUsed = mbOutlineUsed = mbShadowUsed = bUsed;
+}
+
+void XclImpFont::SetFontData( const XclFontData& rFontData, bool bHasCharSet )
+{
+ maData = rFontData;
+ mbHasCharSet = bHasCharSet;
+ if( maData.maStyle.Len() )
+ {
+ if( SfxObjectShell* pDocShell = GetDocShell() )
+ {
+ if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
+ pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
+ {
+ if( const FontList* pFontList = pInfoItem->GetFontList() )
+ {
+ FontInfo aFontInfo( pFontList->Get( maData.maName, maData.maStyle ) );
+ maData.SetScWeight( aFontInfo.GetWeight() );
+ maData.SetScPosture( aFontInfo.GetItalic() );
+ }
+ }
+ }
+ maData.maStyle.Erase();
+ }
+ GuessScriptType();
+ SetAllUsedFlags( true );
+}
+
+rtl_TextEncoding XclImpFont::GetFontEncoding() const
+{
+ // #i63105# use text encoding from FONT record
+ // #i67768# BIFF2-BIFF4 FONT records do not contain character set
+ rtl_TextEncoding eFontEnc = mbHasCharSet ? maData.GetFontEncoding() : GetTextEncoding();
+ return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? GetTextEncoding() : eFontEnc;
+}
+
+void XclImpFont::ReadFont( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ ReadFontData2( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ ReadFontData2( rStrm );
+ ReadFontColor( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF5:
+ ReadFontData5( rStrm );
+ ReadFontName2( rStrm );
+ break;
+ case EXC_BIFF8:
+ ReadFontData5( rStrm );
+ ReadFontName8( rStrm );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ return;
+ }
+ GuessScriptType();
+ SetAllUsedFlags( true );
+}
+
+void XclImpFont::ReadEfont( XclImpStream& rStrm )
+{
+ ReadFontColor( rStrm );
+}
+
+void XclImpFont::ReadCFFontBlock( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
+ if( GetBiff() != EXC_BIFF8 )
+ return;
+
+ sal_uInt32 nHeight, nStyle, nColor, nFontFlags1, nFontFlags2, nFontFlags3;
+ sal_uInt16 nWeight, nEscapem;
+ sal_uInt8 nUnderl;
+
+ rStrm.Ignore( 64 );
+ rStrm >> nHeight >> nStyle >> nWeight >> nEscapem >> nUnderl;
+ rStrm.Ignore( 3 );
+ rStrm >> nColor;
+ rStrm.Ignore( 4 );
+ rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3;
+ rStrm.Ignore( 18 );
+
+ if( (mbHeightUsed = (nHeight <= 0x7FFF)) == true )
+ maData.mnHeight = static_cast< sal_uInt16 >( nHeight );
+ if( (mbWeightUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE ) && (nWeight < 0x7FFF)) == true )
+ maData.mnWeight = static_cast< sal_uInt16 >( nWeight );
+ if( (mbItalicUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE )) == true )
+ maData.mbItalic = ::get_flag( nStyle, EXC_CF_FONT_STYLE );
+ if( (mbUnderlUsed = !::get_flag( nFontFlags3, EXC_CF_FONT_UNDERL ) && (nUnderl <= 0x7F)) == true )
+ maData.mnUnderline = nUnderl;
+ if( (mbColorUsed = (nColor <= 0x7FFF)) == true )
+ maData.maColor = GetPalette().GetColor( static_cast< sal_uInt16 >( nColor ) );
+ if( (mbStrikeUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT )) == true )
+ maData.mbStrikeout = ::get_flag( nStyle, EXC_CF_FONT_STRIKEOUT );
+}
+
+void XclImpFont::FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType, bool bSkipPoolDefs ) const
+{
+ // true = edit engine Which-IDs (EE_CHAR_*); false = Calc Which-IDs (ATTR_*)
+ bool bEE = eType != EXC_FONTITEM_CELL;
+
+// item = the item to put into the item set
+// sc_which = the Calc Which-ID of the item
+// ee_which = the edit engine Which-ID of the item
+#define PUTITEM( item, sc_which, ee_which ) \
+ ScfTools::PutItem( rItemSet, item, (bEE ? (ee_which) : (sc_which)), bSkipPoolDefs )
+
+// Font item
+ // #i36997# do not set default Tahoma font from notes
+ bool bDefNoteFont = (eType == EXC_FONTITEM_NOTE) && (maData.maName.EqualsIgnoreCaseAscii( "Tahoma" ));
+ if( mbFontNameUsed && !bDefNoteFont )
+ {
+ rtl_TextEncoding eFontEnc = maData.GetFontEncoding();
+ rtl_TextEncoding eTempTextEnc = (bEE && (eFontEnc == GetTextEncoding())) ?
+ ScfTools::GetSystemTextEncoding() : eFontEnc;
+
+ SvxFontItem aFontItem( maData.GetScFamily( GetTextEncoding() ), maData.maName, EMPTY_STRING,
+ PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
+ // set only for valid script types
+ if( mbHasWstrn )
+ PUTITEM( aFontItem, ATTR_FONT, EE_CHAR_FONTINFO );
+ if( mbHasAsian )
+ PUTITEM( aFontItem, ATTR_CJK_FONT, EE_CHAR_FONTINFO_CJK );
+ if( mbHasCmplx )
+ PUTITEM( aFontItem, ATTR_CTL_FONT, EE_CHAR_FONTINFO_CTL );
+ }
+
+// Font height (for all script types)
+ if( mbHeightUsed )
+ {
+ sal_Int32 nHeight = maData.mnHeight;
+ if( bEE && (eType != EXC_FONTITEM_HF) ) // do not convert header/footer height
+ nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH; // 1 in == 72 pt
+
+ SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
+ PUTITEM( aHeightItem, ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT );
+ PUTITEM( aHeightItem, ATTR_CJK_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CJK );
+ PUTITEM( aHeightItem, ATTR_CTL_FONT_HEIGHT, EE_CHAR_FONTHEIGHT_CTL );
+ }
+
+// Font color - pass AUTO_COL to item
+ if( mbColorUsed )
+ PUTITEM( SvxColorItem( maData.maColor, ATTR_FONT_COLOR ), ATTR_FONT_COLOR, EE_CHAR_COLOR );
+
+// Font weight (for all script types)
+ if( mbWeightUsed )
+ {
+ SvxWeightItem aWeightItem( maData.GetScWeight(), ATTR_FONT_WEIGHT );
+ PUTITEM( aWeightItem, ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT );
+ PUTITEM( aWeightItem, ATTR_CJK_FONT_WEIGHT, EE_CHAR_WEIGHT_CJK );
+ PUTITEM( aWeightItem, ATTR_CTL_FONT_WEIGHT, EE_CHAR_WEIGHT_CTL );
+ }
+
+// Font underline
+ if( mbUnderlUsed )
+ {
+ SvxUnderlineItem aUnderlItem( maData.GetScUnderline(), ATTR_FONT_UNDERLINE );
+ PUTITEM( aUnderlItem, ATTR_FONT_UNDERLINE, EE_CHAR_UNDERLINE );
+ }
+
+// Font posture (for all script types)
+ if( mbItalicUsed )
+ {
+ SvxPostureItem aPostItem( maData.GetScPosture(), ATTR_FONT_POSTURE );
+ PUTITEM( aPostItem, ATTR_FONT_POSTURE, EE_CHAR_ITALIC );
+ PUTITEM( aPostItem, ATTR_CJK_FONT_POSTURE, EE_CHAR_ITALIC_CJK );
+ PUTITEM( aPostItem, ATTR_CTL_FONT_POSTURE, EE_CHAR_ITALIC_CTL );
+ }
+
+// Boolean attributes crossed out, contoured, shadowed
+ if( mbStrikeUsed )
+ PUTITEM( SvxCrossedOutItem( maData.GetScStrikeout(), ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, EE_CHAR_STRIKEOUT );
+ if( mbOutlineUsed )
+ PUTITEM( SvxContourItem( maData.mbOutline, ATTR_FONT_CONTOUR ), ATTR_FONT_CONTOUR, EE_CHAR_OUTLINE );
+ if( mbShadowUsed )
+ PUTITEM( SvxShadowedItem( maData.mbShadow, ATTR_FONT_SHADOWED ), ATTR_FONT_SHADOWED, EE_CHAR_SHADOW );
+
+// Super-/subscript: only on edit engine objects
+ if( mbEscapemUsed && bEE )
+ rItemSet.Put( SvxEscapementItem( maData.GetScEscapement(), EE_CHAR_ESCAPEMENT ) );
+
+#undef PUTITEM
+}
+
+void XclImpFont::WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, const Color* pFontColor ) const
+{
+ GetFontPropSetHelper().WriteFontProperties(
+ rPropSet, eType, maData, mbHasWstrn, mbHasAsian, mbHasCmplx, pFontColor );
+}
+
+void XclImpFont::ReadFontData2( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> maData.mnHeight >> nFlags;
+
+ maData.mnWeight = ::get_flagvalue( nFlags, EXC_FONTATTR_BOLD, EXC_FONTWGHT_BOLD, EXC_FONTWGHT_NORMAL );
+ maData.mnUnderline = ::get_flagvalue( nFlags, EXC_FONTATTR_UNDERLINE, EXC_FONTUNDERL_SINGLE, EXC_FONTUNDERL_NONE );
+ maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
+ maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
+ maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
+ maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
+ mbHasCharSet = false;
+}
+
+void XclImpFont::ReadFontData5( XclImpStream& rStrm )
+{
+ sal_uInt16 nFlags;
+
+ rStrm >> maData.mnHeight >> nFlags;
+ ReadFontColor( rStrm );
+ rStrm >> maData.mnWeight >> maData.mnEscapem >> maData.mnUnderline >> maData.mnFamily >> maData.mnCharSet;
+ rStrm.Ignore( 1 );
+
+ maData.mbItalic = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
+ maData.mbStrikeout = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
+ maData.mbOutline = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
+ maData.mbShadow = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
+ mbHasCharSet = true;
+}
+
+void XclImpFont::ReadFontColor( XclImpStream& rStrm )
+{
+ maData.maColor = GetPalette().GetColor( rStrm.ReaduInt16() );
+}
+
+void XclImpFont::ReadFontName2( XclImpStream& rStrm )
+{
+ maData.maName = rStrm.ReadByteString( false );
+}
+
+void XclImpFont::ReadFontName8( XclImpStream& rStrm )
+{
+ maData.maName = rStrm.ReadUniString( rStrm.ReaduInt8() );
+}
+
+void XclImpFont::GuessScriptType()
+{
+ mbHasWstrn = true;
+ mbHasAsian = mbHasCmplx = false;
+
+ // find the script types for which the font contains characters
+ if( OutputDevice* pPrinter = GetPrinter() )
+ {
+ Font aFont( maData.maName, Size( 0, 10 ) );
+ FontCharMap aCharMap;
+
+ pPrinter->SetFont( aFont );
+ if( pPrinter->GetFontCharMap( aCharMap ) )
+ {
+ // CJK fonts
+ mbHasAsian =
+ aCharMap.HasChar( 0x3041 ) || // 3040-309F: Hiragana
+ aCharMap.HasChar( 0x30A1 ) || // 30A0-30FF: Katakana
+ aCharMap.HasChar( 0x3111 ) || // 3100-312F: Bopomofo
+ aCharMap.HasChar( 0x3131 ) || // 3130-318F: Hangul Compatibility Jamo
+ aCharMap.HasChar( 0x3301 ) || // 3300-33FF: CJK Compatibility
+ aCharMap.HasChar( 0x3401 ) || // 3400-4DBF: CJK Unified Ideographs Extension A
+ aCharMap.HasChar( 0x4E01 ) || // 4E00-9FAF: CJK Unified Ideographs
+ aCharMap.HasChar( 0x7E01 ) || // 4E00-9FAF: CJK unified ideographs
+ aCharMap.HasChar( 0xA001 ) || // A001-A48F: Yi Syllables
+ aCharMap.HasChar( 0xAC01 ) || // AC00-D7AF: Hangul Syllables
+ aCharMap.HasChar( 0xCC01 ) || // AC00-D7AF: Hangul Syllables
+ aCharMap.HasChar( 0xF901 ) || // F900-FAFF: CJK Compatibility Ideographs
+ aCharMap.HasChar( 0xFF71 ); // FF00-FFEF: Halfwidth/Fullwidth Forms
+ // CTL fonts
+ mbHasCmplx =
+ aCharMap.HasChar( 0x05D1 ) || // 0590-05FF: Hebrew
+ aCharMap.HasChar( 0x0631 ) || // 0600-06FF: Arabic
+ aCharMap.HasChar( 0x0721 ) || // 0700-074F: Syriac
+ aCharMap.HasChar( 0x0911 ) || // 0900-0DFF: Indic scripts
+ aCharMap.HasChar( 0x0E01 ) || // 0E00-0E7F: Thai
+ aCharMap.HasChar( 0xFB21 ) || // FB1D-FB4F: Hebrew Presentation Forms
+ aCharMap.HasChar( 0xFB51 ) || // FB50-FDFF: Arabic Presentation Forms-A
+ aCharMap.HasChar( 0xFE71 ); // FE70-FEFF: Arabic Presentation Forms-B
+ // Western fonts
+ mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || aCharMap.HasChar( 'A' );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpFontBuffer::XclImpFontBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ maFont4( rRoot ),
+ maCtrlFont( rRoot )
+{
+ Initialize();
+
+ // default font for form controls without own font information
+ XclFontData aCtrlFontData;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ aCtrlFontData.maName.AssignAscii( "Helv" );
+ aCtrlFontData.mnHeight = 160;
+ aCtrlFontData.mnWeight = EXC_FONTWGHT_BOLD;
+ break;
+ case EXC_BIFF8:
+ aCtrlFontData.maName.AssignAscii( "Tahoma" );
+ aCtrlFontData.mnHeight = 160;
+ aCtrlFontData.mnWeight = EXC_FONTWGHT_NORMAL;
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+ maCtrlFont.SetFontData( aCtrlFontData, false );
+}
+
+void XclImpFontBuffer::Initialize()
+{
+ maFontList.clear();
+
+ // application font for column width calculation, later filled with first font from font list
+ XclFontData aAppFontData;
+ aAppFontData.maName.AssignAscii( "Arial" );
+ aAppFontData.mnHeight = 200;
+ aAppFontData.mnWeight = EXC_FONTWGHT_NORMAL;
+ UpdateAppFont( aAppFontData, false );
+}
+
+const XclImpFont* XclImpFontBuffer::GetFont( sal_uInt16 nFontIndex ) const
+{
+ /* Font with index 4 is not stored in an Excel file, but used e.g. by
+ BIFF5 form pushbutton objects. It is the bold default font.
+ This also means that entries above 4 are out by one in the list. */
+
+ if (nFontIndex == 4)
+ return &maFont4;
+
+ if (nFontIndex < 4)
+ {
+ // Font ID is zero-based when it's less than 4.
+ return nFontIndex >= maFontList.size() ? NULL : &maFontList[nFontIndex];
+ }
+
+ // Font ID is greater than 4. It is now 1-based.
+ return nFontIndex > maFontList.size() ? NULL : &maFontList[nFontIndex-1];
+}
+
+void XclImpFontBuffer::ReadFont( XclImpStream& rStrm )
+{
+ XclImpFont* pFont = new XclImpFont( GetRoot() );
+ pFont->ReadFont( rStrm );
+ maFontList.push_back( pFont );
+
+ if( maFontList.size() == 1 )
+ {
+ UpdateAppFont( pFont->GetFontData(), pFont->HasCharSet() );
+ // #i71033# set text encoding from application font, if CODEPAGE is missing
+ SetAppFontEncoding( pFont->GetFontEncoding() );
+ }
+}
+
+void XclImpFontBuffer::ReadEfont( XclImpStream& rStrm )
+{
+ if( !maFontList.empty() )
+ maFontList.back().ReadEfont( rStrm );
+}
+
+void XclImpFontBuffer::FillToItemSet(
+ SfxItemSet& rItemSet, XclFontItemType eType,
+ sal_uInt16 nFontIdx, bool bSkipPoolDefs ) const
+{
+ if( const XclImpFont* pFont = GetFont( nFontIdx ) )
+ pFont->FillToItemSet( rItemSet, eType, bSkipPoolDefs );
+}
+
+void XclImpFontBuffer::WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, sal_uInt16 nFontIdx, const Color* pFontColor ) const
+{
+ if( const XclImpFont* pFont = GetFont( nFontIdx ) )
+ pFont->WriteFontProperties( rPropSet, eType, pFontColor );
+}
+
+void XclImpFontBuffer::WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const
+{
+ maCtrlFont.WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL );
+}
+
+void XclImpFontBuffer::UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet )
+{
+ maAppFont = rFontData;
+ // #i3006# Calculate the width of '0' from first font and current printer.
+ SetCharWidth( maAppFont );
+
+ // font 4 is bold font 0
+ XclFontData aFont4Data( maAppFont );
+ aFont4Data.mnWeight = EXC_FONTWGHT_BOLD;
+ maFont4.SetFontData( aFont4Data, bHasCharSet );
+}
+
+// FORMAT record - number formats =============================================
+
+XclImpNumFmtBuffer::XclImpNumFmtBuffer( const XclImpRoot& rRoot ) :
+ XclNumFmtBuffer( rRoot ),
+ XclImpRoot( rRoot ),
+ mnNextXclIdx( 0 )
+{
+}
+
+void XclImpNumFmtBuffer::Initialize()
+{
+ maIndexMap.clear();
+ mnNextXclIdx = 0;
+ InitializeImport(); // base class
+}
+
+void XclImpNumFmtBuffer::ReadFormat( XclImpStream& rStrm )
+{
+ String aFormat;
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2:
+ case EXC_BIFF3:
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF4:
+ rStrm.Ignore( 2 ); // in BIFF4 the index field exists, but is undefined
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF5:
+ rStrm >> mnNextXclIdx;
+ aFormat = rStrm.ReadByteString( false );
+ break;
+
+ case EXC_BIFF8:
+ rStrm >> mnNextXclIdx;
+ aFormat = rStrm.ReadUniString();
+ break;
+
+ default:
+ DBG_ERROR_BIFF();
+ return;
+ }
+
+ if( mnNextXclIdx < 0xFFFF )
+ {
+ InsertFormat( mnNextXclIdx, aFormat );
+ ++mnNextXclIdx;
+ }
+}
+
+void XclImpNumFmtBuffer::CreateScFormats()
+{
+ DBG_ASSERT( maIndexMap.empty(), "XclImpNumFmtBuffer::CreateScFormats - already created" );
+
+ SvNumberFormatter& rFormatter = GetFormatter();
+ for( XclNumFmtMap::const_iterator aIt = GetFormatMap().begin(), aEnd = GetFormatMap().end(); aIt != aEnd; ++aIt )
+ {
+ const XclNumFmt& rNumFmt = aIt->second;
+
+ // insert/convert the Excel number format
+ xub_StrLen nCheckPos;
+ short nType = NUMBERFORMAT_DEFINED;
+ sal_uInt32 nKey;
+ if( rNumFmt.maFormat.Len() )
+ {
+ String aFormat( rNumFmt.maFormat );
+ rFormatter.PutandConvertEntry( aFormat, nCheckPos,
+ nType, nKey, LANGUAGE_ENGLISH_US, rNumFmt.meLanguage );
+ }
+ else
+ nKey = rFormatter.GetFormatIndex( rNumFmt.meOffset, rNumFmt.meLanguage );
+
+ // insert the resulting format key into the Excel->Calc index map
+ maIndexMap[ aIt->first ] = nKey;
+ }
+}
+
+sal_uLong XclImpNumFmtBuffer::GetScFormat( sal_uInt16 nXclNumFmt ) const
+{
+ XclImpIndexMap::const_iterator aIt = maIndexMap.find( nXclNumFmt );
+ return (aIt != maIndexMap.end()) ? aIt->second : NUMBERFORMAT_ENTRY_NOT_FOUND;
+}
+
+void XclImpNumFmtBuffer::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt, bool bSkipPoolDefs ) const
+{
+ sal_uLong nScNumFmt = GetScFormat( nXclNumFmt );
+ if( nScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ nScNumFmt = GetStdScNumFmt();
+ FillScFmtToItemSet( rItemSet, nScNumFmt, bSkipPoolDefs );
+}
+
+void XclImpNumFmtBuffer::FillScFmtToItemSet( SfxItemSet& rItemSet, sal_uLong nScNumFmt, bool bSkipPoolDefs ) const
+{
+ DBG_ASSERT( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND, "XclImpNumFmtBuffer::FillScFmtToItemSet - invalid number format" );
+ ScfTools::PutItem( rItemSet, SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ), bSkipPoolDefs );
+ if( rItemSet.GetItemState( ATTR_VALUE_FORMAT, false ) == SFX_ITEM_SET )
+ ScGlobal::AddLanguage( rItemSet, GetFormatter() );
+}
+
+// XF, STYLE record - Cell formatting =========================================
+
+void XclImpCellProt::FillFromXF2( sal_uInt8 nNumFmt )
+{
+ mbLocked = ::get_flag( nNumFmt, EXC_XF2_LOCKED );
+ mbHidden = ::get_flag( nNumFmt, EXC_XF2_HIDDEN );
+}
+
+void XclImpCellProt::FillFromXF3( sal_uInt16 nProt )
+{
+ mbLocked = ::get_flag( nProt, EXC_XF_LOCKED );
+ mbHidden = ::get_flag( nProt, EXC_XF_HIDDEN );
+}
+
+void XclImpCellProt::FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
+{
+ ScfTools::PutItem( rItemSet, ScProtectionAttr( mbLocked, mbHidden ), bSkipPoolDefs );
+}
+
+
+// ----------------------------------------------------------------------------
+
+void XclImpCellAlign::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nFlags, 0, 3 );
+}
+
+void XclImpCellAlign::FillFromXF3( sal_uInt16 nAlign )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK ); // new in BIFF3
+}
+
+void XclImpCellAlign::FillFromXF4( sal_uInt16 nAlign )
+{
+ FillFromXF3( nAlign );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 2 ); // new in BIFF4
+ mnOrient = ::extract_value< sal_uInt8 >( nAlign, 6, 2 ); // new in BIFF4
+}
+
+void XclImpCellAlign::FillFromXF5( sal_uInt16 nAlign )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
+ mnOrient = ::extract_value< sal_uInt8 >( nAlign, 8, 2 );
+}
+
+void XclImpCellAlign::FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
+{
+ mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
+ mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
+ mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
+ mnRotation = ::extract_value< sal_uInt8 >( nAlign, 8, 8 ); // new in BIFF8
+ mnIndent = ::extract_value< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8
+ mbShrink = ::get_flag( nMiscAttrib, EXC_XF8_SHRINK ); // new in BIFF8
+ mnTextDir = ::extract_value< sal_uInt8 >( nMiscAttrib, 6, 2 ); // new in BIFF8
+}
+
+void XclImpCellAlign::FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs ) const
+{
+ // horizontal alignment
+ ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
+ ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScHorJustifyMethod(), ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
+
+ // text wrap (#i74508# always if vertical alignment is justified or distributed)
+ bool bLineBreak = mbLineBreak || (mnVerAlign == EXC_XF_VER_JUSTIFY) || (mnVerAlign == EXC_XF_VER_DISTRIB);
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, bLineBreak ), bSkipPoolDefs );
+
+ // vertical alignment
+ ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
+ ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScVerJustifyMethod(), ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
+
+ // indent
+ sal_uInt16 nScIndent = mnIndent * 200; // 1 Excel unit == 10 pt == 200 twips
+ ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, nScIndent ), bSkipPoolDefs );
+
+ // shrink to fit
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, mbShrink ), bSkipPoolDefs );
+
+ // text orientation/rotation (BIFF2-BIFF7 sets mnOrient)
+ sal_uInt8 nXclRot = (mnOrient == EXC_ORIENT_NONE) ? mnRotation : XclTools::GetXclRotFromOrient( mnOrient );
+ bool bStacked = (nXclRot == EXC_ROT_STACKED);
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, bStacked ), bSkipPoolDefs );
+ // set an angle in the range from -90 to 90 degrees
+ sal_Int32 nAngle = XclTools::GetScRotation( nXclRot, 0 );
+ ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, nAngle ), bSkipPoolDefs );
+ // set "Use asian vertical layout", if cell is stacked and font contains CKJ characters
+ bool bAsianVert = bStacked && pFont && pFont->HasAsianChars();
+ ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_VERTICAL_ASIAN, bAsianVert ), bSkipPoolDefs );
+
+ // CTL text direction
+ ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCellBorder::XclImpCellBorder()
+{
+ SetUsedFlags( false, false );
+}
+
+void XclImpCellBorder::SetUsedFlags( bool bOuterUsed, bool bDiagUsed )
+{
+ mbLeftUsed = mbRightUsed = mbTopUsed = mbBottomUsed = bOuterUsed;
+ mbDiagUsed = bDiagUsed;
+}
+
+void XclImpCellBorder::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnLeftLine = ::get_flagvalue( nFlags, EXC_XF2_LEFTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnRightLine = ::get_flagvalue( nFlags, EXC_XF2_RIGHTLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnTopLine = ::get_flagvalue( nFlags, EXC_XF2_TOPLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnBottomLine = ::get_flagvalue( nFlags, EXC_XF2_BOTTOMLINE, EXC_LINE_THIN, EXC_LINE_NONE );
+ mnLeftColor = mnRightColor = mnTopColor = mnBottomColor = EXC_COLOR_BIFF2_BLACK;
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF3( sal_uInt32 nBorder )
+{
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 8, 3 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nBorder, 16, 3 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 24, 3 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 3, 5 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 11, 5 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nBorder, 19, 5 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 27, 5 );
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea )
+{
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder, 0, 3 );
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder, 3, 3 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nArea, 22, 3 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder, 6, 3 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder, 9, 7 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder, 16, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nArea, 25, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder, 23, 7 );
+ SetUsedFlags( true, false );
+}
+
+void XclImpCellBorder::FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
+{
+ mnLeftLine = ::extract_value< sal_uInt8 >( nBorder1, 0, 4 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nBorder1, 4, 4 );
+ mnTopLine = ::extract_value< sal_uInt8 >( nBorder1, 8, 4 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nBorder1, 12, 4 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nBorder1, 16, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nBorder1, 23, 7 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nBorder2, 0, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nBorder2, 7, 7 );
+ mbDiagTLtoBR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_TL_TO_BR );
+ mbDiagBLtoTR = ::get_flag( nBorder1, EXC_XF_DIAGONAL_BL_TO_TR );
+ if( mbDiagTLtoBR || mbDiagBLtoTR )
+ {
+ mnDiagLine = ::extract_value< sal_uInt8 >( nBorder2, 21, 4 );
+ mnDiagColor = ::extract_value< sal_uInt16 >( nBorder2, 14, 7 );
+ }
+ SetUsedFlags( true, true );
+}
+
+void XclImpCellBorder::FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags )
+{
+ mnLeftLine = ::extract_value< sal_uInt8 >( nLineStyle, 0, 4 );
+ mnRightLine = ::extract_value< sal_uInt8 >( nLineStyle, 4, 4 );
+ mnTopLine = ::extract_value< sal_uInt8 >( nLineStyle, 8, 4 );
+ mnBottomLine = ::extract_value< sal_uInt8 >( nLineStyle, 12, 4 );
+ mnLeftColor = ::extract_value< sal_uInt16 >( nLineColor, 0, 7 );
+ mnRightColor = ::extract_value< sal_uInt16 >( nLineColor, 7, 7 );
+ mnTopColor = ::extract_value< sal_uInt16 >( nLineColor, 16, 7 );
+ mnBottomColor = ::extract_value< sal_uInt16 >( nLineColor, 23, 7 );
+ mbLeftUsed = !::get_flag( nFlags, EXC_CF_BORDER_LEFT );
+ mbRightUsed = !::get_flag( nFlags, EXC_CF_BORDER_RIGHT );
+ mbTopUsed = !::get_flag( nFlags, EXC_CF_BORDER_TOP );
+ mbBottomUsed = !::get_flag( nFlags, EXC_CF_BORDER_BOTTOM );
+ mbDiagUsed = false;
+}
+
+bool XclImpCellBorder::HasAnyOuterBorder() const
+{
+ return
+ (mbLeftUsed && (mnLeftLine != EXC_LINE_NONE)) ||
+ (mbRightUsed && (mnRightLine != EXC_LINE_NONE)) ||
+ (mbTopUsed && (mnTopLine != EXC_LINE_NONE)) ||
+ (mbBottomUsed && (mnBottomLine != EXC_LINE_NONE));
+}
+
+namespace {
+
+// TODO: These values are approximate; we should probably tweak these values
+// further to better match Excel's border thickness.
+#define XLS_LINE_WIDTH_HAIR 1
+#define XLS_LINE_WIDTH_THIN 6
+#define XLS_LINE_WIDTH_MEDIUM 18
+#define XLS_LINE_WIDTH_THICK 24
+
+/** Converts the passed line style to a ::editeng::SvxBorderLine, or returns false, if style is "no line". */
+bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette& rPalette, sal_uInt8 nXclLine, sal_uInt16 nXclColor )
+{
+ static const sal_uInt16 ppnLineParam[][ 4 ] =
+ {
+ // outer width, type
+ { 0, ::editeng::SOLID }, // 0 = none
+ { XLS_LINE_WIDTH_THIN, ::editeng::SOLID }, // 1 = thin
+ { XLS_LINE_WIDTH_MEDIUM, ::editeng::SOLID }, // 2 = medium
+ { XLS_LINE_WIDTH_THIN, ::editeng::DASHED }, // 3 = dashed
+ { XLS_LINE_WIDTH_THIN, ::editeng::DOTTED }, // 4 = dotted
+ { XLS_LINE_WIDTH_THICK, ::editeng::SOLID }, // 5 = thick
+ { XLS_LINE_WIDTH_THIN, ::editeng::DOUBLE }, // 6 = double
+ { XLS_LINE_WIDTH_HAIR, ::editeng::SOLID }, // 7 = hair
+ { XLS_LINE_WIDTH_MEDIUM, ::editeng::DASHED }, // 8 = med dash
+ { XLS_LINE_WIDTH_THIN, ::editeng::SOLID }, // 9 = thin dashdot
+ { XLS_LINE_WIDTH_MEDIUM, ::editeng::SOLID }, // A = med dashdot
+ { XLS_LINE_WIDTH_THIN, ::editeng::SOLID }, // B = thin dashdotdot
+ { XLS_LINE_WIDTH_MEDIUM, ::editeng::SOLID }, // C = med dashdotdot
+ { XLS_LINE_WIDTH_MEDIUM, ::editeng::SOLID } // D = med slant dashdot
+ };
+
+ if( nXclLine == EXC_LINE_NONE )
+ return false;
+ if( nXclLine >= SAL_N_ELEMENTS( ppnLineParam ) )
+ nXclLine = EXC_LINE_THIN;
+
+ rLine.SetColor( rPalette.GetColor( nXclColor ) );
+ rLine.SetWidth( ppnLineParam[ nXclLine ][ 0 ] );
+ rLine.SetStyle( (::editeng::SvxBorderStyle)ppnLineParam[ nXclLine ][ 1 ] );
+ return true;
+}
+
+} // namespace
+
+void XclImpCellBorder::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
+{
+ if( mbLeftUsed || mbRightUsed || mbTopUsed || mbBottomUsed )
+ {
+ SvxBoxItem aBoxItem( ATTR_BORDER );
+ ::editeng::SvxBorderLine aLine;
+ if( mbLeftUsed && lclConvertBorderLine( aLine, rPalette, mnLeftLine, mnLeftColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
+ if( mbRightUsed && lclConvertBorderLine( aLine, rPalette, mnRightLine, mnRightColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
+ if( mbTopUsed && lclConvertBorderLine( aLine, rPalette, mnTopLine, mnTopColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
+ if( mbBottomUsed && lclConvertBorderLine( aLine, rPalette, mnBottomLine, mnBottomColor ) )
+ aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
+ ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
+ }
+ if( mbDiagUsed )
+ {
+ SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
+ SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
+ ::editeng::SvxBorderLine aLine;
+ if( lclConvertBorderLine( aLine, rPalette, mnDiagLine, mnDiagColor ) )
+ {
+ if( mbDiagTLtoBR )
+ aTLBRItem.SetLine( &aLine );
+ if( mbDiagBLtoTR )
+ aBLTRItem.SetLine( &aLine );
+ }
+ ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
+ ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpCellArea::XclImpCellArea()
+{
+ SetUsedFlags( false );
+}
+
+void XclImpCellArea::SetUsedFlags( bool bUsed )
+{
+ mbForeUsed = mbBackUsed = mbPattUsed = bUsed;
+}
+
+void XclImpCellArea::FillFromXF2( sal_uInt8 nFlags )
+{
+ mnPattern = ::get_flagvalue( nFlags, EXC_XF2_BACKGROUND, EXC_PATT_12_5_PERC, EXC_PATT_NONE );
+ mnForeColor = EXC_COLOR_BIFF2_BLACK;
+ mnBackColor = EXC_COLOR_BIFF2_WHITE;
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF3( sal_uInt16 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nArea, 0, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 6, 5 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 11, 5 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF5( sal_uInt32 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nArea, 16, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea )
+{
+ mnPattern = ::extract_value< sal_uInt8 >( nBorder2, 26, 6 );
+ mnForeColor = ::extract_value< sal_uInt16 >( nArea, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nArea, 7, 7 );
+ SetUsedFlags( true );
+}
+
+void XclImpCellArea::FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags )
+{
+ mnForeColor = ::extract_value< sal_uInt16 >( nColor, 0, 7 );
+ mnBackColor = ::extract_value< sal_uInt16 >( nColor, 7, 7 );
+ mnPattern = ::extract_value< sal_uInt8 >( nPattern, 10, 6 );
+ mbForeUsed = !::get_flag( nFlags, EXC_CF_AREA_FGCOLOR );
+ mbBackUsed = !::get_flag( nFlags, EXC_CF_AREA_BGCOLOR );
+ mbPattUsed = !::get_flag( nFlags, EXC_CF_AREA_PATTERN );
+
+ if( mbBackUsed && (!mbPattUsed || (mnPattern == EXC_PATT_SOLID)) )
+ {
+ mnForeColor = mnBackColor;
+ mnPattern = EXC_PATT_SOLID;
+ mbForeUsed = mbPattUsed = true;
+ }
+ else if( !mbBackUsed && mbPattUsed && (mnPattern == EXC_PATT_SOLID) )
+ {
+ mbPattUsed = false;
+ }
+}
+
+void XclImpCellArea::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
+{
+ if( mbPattUsed ) // colors may be both unused in cond. formats
+ {
+ SvxBrushItem aBrushItem( ATTR_BACKGROUND );
+
+ // do not use IsTransparent() - old Calc filter writes tranparency with different color indexes
+ if( mnPattern == EXC_PATT_NONE )
+ {
+ aBrushItem.SetColor( Color( COL_TRANSPARENT ) );
+ }
+ else
+ {
+ Color aFore( rPalette.GetColor( mbForeUsed ? mnForeColor : EXC_COLOR_WINDOWTEXT ) );
+ Color aBack( rPalette.GetColor( mbBackUsed ? mnBackColor : EXC_COLOR_WINDOWBACK ) );
+ aBrushItem.SetColor( XclTools::GetPatternColor( aFore, aBack, mnPattern ) );
+ }
+
+ ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+XclImpXF::XclImpXF( const XclImpRoot& rRoot ) :
+ XclXFBase( true ), // default is cell XF
+ XclImpRoot( rRoot ),
+ mpStyleSheet( 0 ),
+ mnXclNumFmt( 0 ),
+ mnXclFont( 0 )
+{
+}
+
+XclImpXF::~XclImpXF()
+{
+}
+
+void XclImpXF::ReadXF2( XclImpStream& rStrm )
+{
+ sal_uInt8 nReadFont, nReadNumFmt, nFlags;
+ rStrm >> nReadFont;
+ rStrm.Ignore( 1 );
+ rStrm >> nReadNumFmt >> nFlags;
+
+ // XF type always cell, no parent, used flags always true
+ SetAllUsedFlags( true );
+
+ // attributes
+ maProtection.FillFromXF2( nReadNumFmt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt & EXC_XF2_VALFMT_MASK;
+ maAlignment.FillFromXF2( nFlags );
+ maBorder.FillFromXF2( nFlags );
+ maArea.FillFromXF2( nFlags );
+}
+
+void XclImpXF::ReadXF3( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nReadFont, nReadNumFmt;
+ rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE ); // new in BIFF3
+ mnParent = ::extract_value< sal_uInt16 >( nAlign, 4, 12 ); // new in BIFF3
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nTypeProt, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt;
+ maAlignment.FillFromXF3( nAlign );
+ maBorder.FillFromXF3( nBorder );
+ maArea.FillFromXF3( nArea ); // new in BIFF3
+}
+
+void XclImpXF::ReadXF4( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nReadFont, nReadNumFmt;
+ rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ mnXclFont = nReadFont;
+ mnXclNumFmt = nReadNumFmt;
+ maAlignment.FillFromXF4( nAlign );
+ maBorder.FillFromXF3( nBorder );
+ maArea.FillFromXF3( nArea );
+}
+
+void XclImpXF::ReadXF5( XclImpStream& rStrm )
+{
+ sal_uInt32 nArea, nBorder;
+ sal_uInt16 nTypeProt, nAlign;
+ rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ maAlignment.FillFromXF5( nAlign );
+ maBorder.FillFromXF5( nBorder, nArea );
+ maArea.FillFromXF5( nArea );
+}
+
+void XclImpXF::ReadXF8( XclImpStream& rStrm )
+{
+ sal_uInt32 nBorder1, nBorder2;
+ sal_uInt16 nTypeProt, nAlign, nMiscAttrib, nArea;
+ rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
+
+ // XF type/parent, attribute used flags
+ mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
+ mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
+ SetUsedFlags( ::extract_value< sal_uInt8 >( nMiscAttrib, 10, 6 ) );
+
+ // attributes
+ maProtection.FillFromXF3( nTypeProt );
+ maAlignment.FillFromXF8( nAlign, nMiscAttrib );
+ maBorder.FillFromXF8( nBorder1, nBorder2 );
+ maArea.FillFromXF8( nBorder2, nArea );
+}
+
+void XclImpXF::ReadXF( XclImpStream& rStrm )
+{
+ switch( GetBiff() )
+ {
+ case EXC_BIFF2: ReadXF2( rStrm ); break;
+ case EXC_BIFF3: ReadXF3( rStrm ); break;
+ case EXC_BIFF4: ReadXF4( rStrm ); break;
+ case EXC_BIFF5: ReadXF5( rStrm ); break;
+ case EXC_BIFF8: ReadXF8( rStrm ); break;
+ default: DBG_ERROR_BIFF();
+ }
+}
+
+const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs )
+{
+ if( mpPattern.get() )
+ return *mpPattern;
+
+ // create new pattern attribute set
+ mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) );
+ SfxItemSet& rItemSet = mpPattern->GetItemSet();
+ XclImpXF* pParentXF = IsCellXF() ? GetXFBuffer().GetXF( mnParent ) : 0;
+
+ // parent cell style
+ if( IsCellXF() && !mpStyleSheet )
+ {
+ mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent );
+
+ /* Enables mb***Used flags, if the formatting attributes differ from
+ the passed XF record. In cell XFs Excel uses the cell attributes,
+ if they differ from the parent style XF.
+ ...or if the respective flag is not set in parent style XF. */
+ if( pParentXF )
+ {
+ if( !mbProtUsed )
+ mbProtUsed = !pParentXF->mbProtUsed || !(maProtection == pParentXF->maProtection);
+ if( !mbFontUsed )
+ mbFontUsed = !pParentXF->mbFontUsed || (mnXclFont != pParentXF->mnXclFont);
+ if( !mbFmtUsed )
+ mbFmtUsed = !pParentXF->mbFmtUsed || (mnXclNumFmt != pParentXF->mnXclNumFmt);
+ if( !mbAlignUsed )
+ mbAlignUsed = !pParentXF->mbAlignUsed || !(maAlignment == pParentXF->maAlignment);
+ if( !mbBorderUsed )
+ mbBorderUsed = !pParentXF->mbBorderUsed || !(maBorder == pParentXF->maBorder);
+ if( !mbAreaUsed )
+ mbAreaUsed = !pParentXF->mbAreaUsed || !(maArea == pParentXF->maArea);
+ }
+ }
+
+ // cell protection
+ if( mbProtUsed )
+ maProtection.FillToItemSet( rItemSet, bSkipPoolDefs );
+
+ // font
+ if( mbFontUsed )
+ GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs );
+
+ // value format
+ if( mbFmtUsed )
+ {
+ GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs );
+ // Trace occurrences of Windows date formats
+ GetTracer().TraceDates( mnXclNumFmt );
+ }
+
+ // alignment
+ if( mbAlignUsed )
+ maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs );
+
+ // border
+ if( mbBorderUsed )
+ {
+ maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
+ GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR ||
+ maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR ||
+ maBorder.mnBottomLine > EXC_LINE_HAIR );
+ }
+
+ // area
+ if( mbAreaUsed )
+ {
+ maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
+ GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE &&
+ maArea.mnPattern != EXC_PATT_SOLID);
+ }
+
+ /* #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( mbAlignUsed || mbBorderUsed )
+ {
+ SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
+ const XclImpCellAlign* pAlign = mbAlignUsed ? &maAlignment : (pParentXF ? &pParentXF->maAlignment : 0);
+ const XclImpCellBorder* pBorder = mbBorderUsed ? &maBorder : (pParentXF ? &pParentXF->maBorder : 0);
+ if( pAlign && pBorder && (0 < pAlign->mnRotation) && (pAlign->mnRotation <= 180) && pBorder->HasAnyOuterBorder() )
+ eRotateMode = SVX_ROTATE_MODE_BOTTOM;
+ ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
+ }
+
+ // Excel's cell margins are different from Calc's default margins.
+ SvxMarginItem aItem(40, 40, 40, 40, ATTR_MARGIN);
+ ScfTools::PutItem(rItemSet, aItem, bSkipPoolDefs);
+
+ return *mpPattern;
+}
+
+void XclImpXF::ApplyPatternToAttrList(
+ list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, sal_uInt32 nForceScNumFmt)
+{
+ // force creation of cell style and hard formatting, do it here to have mpStyleSheet
+ const ScPatternAttr& rOrigPat = CreatePattern();
+ ScPatternAttr aNewPat = rOrigPat;
+ const ScPatternAttr* pPat = NULL;
+
+ // insert into document
+ ScDocument& rDoc = GetDoc();
+
+ if (IsCellXF() && mpStyleSheet)
+ {
+ // Style sheet exists. Create a copy of the original pattern.
+ aNewPat.SetStyleSheet(mpStyleSheet);
+ pPat = &aNewPat;
+ }
+
+ if (HasUsedFlags())
+ {
+ if (!pPat)
+ pPat = &aNewPat;
+
+ SfxItemPoolCache aCache(rDoc.GetPool(), &rOrigPat.GetItemSet());
+ pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
+ }
+
+ if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ if (!pPat)
+ pPat = &aNewPat;
+
+ ScPatternAttr aNumPat(GetDoc().GetPool());
+ GetNumFmtBuffer().FillScFmtToItemSet(aNumPat.GetItemSet(), nForceScNumFmt);
+ SfxItemPoolCache aCache(rDoc.GetPool(), &aNumPat.GetItemSet());
+ pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
+ }
+
+ // Make sure we skip unnamed styles.
+ if (pPat && pPat->GetStyleName())
+ {
+ // Check for a gap between the last entry and this one.
+ bool bHasGap = false;
+ if (rAttrs.empty() && nRow1 > 0)
+ // First attribute range doesn't start at row 0.
+ bHasGap = true;
+
+ if (!rAttrs.empty() && rAttrs.back().nRow + 1 < nRow1)
+ bHasGap = true;
+
+ if (bHasGap)
+ {
+ // Fill this gap with the default pattern.
+ ScAttrEntry aEntry;
+ aEntry.nRow = nRow1 - 1;
+ aEntry.pPattern = rDoc.GetDefPattern();
+ rAttrs.push_back(aEntry);
+ }
+
+ ScAttrEntry aEntry;
+ aEntry.nRow = nRow2;
+ aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(*pPat));
+ rAttrs.push_back(aEntry);
+ }
+}
+
+void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags )
+{
+ /* Notes about finding the mb***Used flags:
+ - In cell XFs a *set* bit means a used attribute.
+ - In style XFs a *cleared* bit means a used attribute.
+ The mb***Used members always store true, if the attribute is used.
+ The "mbCellXF == ::get_flag(...)" construct evaluates to true in
+ both mentioned cases: cell XF and set bit; or style XF and cleared bit.
+ */
+ mbProtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_PROT ));
+ mbFontUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_FONT ));
+ mbFmtUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_VALFMT ));
+ mbAlignUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_ALIGN ));
+ mbBorderUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_BORDER ));
+ mbAreaUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_AREA ));
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnXfId( EXC_XF_NOTFOUND ),
+ mnBuiltinId( EXC_STYLE_USERDEF ),
+ mnLevel( EXC_STYLE_NOLEVEL ),
+ mbBuiltin( false ),
+ mbCustom( false ),
+ mbHidden( false ),
+ mpStyleSheet( 0 )
+{
+}
+
+void XclImpStyle::ReadStyle( XclImpStream& rStrm )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 );
+
+ sal_uInt16 nXFIndex;
+ rStrm >> nXFIndex;
+ mnXfId = nXFIndex & EXC_STYLE_XFMASK;
+ mbBuiltin = ::get_flag( nXFIndex, EXC_STYLE_BUILTIN );
+
+ if( mbBuiltin )
+ {
+ rStrm >> mnBuiltinId >> mnLevel;
+ }
+ else
+ {
+ maName = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
+ // #i103281# check if this is a new built-in style introduced in XL2007
+ if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() )
+ {
+ sal_uInt8 nExtFlags;
+ rStrm.Ignore( 12 );
+ rStrm >> nExtFlags;
+ mbBuiltin = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN );
+ mbCustom = ::get_flag( nExtFlags, EXC_STYLEEXT_CUSTOM );
+ mbHidden = ::get_flag( nExtFlags, EXC_STYLEEXT_HIDDEN );
+ if( mbBuiltin )
+ {
+ rStrm.Ignore( 1 ); // category
+ rStrm >> mnBuiltinId >> mnLevel;
+ }
+ }
+ }
+}
+
+ScStyleSheet* XclImpStyle::CreateStyleSheet()
+{
+ // #i1624# #i1768# ignore unnamed user styles
+ if( !mpStyleSheet && (maFinalName.Len() > 0) )
+ {
+ bool bCreatePattern = false;
+ XclImpXF* pXF = GetXFBuffer().GetXF( mnXfId );
+
+ bool bDefStyle = mbBuiltin && (mnBuiltinId == EXC_STYLE_NORMAL);
+ if( bDefStyle )
+ {
+ // set all flags to true to get all items in XclImpXF::CreatePattern()
+ if( pXF ) pXF->SetAllUsedFlags( true );
+ // use existing "Default" style sheet
+ mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find(
+ ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) );
+ DBG_ASSERT( mpStyleSheet, "XclImpStyle::CreateStyleSheet - Default style not found" );
+ bCreatePattern = true;
+ }
+ else
+ {
+ /* #i103281# do not create another style sheet of the same name,
+ if it exists already. This is needed to prevent that styles
+ pasted from clipboard get duplicated over and over. */
+ mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
+ if( !mpStyleSheet )
+ {
+ mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
+ bCreatePattern = true;
+ }
+ }
+
+ // bDefStyle==true omits default pool items in CreatePattern()
+ if( bCreatePattern && mpStyleSheet && pXF )
+ mpStyleSheet->GetItemSet().Put( pXF->CreatePattern( bDefStyle ).GetItemSet() );
+ }
+ return mpStyleSheet;
+}
+
+void XclImpStyle::CreateUserStyle( const String& rFinalName )
+{
+ maFinalName = rFinalName;
+ if( !IsBuiltin() || mbCustom )
+ CreateStyleSheet();
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpXFBuffer::Initialize()
+{
+ maXFList.clear();
+ maBuiltinStyles.clear();
+ maUserStyles.clear();
+ maStylesByXf.clear();
+}
+
+void XclImpXFBuffer::ReadXF( XclImpStream& rStrm )
+{
+ XclImpXF* pXF = new XclImpXF( GetRoot() );
+ pXF->ReadXF( rStrm );
+ maXFList.push_back( pXF );
+}
+
+void XclImpXFBuffer::ReadStyle( XclImpStream& rStrm )
+{
+ XclImpStyle* pStyle = new XclImpStyle( GetRoot() );
+ pStyle->ReadStyle( rStrm );
+ (pStyle->IsBuiltin() ? maBuiltinStyles : maUserStyles).push_back( pStyle );
+ DBG_ASSERT( maStylesByXf.count( pStyle->GetXfId() ) == 0, "XclImpXFBuffer::ReadStyle - multiple styles with equal XF identifier" );
+ maStylesByXf[ pStyle->GetXfId() ] = pStyle;
+}
+
+sal_uInt16 XclImpXFBuffer::GetFontIndex( sal_uInt16 nXFIndex ) const
+{
+ const XclImpXF* pXF = GetXF( nXFIndex );
+ return pXF ? pXF->GetFontIndex() : EXC_FONT_NOTFOUND;
+}
+
+const XclImpFont* XclImpXFBuffer::GetFont( sal_uInt16 nXFIndex ) const
+{
+ return GetFontBuffer().GetFont( GetFontIndex( nXFIndex ) );
+}
+
+namespace {
+
+/** Functor for case-insensitive string comparison, usable in maps etc. */
+struct IgnoreCaseCompare
+{
+ inline bool operator()( const String& rName1, const String& rName2 ) const
+ { return rName1.CompareIgnoreCaseToAscii( rName2 ) == COMPARE_LESS; }
+};
+
+} // namespace
+
+void XclImpXFBuffer::CreateUserStyles()
+{
+ // calculate final names of all styles
+ typedef ::std::map< String, XclImpStyle*, IgnoreCaseCompare > CellStyleNameMap;
+ typedef ::std::vector< XclImpStyle* > XclImpStyleVector;
+
+ CellStyleNameMap aCellStyles;
+ XclImpStyleVector 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
+ initialized 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 = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0);
+ SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
+ String aStandardName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
+ if( (pStyleSheet->GetName() != aStandardName) && (bReserveAll || !pStyleSheet->IsUserDefined()) )
+ if( aCellStyles.count( pStyleSheet->GetName() ) == 0 )
+ aCellStyles[ pStyleSheet->GetName() ] = 0;
+
+ /* Calculate names of built-in styles. Store styles with reserved names
+ in the aConflictNameStyles list. */
+ for( XclImpStyleList::iterator itStyle = maBuiltinStyles.begin(); itStyle != maBuiltinStyles.end(); ++itStyle )
+ {
+ String aStyleName = XclTools::GetBuiltInStyleName( itStyle->GetBuiltinId(), itStyle->GetName(), itStyle->GetLevel() );
+ DBG_ASSERT( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
+ "XclImpXFBuffer::CreateUserStyles - multiple styles with equal built-in identifier" );
+ if( aCellStyles.count( aStyleName ) > 0 )
+ aConflictNameStyles.push_back( &(*itStyle) );
+ else
+ aCellStyles[ aStyleName ] = &(*itStyle);
+ }
+
+ /* Calculate names of user defined styles. Store styles with reserved
+ names in the aConflictNameStyles list. */
+ for( XclImpStyleList::iterator itStyle = maUserStyles.begin(); itStyle != maUserStyles.end(); ++itStyle )
+ {
+ // #i1624# #i1768# ignore unnamed user styles
+ if( itStyle->GetName().Len() > 0 )
+ {
+ if( aCellStyles.count( itStyle->GetName() ) > 0 )
+ aConflictNameStyles.push_back( &(*itStyle) );
+ else
+ aCellStyles[ itStyle->GetName() ] = &(*itStyle);
+ }
+ }
+
+ // find unused names for all styles with conflicting names
+ for( XclImpStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
+ {
+ XclImpStyle* pStyle = *aIt;
+ String aUnusedName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aUnusedName.Assign( pStyle->GetName() ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) );
+ }
+ while( aCellStyles.count( aUnusedName ) > 0 );
+ aCellStyles[ aUnusedName ] = pStyle;
+ }
+
+ // set final names and create user-defined and modified built-in cell styles
+ for( CellStyleNameMap::iterator aIt = aCellStyles.begin(), aEnd = aCellStyles.end(); aIt != aEnd; ++aIt )
+ if( aIt->second )
+ aIt->second->CreateUserStyle( aIt->first );
+}
+
+ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex )
+{
+ XclImpStyleMap::iterator aIt = maStylesByXf.find( nXFIndex );
+ return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet();
+}
+
+// Buffer for XF indexes in cells =============================================
+
+IMPL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange, 100, 500 )
+
+bool XclImpXFRange::Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex )
+{
+ if( maXFIndex != rXFIndex )
+ return false;
+
+ if( mnScRow2 + 1 == nScRow )
+ {
+ ++mnScRow2;
+ return true;
+ }
+ if( mnScRow1 > 0 && (mnScRow1 - 1 == nScRow) )
+ {
+ --mnScRow1;
+ return true;
+ }
+
+ return false;
+}
+
+bool XclImpXFRange::Expand( const XclImpXFRange& rNextRange )
+{
+ DBG_ASSERT( mnScRow2 < rNextRange.mnScRow1, "XclImpXFRange::Expand - rows out of order" );
+ if( (maXFIndex == rNextRange.maXFIndex) && (mnScRow2 + 1 == rNextRange.mnScRow1) )
+ {
+ mnScRow2 = rNextRange.mnScRow2;
+ return true;
+ }
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpXFRangeColumn::SetDefaultXF( const XclImpXFIndex& rXFIndex )
+{
+ // List should be empty when inserting the default column format.
+ // Later explicit SetXF() calls will break up this range.
+ DBG_ASSERT( maIndexList.empty(), "XclImpXFRangeColumn::SetDefaultXF - Setting Default Column XF is not empty" );
+
+ // insert a complete row range with one insert.
+ maIndexList.push_back( new XclImpXFRange( 0, MAXROW, rXFIndex ) );
+}
+
+// ----------------------------------------------------------------------------
+
+void XclImpXFRangeColumn::SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex )
+{
+ XclImpXFRange* pPrevRange;
+ XclImpXFRange* pNextRange;
+ sal_uLong nNextIndex;
+
+ Find( pPrevRange, pNextRange, nNextIndex, nScRow );
+
+ // previous range:
+ // try to overwrite XF (if row is contained in) or try to expand range
+ if( pPrevRange )
+ {
+ if( pPrevRange->Contains( nScRow ) ) // overwrite old XF
+ {
+ if( rXFIndex == pPrevRange->maXFIndex )
+ return;
+
+ SCROW nFirstScRow = pPrevRange->mnScRow1;
+ SCROW nLastScRow = pPrevRange->mnScRow2;
+ sal_uLong nIndex = nNextIndex - 1;
+ XclImpXFRange* pThisRange = pPrevRange;
+ pPrevRange = (nIndex > 0 && nIndex <= maIndexList.size()) ? &(maIndexList[ nIndex - 1 ]) : 0;
+
+ if( nFirstScRow == nLastScRow ) // replace solely XF
+ {
+ pThisRange->maXFIndex = rXFIndex;
+ TryConcatPrev( nNextIndex ); // try to concat. next with this
+ TryConcatPrev( nIndex ); // try to concat. this with previous
+ }
+ else if( nFirstScRow == nScRow ) // replace first XF
+ {
+ ++(pThisRange->mnScRow1);
+ // try to concatenate with previous of this
+ if( !pPrevRange || !pPrevRange->Expand( nScRow, rXFIndex ) )
+ Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
+ }
+ else if( nLastScRow == nScRow ) // replace last XF
+ {
+ --(pThisRange->mnScRow2);
+ if( !pNextRange || !pNextRange->Expand( nScRow, rXFIndex ) )
+ Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
+ }
+ else // insert in the middle of the range
+ {
+ pThisRange->mnScRow1 = nScRow + 1;
+ // List::Insert() moves entries towards end of list, so insert twice at nIndex
+ Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
+ Insert( new XclImpXFRange( nFirstScRow, nScRow - 1, pThisRange->maXFIndex ), nIndex );
+ }
+ return;
+ }
+ else if( pPrevRange->Expand( nScRow, rXFIndex ) ) // try to expand
+ {
+ TryConcatPrev( nNextIndex ); // try to concatenate next with expanded
+ return;
+ }
+ }
+
+ // try to expand next range
+ if( pNextRange && pNextRange->Expand( nScRow, rXFIndex ) )
+ return;
+
+ // create new range
+ Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
+}
+
+void XclImpXFRangeColumn::Insert(XclImpXFRange* pXFRange, sal_uLong nIndex)
+{
+ maIndexList.insert( maIndexList.begin() + nIndex, pXFRange );
+}
+
+void XclImpXFRangeColumn::Find(
+ XclImpXFRange*& rpPrevRange, XclImpXFRange*& rpNextRange,
+ sal_uLong& rnNextIndex, SCROW nScRow )
+{
+
+ // test whether list is empty
+ if( maIndexList.empty() )
+ {
+ rpPrevRange = rpNextRange = 0;
+ rnNextIndex = 0;
+ return;
+ }
+
+ rpPrevRange = &maIndexList.front();
+ rpNextRange = &maIndexList.back();
+
+ // test whether row is at end of list (contained in or behind last range)
+ // rpPrevRange will contain a possible existing row
+ if( rpNextRange->mnScRow1 <= nScRow )
+ {
+ rpPrevRange = rpNextRange;
+ rpNextRange = 0;
+ rnNextIndex = maIndexList.size();
+ return;
+ }
+
+ // test whether row is at beginning of list (really before first range)
+ if( nScRow < rpPrevRange->mnScRow1 )
+ {
+ rpNextRange = rpPrevRange;
+ rpPrevRange = 0;
+ rnNextIndex = 0;
+ return;
+ }
+
+ // loop: find range entries before and after new row
+ // break the loop if there is no more range between first and last -or-
+ // if rpPrevRange contains nScRow (rpNextRange will never contain nScRow)
+ sal_uLong nPrevIndex = 0;
+ sal_uLong nMidIndex;
+ rnNextIndex = maIndexList.size() - 1;
+ XclImpXFRange* pMidRange;
+ while( ((rnNextIndex - nPrevIndex) > 1) && (rpPrevRange->mnScRow2 < nScRow) )
+ {
+ nMidIndex = (nPrevIndex + rnNextIndex) / 2;
+ pMidRange = &maIndexList[nMidIndex];
+ DBG_ASSERT( pMidRange, "XclImpXFRangeColumn::Find - missing XF index range" );
+ if( nScRow < pMidRange->mnScRow1 ) // row is really before pMidRange
+ {
+ rpNextRange = pMidRange;
+ rnNextIndex = nMidIndex;
+ }
+ else // row is in or after pMidRange
+ {
+ rpPrevRange = pMidRange;
+ nPrevIndex = nMidIndex;
+ }
+ }
+
+ // find next rpNextRange if rpPrevRange contains nScRow
+ if( nScRow <= rpPrevRange->mnScRow2 )
+ {
+ rnNextIndex = nPrevIndex + 1;
+ rpNextRange = &maIndexList[rnNextIndex];
+ }
+}
+
+void XclImpXFRangeColumn::TryConcatPrev( sal_uLong nIndex )
+{
+ if( !nIndex || nIndex >= maIndexList.size() )
+ return;
+
+ XclImpXFRange& prevRange = maIndexList[ nIndex - 1 ];
+ XclImpXFRange& nextRange = maIndexList[ nIndex ];
+
+ if( prevRange.Expand( nextRange ) )
+ maIndexList.erase( maIndexList.begin() + nIndex );
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpXFRangeBuffer::XclImpXFRangeBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+XclImpXFRangeBuffer::~XclImpXFRangeBuffer()
+{
+}
+
+void XclImpXFRangeBuffer::Initialize()
+{
+ maColumns.clear();
+ maHyperlinks.clear();
+ maMergeList.RemoveAll();
+}
+
+void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode )
+{
+ SCCOL nScCol = rScPos.Col();
+ SCROW nScRow = rScPos.Row();
+
+ // set cell XF's
+ size_t nIndex = static_cast< size_t >( nScCol );
+ if( maColumns.size() <= nIndex )
+ maColumns.resize( nIndex + 1 );
+ if( !maColumns[ nIndex ] )
+ maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
+ // remember all Boolean cells, they will get 'Standard' number format
+ maColumns[ nIndex ]->SetXF( nScRow, XclImpXFIndex( nXFIndex, eMode == xlXFModeBoolCell ) );
+
+ // set "center across selection" and "fill" attribute for all following empty cells
+ // ignore it on row default XFs
+ if( eMode != xlXFModeRow )
+ {
+ const XclImpXF* pXF = GetXFBuffer().GetXF( nXFIndex );
+ if( pXF && ((pXF->GetHorAlign() == EXC_XF_HOR_CENTER_AS) || (pXF->GetHorAlign() == EXC_XF_HOR_FILL)) )
+ {
+ // expand last merged range if this attribute is set repeatedly
+ if ( !maMergeList.empty() )
+ {
+ ScRange* pRange = maMergeList.back();
+ if( (pRange->aEnd.Row() == nScRow)
+ && (pRange->aEnd.Col() + 1 == nScCol)
+ && (eMode == xlXFModeBlank)
+ )
+ pRange->aEnd.IncCol();
+ }
+ else if( eMode != xlXFModeBlank ) // do not merge empty cells
+ SetMerge( nScCol, nScRow );
+ }
+ }
+}
+
+void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeCell );
+}
+
+void XclImpXFRangeBuffer::SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeBlank );
+}
+
+void XclImpXFRangeBuffer::SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
+{
+ SetXF( rScPos, nXFIndex, xlXFModeBoolCell );
+}
+
+void XclImpXFRangeBuffer::SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex )
+{
+ for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
+ SetXF( ScAddress( nScCol, nScRow, 0 ), nXFIndex, xlXFModeRow );
+}
+
+void XclImpXFRangeBuffer::SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex )
+{
+ // our array should not have values when creating the default column format.
+ size_t nIndex = static_cast< size_t >( nScCol );
+ if( maColumns.size() <= nIndex )
+ maColumns.resize( nIndex + 1 );
+ DBG_ASSERT( !maColumns[ nIndex ], "XclImpXFRangeBuffer::SetColumnDefXF - default column of XFs already has values" );
+ maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
+ maColumns[ nIndex ]->SetDefaultXF( XclImpXFIndex( nXFIndex ) );
+}
+
+void XclImpXFRangeBuffer::SetBorderLine( const ScRange& rRange, SCTAB nScTab, sal_uInt16 nLine )
+{
+ SCCOL nFromScCol = (nLine == BOX_LINE_RIGHT) ? rRange.aEnd.Col() : rRange.aStart.Col();
+ SCROW nFromScRow = (nLine == BOX_LINE_BOTTOM) ? rRange.aEnd.Row() : rRange.aStart.Row();
+ ScDocument& rDoc = GetDoc();
+
+ const SvxBoxItem* pFromItem = static_cast< const SvxBoxItem* >(
+ rDoc.GetAttr( nFromScCol, nFromScRow, nScTab, ATTR_BORDER ) );
+ const SvxBoxItem* pToItem = static_cast< const SvxBoxItem* >(
+ rDoc.GetAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, ATTR_BORDER ) );
+
+ SvxBoxItem aNewItem( *pToItem );
+ aNewItem.SetLine( pFromItem->GetLine( nLine ), nLine );
+ rDoc.ApplyAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, aNewItem );
+}
+
+void XclImpXFRangeBuffer::SetHyperlink( const XclRange& rXclRange, const String& rUrl )
+{
+ maHyperlinks.push_back( XclImpHyperlinkRange( rXclRange, rUrl ) );
+}
+
+void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol, SCROW nScRow )
+{
+ maMergeList.Append( ScRange( nScCol, nScRow, 0 ) );
+}
+
+void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 )
+{
+ if( (nScCol1 < nScCol2) || (nScRow1 < nScRow2) )
+ maMergeList.Append( ScRange( nScCol1, nScRow1, 0, nScCol2, nScRow2, 0 ) );
+}
+
+void XclImpXFRangeBuffer::Finalize()
+{
+ ScDocument& rDoc = GetDoc();
+ SCTAB nScTab = GetCurrScTab();
+
+ // apply patterns
+ XclImpXFBuffer& rXFBuffer = GetXFBuffer();
+ for( XclImpXFRangeColumnVec::const_iterator aVBeg = maColumns.begin(), aVEnd = maColumns.end(), aVIt = aVBeg; aVIt != aVEnd; ++aVIt )
+ {
+ // apply all cell styles of an existing column
+ if( aVIt->get() )
+ {
+ XclImpXFRangeColumn& rColumn = **aVIt;
+ SCCOL nScCol = static_cast< SCCOL >( aVIt - aVBeg );
+ list<ScAttrEntry> aAttrs;
+
+ for (XclImpXFRangeColumn::IndexList::iterator itr = rColumn.begin(), itrEnd = rColumn.end();
+ itr != itrEnd; ++itr)
+ {
+ XclImpXFRange& rStyle = *itr;
+ const XclImpXFIndex& rXFIndex = rStyle.maXFIndex;
+ XclImpXF* pXF = rXFBuffer.GetXF( rXFIndex.GetXFIndex() );
+ if (!pXF)
+ continue;
+
+ sal_uInt32 nForceScNumFmt = rXFIndex.IsBoolCell() ?
+ GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
+
+ pXF->ApplyPatternToAttrList(aAttrs, rStyle.mnScRow1, rStyle.mnScRow2, nForceScNumFmt);
+ }
+
+ if (aAttrs.empty() || aAttrs.back().nRow != MAXROW)
+ {
+ ScAttrEntry aEntry;
+ aEntry.nRow = MAXROW;
+ aEntry.pPattern = rDoc.GetDefPattern();
+ aAttrs.push_back(aEntry);
+ }
+
+ size_t nAttrSize = aAttrs.size();
+ ScAttrEntry* pData = new ScAttrEntry[nAttrSize];
+ list<ScAttrEntry>::const_iterator itr = aAttrs.begin(), itrEnd = aAttrs.end();
+ for (size_t i = 0; itr != itrEnd; ++itr, ++i)
+ pData[i] = *itr;
+
+ rDoc.SetAttrEntries(nScCol, nScTab, pData, static_cast<SCSIZE>(nAttrSize));
+ }
+ }
+
+ // insert hyperlink cells
+ for( XclImpHyperlinkList::const_iterator aLIt = maHyperlinks.begin(), aLEnd = maHyperlinks.end(); aLIt != aLEnd; ++aLIt )
+ XclImpHyperlink::InsertUrl( GetRoot(), aLIt->first, aLIt->second );
+
+ // apply cell merging
+ for ( size_t i = 0, nRange = maMergeList.size(); i < nRange; ++i )
+ {
+ const ScRange* pRange = maMergeList[ i ];
+ const ScAddress& rStart = pRange->aStart;
+ const ScAddress& rEnd = pRange->aEnd;
+ bool bMultiCol = rStart.Col() != rEnd.Col();
+ bool bMultiRow = rStart.Row() != rEnd.Row();
+ // set correct right border
+ if( bMultiCol )
+ SetBorderLine( *pRange, nScTab, BOX_LINE_RIGHT );
+ // set correct lower border
+ if( bMultiRow )
+ SetBorderLine( *pRange, nScTab, BOX_LINE_BOTTOM );
+ // do merge
+ if( bMultiCol || bMultiRow )
+ rDoc.DoMerge( nScTab, rStart.Col(), rStart.Row(), rEnd.Col(), rEnd.Row() );
+ // #i93609# merged range in a single row: test if manual row height is needed
+ if( !bMultiRow )
+ {
+ bool bTextWrap = static_cast< const SfxBoolItem* >( rDoc.GetAttr( rStart.Col(), rStart.Row(), rStart.Tab(), ATTR_LINEBREAK ) )->GetValue();
+ if( !bTextWrap && (rDoc.GetCellType( rStart ) == CELLTYPE_EDIT) )
+ if( const EditTextObject* pEditObj = static_cast< const ScEditCell* >( rDoc.GetCell( rStart ) )->GetData() )
+ bTextWrap = pEditObj->GetParagraphCount() > 1;
+ if( bTextWrap )
+ GetOldRoot().pColRowBuff->SetManualRowHeight( rStart.Row() );
+ }
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xiview.cxx b/sc/source/filter/excel/xiview.cxx
new file mode 100644
index 000000000000..85abb6589f03
--- /dev/null
+++ b/sc/source/filter/excel/xiview.cxx
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xiview.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
+#include "viewopti.hxx"
+#include "xistream.hxx"
+#include "xihelper.hxx"
+#include "xistyle.hxx"
+
+// Document view settings =====================================================
+
+XclImpDocViewSettings::XclImpDocViewSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpDocViewSettings::ReadWindow1( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnWinX
+ >> maData.mnWinY
+ >> maData.mnWinWidth
+ >> maData.mnWinHeight
+ >> maData.mnFlags;
+ if( GetBiff() >= EXC_BIFF5 )
+ {
+ rStrm >> maData.mnDisplXclTab
+ >> maData.mnFirstVisXclTab
+ >> maData.mnXclSelectCnt
+ >> maData.mnTabBarWidth;
+ }
+}
+
+SCTAB XclImpDocViewSettings::GetDisplScTab() const
+{
+ /* Simply cast Excel index to Calc index.
+ TODO: This may fail if the document contains scenarios. */
+ sal_uInt16 nMaxXclTab = static_cast< sal_uInt16 >( GetMaxPos().Tab() );
+ return static_cast< SCTAB >( (maData.mnDisplXclTab <= nMaxXclTab) ? maData.mnDisplXclTab : 0 );
+}
+
+void XclImpDocViewSettings::Finalize()
+{
+ ScViewOptions aViewOpt( GetDoc().GetViewOptions() );
+ aViewOpt.SetOption( VOPT_HSCROLL, ::get_flag( maData.mnFlags, EXC_WIN1_HOR_SCROLLBAR ) );
+ aViewOpt.SetOption( VOPT_VSCROLL, ::get_flag( maData.mnFlags, EXC_WIN1_VER_SCROLLBAR ) );
+ aViewOpt.SetOption( VOPT_TABCONTROLS, ::get_flag( maData.mnFlags, EXC_WIN1_TABBAR ) );
+ GetDoc().SetViewOptions( aViewOpt );
+
+ // displayed sheet
+ GetExtDocOptions().GetDocSettings().mnDisplTab = GetDisplScTab();
+
+ // width of the tabbar with sheet names
+ if( maData.mnTabBarWidth <= 1000 )
+ GetExtDocOptions().GetDocSettings().mfTabBarWidth = static_cast< double >( maData.mnTabBarWidth ) / 1000.0;
+}
+
+// Sheet view settings ========================================================
+
+namespace {
+
+long lclGetScZoom( sal_uInt16 nXclZoom, sal_uInt16 nDefZoom )
+{
+ return static_cast< long >( nXclZoom ? nXclZoom : nDefZoom );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclImpTabViewSettings::XclImpTabViewSettings( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+ Initialize();
+}
+
+void XclImpTabViewSettings::Initialize()
+{
+ maData.SetDefaults();
+}
+
+void XclImpTabViewSettings::ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal )
+{
+ DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF8 );
+ if( GetBiff() < EXC_BIFF8 )
+ return;
+
+ sal_uInt8 ColorIndex;
+ Color TabBgColor;
+
+ rStrm.Ignore( 16 );
+ ColorIndex = rStrm.ReaduInt8() & EXC_SHEETEXT_TABCOLOR; //0x7F
+ if ( ColorIndex >= 8 && ColorIndex <= 63 ) //only accept valid index values
+ {
+ TabBgColor = rPal.GetColor( ColorIndex );
+ maData.maTabBgColor = TabBgColor;
+ }
+}
+
+void XclImpTabViewSettings::ReadWindow2( XclImpStream& rStrm, bool bChart )
+{
+ if( GetBiff() == EXC_BIFF2 )
+ {
+ maData.mbShowFormulas = rStrm.ReaduInt8() != 0;
+ maData.mbShowGrid = rStrm.ReaduInt8() != 0;
+ maData.mbShowHeadings = rStrm.ReaduInt8() != 0;
+ maData.mbFrozenPanes = rStrm.ReaduInt8() != 0;
+ maData.mbShowZeros = rStrm.ReaduInt8() != 0;
+ rStrm >> maData.maFirstXclPos;
+ maData.mbDefGridColor = rStrm.ReaduInt8() != 0;
+ rStrm >> maData.maGridColor;
+ }
+ else
+ {
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> maData.maFirstXclPos;
+
+ // #i59590# real life: Excel ignores some view settings in chart sheets
+ maData.mbSelected = ::get_flag( nFlags, EXC_WIN2_SELECTED );
+ maData.mbDisplayed = ::get_flag( nFlags, EXC_WIN2_DISPLAYED );
+ maData.mbMirrored = !bChart && ::get_flag( nFlags, EXC_WIN2_MIRRORED );
+ maData.mbFrozenPanes = !bChart && ::get_flag( nFlags, EXC_WIN2_FROZEN );
+ maData.mbPageMode = !bChart && ::get_flag( nFlags, EXC_WIN2_PAGEBREAKMODE );
+ maData.mbDefGridColor = bChart || ::get_flag( nFlags, EXC_WIN2_DEFGRIDCOLOR );
+ maData.mbShowFormulas = !bChart && ::get_flag( nFlags, EXC_WIN2_SHOWFORMULAS );
+ maData.mbShowGrid = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWGRID );
+ maData.mbShowHeadings = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWHEADINGS );
+ maData.mbShowZeros = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWZEROS );
+ maData.mbShowOutline = bChart || ::get_flag( nFlags, EXC_WIN2_SHOWOUTLINE );
+
+ switch( GetBiff() )
+ {
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ case EXC_BIFF5:
+ rStrm >> maData.maGridColor;
+ break;
+ case EXC_BIFF8:
+ {
+ sal_uInt16 nGridColorIdx;
+ rStrm >> nGridColorIdx;
+ // zoom data not included in chart sheets
+ if( rStrm.GetRecLeft() >= 6 )
+ {
+ rStrm.Ignore( 2 );
+ rStrm >> maData.mnPageZoom >> maData.mnNormalZoom;
+ }
+
+ if( !maData.mbDefGridColor )
+ maData.maGridColor = GetPalette().GetColor( nGridColorIdx );
+ }
+ break;
+ default: DBG_ERROR_BIFF();
+ }
+ }
+
+ // do not scroll chart sheets
+ if( bChart )
+ maData.maFirstXclPos.Set( 0, 0 );
+}
+
+void XclImpTabViewSettings::ReadScl( XclImpStream& rStrm )
+{
+ sal_uInt16 nNum, nDenom;
+ rStrm >> nNum >> nDenom;
+ DBG_ASSERT( nDenom > 0, "XclImpPageSettings::ReadScl - invalid denominator" );
+ if( nDenom > 0 )
+ maData.mnCurrentZoom = limit_cast< sal_uInt16 >( (nNum * 100) / nDenom );
+}
+
+void XclImpTabViewSettings::ReadPane( XclImpStream& rStrm )
+{
+ rStrm >> maData.mnSplitX;
+ maData.mnSplitY = rStrm.ReaduInt16();
+
+ rStrm >> maData.maSecondXclPos
+ >> maData.mnActivePane;
+}
+
+void XclImpTabViewSettings::ReadSelection( XclImpStream& rStrm )
+{
+ // pane of this selection
+ sal_uInt8 nPane;
+ rStrm >> nPane;
+ XclSelectionData& rSelData = maData.CreateSelectionData( nPane );
+ // cursor position and selection
+ rStrm >> rSelData.maXclCursor >> rSelData.mnCursorIdx;
+ rSelData.maXclSelection.Read( rStrm, false );
+}
+
+void XclImpTabViewSettings::Finalize()
+{
+ SCTAB nScTab = GetCurrScTab();
+ ScDocument& rDoc = GetDoc();
+ XclImpAddressConverter& rAddrConv = GetAddressConverter();
+ ScExtTabSettings& rTabSett = GetExtDocOptions().GetOrCreateTabSettings( nScTab );
+ bool bDisplayed = GetDocViewSettings().GetDisplScTab() == nScTab;
+
+ // *** sheet options: cursor, selection, splits, zoom ***
+
+ // sheet flags
+ if( maData.mbMirrored )
+ // do not call this function with sal_False, it would mirror away all drawing objects
+ rDoc.SetLayoutRTL( nScTab, sal_True );
+ rTabSett.mbSelected = maData.mbSelected || bDisplayed;
+
+ // first visible cell in top-left pane and in additional pane(s)
+ rTabSett.maFirstVis = rAddrConv.CreateValidAddress( maData.maFirstXclPos, nScTab, false );
+ rTabSett.maSecondVis = rAddrConv.CreateValidAddress( maData.maSecondXclPos, nScTab, false );
+
+ // cursor position and selection
+ if( const XclSelectionData* pSelData = maData.GetSelectionData( maData.mnActivePane ) )
+ {
+ rTabSett.maCursor = rAddrConv.CreateValidAddress( pSelData->maXclCursor, nScTab, false );
+ rAddrConv.ConvertRangeList( rTabSett.maSelection, pSelData->maXclSelection, nScTab, false );
+ }
+
+ // active pane
+ switch( maData.mnActivePane )
+ {
+ case EXC_PANE_TOPLEFT: rTabSett.meActivePane = SCEXT_PANE_TOPLEFT; break;
+ case EXC_PANE_TOPRIGHT: rTabSett.meActivePane = SCEXT_PANE_TOPRIGHT; break;
+ case EXC_PANE_BOTTOMLEFT: rTabSett.meActivePane = SCEXT_PANE_BOTTOMLEFT; break;
+ case EXC_PANE_BOTTOMRIGHT: rTabSett.meActivePane = SCEXT_PANE_BOTTOMRIGHT; break;
+ }
+
+ // freeze/split position
+ rTabSett.mbFrozenPanes = maData.mbFrozenPanes;
+ if( maData.mbFrozenPanes )
+ {
+ /* Frozen panes: handle split position as row/column positions.
+ #i35812# Excel uses number of visible rows/columns, Calc uses position of freeze. */
+ if( (maData.mnSplitX > 0) && (maData.maFirstXclPos.mnCol + maData.mnSplitX <= GetScMaxPos().Col()) )
+ rTabSett.maFreezePos.SetCol( static_cast< SCCOL >( maData.maFirstXclPos.mnCol + maData.mnSplitX ) );
+ if( (maData.mnSplitY > 0) && (maData.maFirstXclPos.mnRow + maData.mnSplitY <= static_cast<unsigned>(GetScMaxPos().Row())) )
+ rTabSett.maFreezePos.SetRow( static_cast< SCROW >( maData.maFirstXclPos.mnRow + maData.mnSplitY ) );
+ }
+ else
+ {
+ // split window: position is in twips
+ rTabSett.maSplitPos.X() = static_cast< long >( maData.mnSplitX );
+ rTabSett.maSplitPos.Y() = static_cast< long >( maData.mnSplitY );
+ }
+
+ // grid color
+ if( maData.mbDefGridColor )
+ rTabSett.maGridColor.SetColor( COL_AUTO );
+ else
+ rTabSett.maGridColor = maData.maGridColor;
+
+ // show grid option
+ rTabSett.mbShowGrid = maData.mbShowGrid;
+
+ // view mode and zoom
+ if( maData.mnCurrentZoom != 0 )
+ (maData.mbPageMode ? maData.mnPageZoom : maData.mnNormalZoom) = maData.mnCurrentZoom;
+ rTabSett.mbPageMode = maData.mbPageMode;
+ rTabSett.mnNormalZoom = lclGetScZoom( maData.mnNormalZoom, EXC_WIN2_NORMALZOOM_DEF );
+ rTabSett.mnPageZoom = lclGetScZoom( maData.mnPageZoom, EXC_WIN2_PAGEZOOM_DEF );
+
+ // *** additional handling for displayed sheet ***
+
+ if( bDisplayed )
+ {
+ // set Excel sheet settings globally at Calc document, take settings from displayed sheet
+ ScViewOptions aViewOpt( rDoc.GetViewOptions() );
+ aViewOpt.SetOption( VOPT_FORMULAS, maData.mbShowFormulas );
+ aViewOpt.SetOption( VOPT_HEADER, maData.mbShowHeadings );
+ aViewOpt.SetOption( VOPT_NULLVALS, maData.mbShowZeros );
+ aViewOpt.SetOption( VOPT_OUTLINER, maData.mbShowOutline );
+ rDoc.SetViewOptions( aViewOpt );
+ }
+
+ // *** set tab bg color
+ if ( !maData.IsDefaultTabBgColor() )
+ rDoc.SetTabBgColor(nScTab, maData.maTabBgColor);
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xladdress.cxx b/sc/source/filter/excel/xladdress.cxx
new file mode 100644
index 000000000000..e66251b33bde
--- /dev/null
+++ b/sc/source/filter/excel/xladdress.cxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xladdress.hxx"
+#include "xestream.hxx"
+#include "xltracer.hxx"
+#include "xistream.hxx"
+
+// ============================================================================
+
+void XclAddress::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ mnRow = rStrm.ReaduInt16();
+ if( bCol16Bit )
+ rStrm >> mnCol;
+ else
+ mnCol = rStrm.ReaduInt8();
+}
+
+void XclAddress::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ rStrm << static_cast<sal_uInt16> (mnRow);
+ if( bCol16Bit )
+ rStrm << mnCol;
+ else
+ rStrm << static_cast< sal_uInt8 >( mnCol );
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclRange::Contains( const XclAddress& rPos ) const
+{
+ return (maFirst.mnCol <= rPos.mnCol) && (rPos.mnCol <= maLast.mnCol) &&
+ (maFirst.mnRow <= rPos.mnRow) && (rPos.mnRow <= maLast.mnRow);
+}
+
+void XclRange::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ maFirst.mnRow = rStrm.ReaduInt16();
+ maLast.mnRow = rStrm.ReaduInt16();
+
+ if( bCol16Bit )
+ rStrm >> maFirst.mnCol >> maLast.mnCol;
+ else
+ {
+ maFirst.mnCol = rStrm.ReaduInt8();
+ maLast.mnCol = rStrm.ReaduInt8();
+ }
+}
+
+void XclRange::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ rStrm << static_cast<sal_uInt16>(maFirst.mnRow) << static_cast<sal_uInt16>(maLast.mnRow);
+ if( bCol16Bit )
+ rStrm << maFirst.mnCol << maLast.mnCol;
+ else
+ rStrm << static_cast< sal_uInt8 >( maFirst.mnCol ) << static_cast< sal_uInt8 >( maLast.mnCol );
+}
+
+// ----------------------------------------------------------------------------
+
+XclRange XclRangeList::GetEnclosingRange() const
+{
+ XclRange aXclRange;
+ if( !empty() )
+ {
+ const_iterator aIt = begin(), aEnd = end();
+ aXclRange = *aIt;
+ for( ++aIt; aIt != aEnd; ++aIt )
+ {
+ aXclRange.maFirst.mnCol = ::std::min( aXclRange.maFirst.mnCol, aIt->maFirst.mnCol );
+ aXclRange.maFirst.mnRow = ::std::min( aXclRange.maFirst.mnRow, aIt->maFirst.mnRow );
+ aXclRange.maLast.mnCol = ::std::max( aXclRange.maLast.mnCol, aIt->maLast.mnCol );
+ aXclRange.maLast.mnRow = ::std::max( aXclRange.maLast.mnRow, aIt->maLast.mnRow );
+ }
+ }
+ return aXclRange;
+}
+
+void XclRangeList::Read( XclImpStream& rStrm, bool bCol16Bit )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ size_t nOldSize = size();
+ resize( nOldSize + nCount );
+ for( iterator aIt = begin() + nOldSize; rStrm.IsValid() && (nCount > 0); --nCount, ++aIt )
+ aIt->Read( rStrm, bCol16Bit );
+}
+
+void XclRangeList::Write( XclExpStream& rStrm, bool bCol16Bit ) const
+{
+ WriteSubList( rStrm, 0, size(), bCol16Bit );
+}
+
+void XclRangeList::WriteSubList( XclExpStream& rStrm, size_t nBegin, size_t nCount, bool bCol16Bit ) const
+{
+ DBG_ASSERT( nBegin <= size(), "XclRangeList::WriteSubList - invalid start position" );
+ size_t nEnd = ::std::min< size_t >( nBegin + nCount, size() );
+ sal_uInt16 nXclCount = ulimit_cast< sal_uInt16 >( nEnd - nBegin );
+ rStrm << nXclCount;
+ rStrm.SetSliceSize( bCol16Bit ? 8 : 6 );
+ for( const_iterator aIt = begin() + nBegin, aEnd = begin() + nEnd; aIt != aEnd; ++aIt )
+ aIt->Write( rStrm, bCol16Bit );
+}
+
+// ============================================================================
+
+XclAddressConverterBase::XclAddressConverterBase( XclTracer& rTracer, const ScAddress& rMaxPos ) :
+ mrTracer( rTracer ),
+ maMaxPos( rMaxPos ),
+ mnMaxCol( static_cast< sal_uInt16 >( rMaxPos.Col() ) ),
+ mnMaxRow( static_cast< sal_uInt16 >( rMaxPos.Row() ) ),
+ mbColTrunc( false ),
+ mbRowTrunc( false ),
+ mbTabTrunc( false )
+{
+ DBG_ASSERT( static_cast< size_t >( rMaxPos.Col() ) <= SAL_MAX_UINT16, "XclAddressConverterBase::XclAddressConverterBase - invalid max column" );
+ DBG_ASSERT( static_cast< size_t >( rMaxPos.Row() ) <= SAL_MAX_UINT32, "XclAddressConverterBase::XclAddressConverterBase - invalid max row" );
+}
+
+XclAddressConverterBase::~XclAddressConverterBase()
+{
+}
+
+bool XclAddressConverterBase::CheckScTab( SCTAB nScTab, bool bWarn )
+{
+ bool bValid = (0 <= nScTab) && (nScTab <= maMaxPos.Tab());
+ if( !bValid && bWarn )
+ {
+ mbTabTrunc |= (nScTab > maMaxPos.Tab()); // do not warn for deleted refs
+ mrTracer.TraceInvalidTab( nScTab, maMaxPos.Tab() );
+ }
+ return bValid;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx
new file mode 100644
index 000000000000..033468998ea5
--- /dev/null
+++ b/sc/source/filter/excel/xlchart.cxx
@@ -0,0 +1,1351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlchart.hxx"
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#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/Symbol.hpp>
+
+#include <sal/macros.h>
+#include <rtl/math.hxx>
+#include <svl/itemset.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/unomid.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include <editeng/memberids.hrc>
+#include "global.hxx"
+#include "xlroot.hxx"
+#include "xlstyle.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::chart2::XChartDocument;
+using ::com::sun::star::drawing::XShape;
+
+namespace cssc = ::com::sun::star::chart;
+
+// Common =====================================================================
+
+XclChRectangle::XclChRectangle() :
+ mnX( 0 ),
+ mnY( 0 ),
+ mnWidth( 0 ),
+ mnHeight( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
+ mnSeriesIdx( nSeriesIdx ),
+ mnPointIdx( nPointIdx )
+{
+}
+
+bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR )
+{
+ return (rL.mnSeriesIdx < rR.mnSeriesIdx) ||
+ ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx));
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
+ mnType( nType ),
+ mnContext( 0 ),
+ mnValue1( 0 ),
+ mnValue2( 0 )
+{
+}
+
+// Frame formatting ===========================================================
+
+XclChFramePos::XclChFramePos() :
+ mnTLMode( EXC_CHFRAMEPOS_PARENT ),
+ mnBRMode( EXC_CHFRAMEPOS_PARENT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChLineFormat::XclChLineFormat() :
+ maColor( COL_BLACK ),
+ mnPattern( EXC_CHLINEFORMAT_SOLID ),
+ mnWeight( EXC_CHLINEFORMAT_SINGLE ),
+ mnFlags( EXC_CHLINEFORMAT_AUTO )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAreaFormat::XclChAreaFormat() :
+ maPattColor( COL_WHITE ),
+ maBackColor( COL_BLACK ),
+ mnPattern( EXC_PATT_SOLID ),
+ mnFlags( EXC_CHAREAFORMAT_AUTO )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChEscherFormat::XclChEscherFormat()
+{
+}
+
+XclChEscherFormat::~XclChEscherFormat()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChPicFormat::XclChPicFormat() :
+ mnBmpMode( EXC_CHPICFORMAT_NONE ),
+ mnFormat( EXC_CHPICFORMAT_DEFAULT ),
+ mnFlags( EXC_CHPICFORMAT_DEFAULTFLAGS ),
+ mfScale( 0.5 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrame::XclChFrame() :
+ mnFormat( EXC_CHFRAME_STANDARD ),
+ mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
+{
+}
+
+// Source links ===============================================================
+
+XclChSourceLink::XclChSourceLink() :
+ mnDestType( EXC_CHSRCLINK_TITLE ),
+ mnLinkType( EXC_CHSRCLINK_DEFAULT ),
+ mnFlags( 0 ),
+ mnNumFmtIdx( 0 )
+{
+}
+
+// Text =======================================================================
+
+XclChObjectLink::XclChObjectLink() :
+ mnTarget( EXC_CHOBJLINK_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFrLabelProps::XclChFrLabelProps() :
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChText::XclChText() :
+ maTextColor( COL_BLACK ),
+ mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
+ mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
+ mnBackMode( EXC_CHTEXT_TRANSPARENT ),
+ mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
+ mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
+ mnRotation( EXC_ROT_NONE )
+{
+}
+
+// Data series ================================================================
+
+XclChMarkerFormat::XclChMarkerFormat() :
+ maLineColor( COL_BLACK ),
+ maFillColor( COL_WHITE ),
+ mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
+ mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
+ mnFlags( EXC_CHMARKERFORMAT_AUTO )
+{
+};
+
+// ----------------------------------------------------------------------------
+
+XclCh3dDataFormat::XclCh3dDataFormat() :
+ mnBase( EXC_CH3DDATAFORMAT_RECT ),
+ mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChDataFormat::XclChDataFormat() :
+ mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSerTrendLine::XclChSerTrendLine() :
+ mfForecastFor( 0.0 ),
+ mfForecastBack( 0.0 ),
+ mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
+ mnOrder( 1 ),
+ mnShowEquation( 0 ),
+ mnShowRSquared( 0 )
+{
+ /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
+ there is no interception point. Cannot use ::rtl::math::setNan() here
+ cause it misses the sign bit. */
+ sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
+ pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSerErrorBar::XclChSerErrorBar() :
+ mfValue( 0.0 ),
+ mnValueCount( 1 ),
+ mnBarType( EXC_CHSERERR_NONE ),
+ mnSourceType( EXC_CHSERERR_FIXED ),
+ mnLineEnd( EXC_CHSERERR_END_TSHAPE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChSeries::XclChSeries() :
+ mnCategType( EXC_CHSERIES_NUMERIC ),
+ mnValueType( EXC_CHSERIES_NUMERIC ),
+ mnBubbleType( EXC_CHSERIES_NUMERIC ),
+ mnCategCount( 0 ),
+ mnValueCount( 0 ),
+ mnBubbleCount( 0 )
+{
+}
+
+// Chart type groups ==========================================================
+
+XclChType::XclChType() :
+ mnOverlap( 0 ),
+ mnGap( 150 ),
+ mnRotation( 0 ),
+ mnPieHole( 0 ),
+ mnBubbleSize( 100 ),
+ mnBubbleType( EXC_CHSCATTER_AREA ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChChart3d::XclChChart3d() :
+ mnRotation( 20 ),
+ mnElevation( 15 ),
+ mnEyeDist( 30 ),
+ mnRelHeight( 100 ),
+ mnRelDepth( 100 ),
+ mnDepthGap( 150 ),
+ mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChLegend::XclChLegend() :
+ mnDockMode( EXC_CHLEGEND_RIGHT ),
+ mnSpacing( EXC_CHLEGEND_MEDIUM ),
+ mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
+ EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTypeGroup::XclChTypeGroup() :
+ mnFlags( 0 ),
+ mnGroupIdx( EXC_CHSERGROUP_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChProperties::XclChProperties() :
+ mnFlags( 0 ),
+ mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
+{
+}
+
+// Axes =======================================================================
+
+XclChLabelRange::XclChLabelRange() :
+ mnCross( 1 ),
+ mnLabelFreq( 1 ),
+ mnTickFreq( 1 ),
+ mnFlags( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChDateRange::XclChDateRange() :
+ mnMinDate( 0 ),
+ mnMaxDate( 0 ),
+ mnMajorStep( 0 ),
+ mnMajorUnit( EXC_CHDATERANGE_DAYS ),
+ mnMinorStep( 0 ),
+ mnMinorUnit( EXC_CHDATERANGE_DAYS ),
+ mnBaseUnit( EXC_CHDATERANGE_DAYS ),
+ mnCross( 0 ),
+ mnFlags( EXC_CHDATERANGE_AUTOMIN | EXC_CHDATERANGE_AUTOMAX |
+ EXC_CHDATERANGE_AUTOMAJOR | EXC_CHDATERANGE_AUTOMINOR |
+ EXC_CHDATERANGE_AUTOBASE | EXC_CHDATERANGE_AUTOCROSS |
+ EXC_CHDATERANGE_AUTODATE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChValueRange::XclChValueRange() :
+ mfMin( 0.0 ),
+ mfMax( 0.0 ),
+ mfMajorStep( 0.0 ),
+ mfMinorStep( 0.0 ),
+ mfCross( 0.0 ),
+ mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
+ EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR |
+ EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTick::XclChTick() :
+ maTextColor( COL_BLACK ),
+ mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
+ mnMinor( 0 ),
+ mnLabelPos( EXC_CHTICK_NEXT ),
+ mnBackMode( EXC_CHTICK_TRANSPARENT ),
+ mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
+ mnRotation( EXC_ROT_NONE )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAxis::XclChAxis() :
+ mnType( EXC_CHAXIS_NONE )
+{
+}
+
+sal_Int32 XclChAxis::GetApiAxisDimension() const
+{
+ sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
+ switch( mnType )
+ {
+ case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
+ case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
+ case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
+ }
+ return nApiAxisDim;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChAxesSet::XclChAxesSet() :
+ mnAxesSetId( EXC_CHAXESSET_PRIMARY )
+{
+}
+
+sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
+{
+ sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
+ switch( mnAxesSetId )
+ {
+ case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
+ case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
+ }
+ return nApiAxesSetIdx;
+}
+
+// Static helper functions ====================================================
+
+sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnLineColors[] =
+ {
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 63
+ };
+ return spnLineColors[ nFormatIdx % SAL_N_ELEMENTS( spnLineColors ) ];
+}
+
+sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnFillColors[] =
+ {
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23
+ };
+ return spnFillColors[ nFormatIdx % SAL_N_ELEMENTS( spnFillColors ) ];
+}
+
+sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
+ return spnTrans[ (nFormatIdx / 56) % SAL_N_ELEMENTS( spnTrans ) ];
+}
+
+sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
+{
+ static const sal_uInt16 spnSymbols[] = {
+ EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
+ EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
+ EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
+ return spnSymbols[ nFormatIdx % SAL_N_ELEMENTS( spnSymbols ) ];
+}
+
+bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
+{
+ static const bool spbFilled[] = {
+ false, true, true, true, false, false, false, false, true, false };
+ return (nMarkerType < SAL_N_ELEMENTS( spbFilled )) && spbFilled[ nMarkerType ];
+}
+
+OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
+{
+ switch( nBarType )
+ {
+ case EXC_CHSERERR_XPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSX;
+ case EXC_CHSERERR_XMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGX;
+ case EXC_CHSERERR_YPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSY;
+ case EXC_CHSERERR_YMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGY;
+ default: DBG_ERRORFILE( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
+ }
+ return OUString();
+}
+
+// Chart formatting info provider =============================================
+
+namespace {
+
+static const XclChFormatInfo spFmtInfos[] =
+{
+ // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
+ { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
+ { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
+ { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
+ { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
+ { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
+ { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
+ { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
+ { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
+ { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
+ { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
+ { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
+ { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
+ { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
+};
+
+}
+
+// ----------------------------------------------------------------------------
+
+XclChFormatInfoProvider::XclChFormatInfoProvider()
+{
+ const XclChFormatInfo* pEnd = STATIC_TABLE_END( spFmtInfos );
+ for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt )
+ maInfoMap[ pIt->meObjType ] = pIt;
+}
+
+const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
+{
+ XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
+ DBG_ASSERT( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
+ return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
+}
+
+// Chart type info provider ===================================================
+
+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 = cssc::DataLabelPlacement;
+
+static const XclChTypeInfo spTypeInfos[] =
+{
+ // chart type chart type category record id service varied point color def label pos comb2d 3d polar area2d area3d 1stvis xcateg swap stack revers betw
+ { EXC_CHTYPEID_BAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true },
+ { EXC_CHTYPEID_HORBAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, false, true, false, true, true, false, true, true, true, false, true },
+ { EXC_CHTYPEID_LINE, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_LINE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, true, false, false, true, false, true, false, true, false, false },
+ { EXC_CHTYPEID_AREA, EXC_CHTYPECATEG_LINE, EXC_ID_CHAREA, SERVICE_CHART2_AREA, EXC_CHVARPOINT_NONE, csscd::CENTER, true, true, false, true, true, false, true, false, true, true, false },
+ { EXC_CHTYPEID_STOCK, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_CANDLE, EXC_CHVARPOINT_NONE, csscd::RIGHT, true, false, false, false, false, false, true, false, true, false, false },
+ { EXC_CHTYPEID_RADARLINE, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARLINE, SERVICE_CHART2_NET, EXC_CHVARPOINT_SINGLE, csscd::TOP, false, false, true, false, true, false, true, false, false, false, false },
+ { EXC_CHTYPEID_RADARAREA, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARAREA, SERVICE_CHART2_FILLEDNET, EXC_CHVARPOINT_NONE, csscd::TOP, false, false, true, true, true, false, true, false, false, true, false },
+ { EXC_CHTYPEID_PIE, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, true, false, false, false, false },
+ { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, true, false },
+ { EXC_CHTYPEID_PIEEXT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIEEXT, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, false, true, true, true, true, true, false, false, false, false },
+ { EXC_CHTYPEID_SCATTER, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, false, false, false, true, false, false, false, false, false, false },
+ { EXC_CHTYPEID_BUBBLES, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_BUBBLE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, true, false, false, false, false, false, false },
+ { EXC_CHTYPEID_SURFACE, EXC_CHTYPECATEG_SURFACE, EXC_ID_CHSURFACE, SERVICE_CHART2_SURFACE, EXC_CHVARPOINT_NONE, csscd::RIGHT, false, true, false, true, true, false, true, false, false, false, false },
+ { EXC_CHTYPEID_UNKNOWN, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true }
+};
+
+} // namespace
+
+XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
+ XclChTypeInfo( rTypeInfo ),
+ mb3dChart( false ),
+ mbSpline( false )
+{
+}
+
+void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
+{
+ static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
+ mb3dChart = mbSupports3d && b3dChart;
+ mbSpline = bSpline;
+}
+
+// ----------------------------------------------------------------------------
+
+XclChTypeInfoProvider::XclChTypeInfoProvider()
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ maInfoMap[ pIt->meTypeId ] = pIt;
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
+{
+ XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
+ DBG_ASSERT( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
+ return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ if( pIt->mnRecId == nRecId )
+ return *pIt;
+ DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
+ return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
+}
+
+const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
+{
+ const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
+ for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ if( rServiceName.equalsAscii( pIt->mpcServiceName ) )
+ return *pIt;
+ DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
+ return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
+}
+
+// Property helpers ===========================================================
+
+XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory,
+ const OUString& rServiceName, const OUString& rObjNameBase ) :
+ mxFactory( xFactory ),
+ maServiceName( rServiceName ),
+ maObjNameBase( rObjNameBase ),
+ mnIndex( 0 )
+{
+}
+
+Any XclChObjectTable::GetObject( const OUString& rObjName )
+{
+ // get object table
+ if( !mxContainer.is() )
+ mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
+ DBG_ASSERT( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
+
+ Any aObj;
+ if( mxContainer.is() )
+ {
+ // get object from container
+ try
+ {
+ aObj = mxContainer->getByName( rObjName );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" );
+ }
+ }
+ return aObj;
+}
+
+OUString XclChObjectTable::InsertObject( const Any& rObj )
+{
+
+ // create object table
+ if( !mxContainer.is() )
+ mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
+ DBG_ASSERT( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
+
+ OUString aObjName;
+ if( mxContainer.is() )
+ {
+ // create new unused identifier
+ do
+ {
+ aObjName = maObjNameBase + OUString::valueOf( ++mnIndex );
+ }
+ while( mxContainer->hasByName( aObjName ) );
+
+ // insert object
+ try
+ {
+ mxContainer->insertByName( aObjName, rObj );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" );
+ aObjName = OUString();
+ }
+ }
+ return aObjName;
+}
+
+// Property names -------------------------------------------------------------
+
+namespace {
+
+/** Property names for line style in common objects. */
+const sal_Char* const sppcLineNamesCommon[] =
+ { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
+/** Property names for line style in linear series objects. */
+const sal_Char* const sppcLineNamesLinear[] =
+ { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
+/** Property names for line style in filled series objects. */
+const sal_Char* const sppcLineNamesFilled[] =
+ { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
+
+/** Property names for solid area style in common objects. */
+const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
+/** Property names for solid area style in filled series objects. */
+const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", 0 };
+/** Property names for gradient area style in common objects. */
+const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", 0 };
+/** Property names for gradient area style in filled series objects. */
+const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", 0 };
+/** Property names for hatch area style in common objects. */
+const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
+/** Property names for hatch area style in filled series objects. */
+const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
+/** Property names for bitmap area style. */
+const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclChPropSetHelper::XclChPropSetHelper() :
+ maLineHlpCommon( sppcLineNamesCommon ),
+ maLineHlpLinear( sppcLineNamesLinear ),
+ maLineHlpFilled( sppcLineNamesFilled ),
+ maAreaHlpCommon( sppcAreaNamesCommon ),
+ maAreaHlpFilled( sppcAreaNamesFilled ),
+ maGradHlpCommon( sppcGradNamesCommon ),
+ maGradHlpFilled( sppcGradNamesFilled ),
+ maHatchHlpCommon( sppcHatchNamesCommon ),
+ maHatchHlpFilled( sppcHatchNamesFilled ),
+ maBitmapHlp( sppcBitmapNames )
+{
+}
+
+// read properties ------------------------------------------------------------
+
+void XclChPropSetHelper::ReadLineProperties(
+ XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // read properties from property set
+ cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
+ sal_Int32 nApiWidth = 0;
+ sal_Int16 nApiTrans = 0;
+ Any aDashNameAny;
+
+ ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
+ rLineHlp.ReadFromPropertySet( rPropSet );
+ rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
+
+ // clear automatic flag
+ ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
+
+ // line width
+ if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
+ else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
+ else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
+ else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
+
+ // line style
+ switch( eApiStyle )
+ {
+ case cssd::LineStyle_NONE:
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ break;
+ case cssd::LineStyle_SOLID:
+ {
+ if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
+ else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
+ else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
+ else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
+ }
+ break;
+ case cssd::LineStyle_DASH:
+ {
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ OUString aDashName;
+ cssd::LineDash aApiDash;
+ if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
+ {
+ // reorder dashes that are shorter than dots
+ if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
+ {
+ ::std::swap( aApiDash.Dashes, aApiDash.Dots );
+ ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
+ }
+ // ignore dots that are nearly equal to dashes
+ if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
+ aApiDash.Dots = 0;
+
+ // convert line dash to predefined Excel dash types
+ if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
+ // one dash and one or more dots
+ rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
+ EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
+ else if( aApiDash.Dashes >= 1 )
+ // one or more dashes and no dots (also: dash-dash-dot)
+ rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
+ EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
+ rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
+ }
+}
+
+bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // read properties from property set
+ cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
+ sal_Int16 nTransparency = 0;
+
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.ReadFromPropertySet( rPropSet );
+ rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
+
+ // clear automatic flag
+ ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
+
+ // set fill style transparent or solid (set solid for anything but transparent)
+ rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
+
+ // return true to indicate complex fill (gradient, bitmap, solid transparency)
+ return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0));
+}
+
+void XclChPropSetHelper::ReadEscherProperties(
+ XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
+ XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
+ const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+ namespace cssa = ::com::sun::star::awt;
+
+ // read style and transparency properties from property set
+ cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
+ Color aColor;
+ sal_Int16 nTransparency = 0;
+
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.ReadFromPropertySet( rPropSet );
+ rAreaHlp >> eApiStyle >> aColor >> nTransparency;
+
+ switch( eApiStyle )
+ {
+ case cssd::FillStyle_SOLID:
+ {
+ DBG_ASSERT( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
+ if( (0 < nTransparency) && (nTransparency <= 100) )
+ {
+ // convert to Escher properties
+ sal_uInt32 nEscherColor = 0x02000000;
+ ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
+ ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
+ ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
+ sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
+ rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
+ }
+ }
+ break;
+ case cssd::FillStyle_GRADIENT:
+ {
+ // extract gradient from global gradient table
+ OUString aGradientName;
+ ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
+ rGradHlp.ReadFromPropertySet( rPropSet );
+ rGradHlp >> eApiStyle >> aGradientName;
+ cssa::Gradient aGradient;
+ if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
+ }
+ }
+ break;
+ case cssd::FillStyle_HATCH:
+ {
+ // extract hatch from global hatch table
+ OUString aHatchName;
+ bool bFillBackground;
+ ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
+ rHatchHlp.ReadFromPropertySet( rPropSet );
+ rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
+ cssd::Hatch aHatch;
+ if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
+ rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
+ }
+ }
+ break;
+ case cssd::FillStyle_BITMAP:
+ {
+ // extract bitmap URL from global bitmap table
+ OUString aBitmapName;
+ cssd::BitmapMode eApiBmpMode;
+ maBitmapHlp.ReadFromPropertySet( rPropSet );
+ maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
+ OUString aBitmapUrl;
+ if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl )
+ {
+ // convert to Escher properties
+ rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
+ rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode );
+ rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ?
+ EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
+ }
+}
+
+void XclChPropSetHelper::ReadMarkerProperties(
+ XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
+{
+ namespace cssc = ::com::sun::star::chart2;
+ namespace cssa = ::com::sun::star::awt;
+ cssc::Symbol aApiSymbol;
+ if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
+ {
+ // clear automatic flag
+ ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
+
+ // symbol style
+ switch( aApiSymbol.Style )
+ {
+ case cssc::SymbolStyle_NONE:
+ rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
+ break;
+ case cssc::SymbolStyle_STANDARD:
+ switch( aApiSymbol.StandardSymbol )
+ {
+ case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
+ case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
+ case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
+ case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
+ case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // arrow right
+ case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
+ case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
+ case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
+ default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ }
+ break;
+ default:
+ rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
+ }
+ bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
+ ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
+
+ // symbol size
+ sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
+ rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
+
+ // symbol colors
+ rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
+ rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
+ }
+}
+
+sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
+{
+ // chart2 handles rotation as double in the range [0,360)
+ double fAngle = 0.0;
+ rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
+ bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
+ return bStacked ? EXC_ROT_STACKED :
+ XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
+}
+
+// write properties -----------------------------------------------------------
+
+void XclChPropSetHelper::WriteLineProperties(
+ ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
+ const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+
+ // line width
+ sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
+ switch( rLineFmt.mnWeight )
+ {
+ case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
+ case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
+ case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
+ }
+
+ // line style
+ cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
+ sal_Int16 nApiTrans = 0;
+ sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
+ cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
+
+ switch( rLineFmt.mnPattern )
+ {
+ case EXC_CHLINEFORMAT_SOLID:
+ eApiStyle = cssd::LineStyle_SOLID;
+ break;
+ case EXC_CHLINEFORMAT_DARKTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
+ break;
+ case EXC_CHLINEFORMAT_MEDTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
+ break;
+ case EXC_CHLINEFORMAT_LIGHTTRANS:
+ eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
+ break;
+ case EXC_CHLINEFORMAT_DASH:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
+ break;
+ case EXC_CHLINEFORMAT_DOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
+ break;
+ case EXC_CHLINEFORMAT_DASHDOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
+ break;
+ case EXC_CHLINEFORMAT_DASHDOTDOT:
+ eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
+ break;
+ }
+
+ // line color
+ sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
+
+ // try to insert the dash style and receive its name
+ Any aDashNameAny;
+ if( eApiStyle == cssd::LineStyle_DASH )
+ {
+ OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) );
+ if( aDashName.getLength() )
+ aDashNameAny <<= aDashName;
+ }
+
+ // write the properties
+ ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
+ rLineHlp.InitializeWrite();
+ rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
+ rLineHlp.WriteToPropertySet( rPropSet );
+}
+
+void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
+{
+ namespace cssd = ::com::sun::star::drawing;
+ cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
+ Color aColor;
+ sal_Int16 nTransparency = 0;
+
+ // fill color
+ if( rAreaFmt.mnPattern != EXC_PATT_NONE )
+ {
+ eFillStyle = cssd::FillStyle_SOLID;
+ aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
+ }
+
+ // write the properties
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.InitializeWrite();
+ rAreaHlp << eFillStyle << aColor << nTransparency;
+ rAreaHlp.WriteToPropertySet( rPropSet );
+}
+
+void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
+ XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
+ const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode )
+{
+ if( rEscherFmt.mxItemSet )
+ {
+ if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, false ) ) )
+ {
+ switch( pStyleItem->GetValue() )
+ {
+ case XFILL_SOLID:
+ // #i84812# Excel 2007 writes Escher properties for solid fill
+ if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, false ) ) )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ // get solid transparence too
+ const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, false ) );
+ sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
+ ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
+ rAreaHlp.InitializeWrite();
+ rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
+ rAreaHlp.WriteToPropertySet( rPropSet );
+ }
+ break;
+ case XFILL_GRADIENT:
+ if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, false ) ) )
+ {
+ Any aGradientAny;
+ if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
+ {
+ OUString aGradName = rGradientTable.InsertObject( aGradientAny );
+ if( aGradName.getLength() )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
+ rGradHlp.InitializeWrite();
+ rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
+ rGradHlp.WriteToPropertySet( rPropSet );
+ }
+ }
+ }
+ break;
+ case XFILL_BITMAP:
+ if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, false ) ) )
+ {
+ Any aBitmapAny;
+ if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
+ {
+ OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
+ if( aBmpName.getLength() )
+ {
+ namespace cssd = ::com::sun::star::drawing;
+ cssd::BitmapMode eApiBmpMode = (rPicFmt.mnBmpMode == EXC_CHPICFORMAT_STRETCH) ?
+ cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
+ maBitmapHlp.InitializeWrite();
+ maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
+ maBitmapHlp.WriteToPropertySet( rPropSet );
+ }
+ }
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
+ }
+ }
+ }
+}
+
+void XclChPropSetHelper::WriteMarkerProperties(
+ ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
+{
+ namespace cssc = ::com::sun::star::chart2;
+ namespace cssa = ::com::sun::star::awt;
+
+ // symbol style
+ cssc::Symbol aApiSymbol;
+ aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
+ switch( rMarkerFmt.mnMarkerType )
+ {
+ case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break;
+ case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
+ case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
+ case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
+ case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 6; break; // bow tie
+ case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 7; break; // sand glass
+ case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right
+ case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 2; break; // arrow down
+ case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 4; break; // arrow right
+ case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 5; break; // arrow left
+ }
+
+ // symbol size
+ sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
+ aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
+
+ // symbol colors
+ aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
+ aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
+ aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
+
+ // set the property
+ rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
+}
+
+void XclChPropSetHelper::WriteRotationProperties(
+ ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
+{
+ if( nRotation != EXC_CHART_AUTOROTATION )
+ {
+ // chart2 handles rotation as double in the range [0,360)
+ double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
+ rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
+ if( bSupportsStacked )
+ rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
+ case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
+ }
+ return maLineHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
+ }
+ return maAreaHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
+ }
+ return maGradHlpCommon;
+}
+
+ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
+{
+ switch( ePropMode )
+ {
+ case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
+ case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
+ default: DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
+ }
+ return maHatchHlpCommon;
+}
+
+// ============================================================================
+
+namespace {
+
+/* 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 EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
+ ScfPropertySet aPropSet( shape_supplier ); \
+ if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #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 EXC_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 ); \
+ EXC_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 )
+{
+ EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
+}
+
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
+EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
+
+#undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
+#undef EXC_IMPLEMENT_GETTITLESHAPE
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclChRootData::XclChRootData() :
+ mxTypeInfoProv( new XclChTypeInfoProvider ),
+ mxFmtInfoProv( new XclChFormatInfoProvider ),
+ mnBorderGapX( 0 ),
+ mnBorderGapY( 0 )
+{
+ // remember some title shape getter functions
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
+ maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
+}
+
+XclChRootData::~XclChRootData()
+{
+}
+
+void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
+{
+ // remember chart document reference and chart shape position/size
+ DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
+ mxChartDoc = rxChartDoc;
+ maChartRect = rChartRect;
+
+ // Excel excludes a border of 5 pixels in each direction from chart area
+ mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
+ mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
+
+ // size of a chart unit in 1/100 mm
+ mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
+ mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
+
+ // create object tables
+ Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
+ mxLineDashTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_DASHTABLE, CREATE_OUSTRING( "Excel line dash " ) ) );
+ mxGradientTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_GRADIENTTABLE, CREATE_OUSTRING( "Excel gradient " ) ) );
+ mxHatchTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_HATCHTABLE, CREATE_OUSTRING( "Excel hatch " ) ) );
+ mxBitmapTable.reset( new XclChObjectTable(
+ xFactory, SERVICE_DRAWING_BITMAPTABLE, CREATE_OUSTRING( "Excel bitmap " ) ) );
+}
+
+void XclChRootData::FinishConversion()
+{
+ // forget formatting object tables
+ mxBitmapTable.reset();
+ mxHatchTable.reset();
+ mxGradientTable.reset();
+ mxLineDashTable.reset();
+ // forget chart document reference
+ mxChartDoc.clear();
+}
+
+Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
+{
+ XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
+ OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
+ Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
+ Reference< XShape > xTitleShape;
+ if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
+ xTitleShape = (aIt->second)( xChart1Doc );
+ return xTitleShape;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx
new file mode 100644
index 000000000000..7c531a64d018
--- /dev/null
+++ b/sc/source/filter/excel/xlescher.cxx
@@ -0,0 +1,382 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlescher.hxx"
+
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <svx/unoapi.hxx>
+#include "document.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xlroot.hxx"
+#include "xltools.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XControlShape;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::script::ScriptEventDescriptor;
+
+// Structs and classes ========================================================
+
+XclObjId::XclObjId() :
+ mnScTab( SCTAB_INVALID ),
+ mnObjId( EXC_OBJ_INVALID_ID )
+{
+}
+
+XclObjId::XclObjId( SCTAB nScTab, sal_uInt16 nObjId ) :
+ mnScTab( nScTab ),
+ mnObjId( nObjId )
+{
+}
+
+bool operator==( const XclObjId& rL, const XclObjId& rR )
+{
+ return (rL.mnScTab == rR.mnScTab) && (rL.mnObjId == rR.mnObjId);
+}
+
+bool operator<( const XclObjId& rL, const XclObjId& rR )
+{
+ return (rL.mnScTab < rR.mnScTab) || ((rL.mnScTab == rR.mnScTab) && (rL.mnObjId < rR.mnObjId));
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Returns the scaling factor to calculate coordinates from twips. */
+double lclGetTwipsScale( MapUnit eMapUnit )
+{
+ /* We cannot use OutputDevice::LogicToLogic() or the XclTools
+ conversion functions to calculate drawing layer coordinates due to
+ Calc's strange definition of a point (1 inch == 72.27 points, instead
+ of 72 points). */
+ double fScale = 1.0;
+ switch( eMapUnit )
+ {
+ case MAP_TWIP: fScale = 72 / POINTS_PER_INCH; break; // Calc twips <-> real twips
+ case MAP_100TH_MM: fScale = HMM_PER_TWIPS; break; // Calc twips <-> 1/100mm
+ default: DBG_ERRORFILE( "lclGetTwipsScale - map unit not implemented" );
+ }
+ return fScale;
+}
+
+/** Calculates a drawing layer X position (in twips) from an object column position. */
+long lclGetXFromCol( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nXclCol, sal_uInt16 nOffset, double fScale )
+{
+ SCCOL nScCol = static_cast< SCCOL >( nXclCol );
+ return static_cast< long >( fScale * (rDoc.GetColOffset( nScCol, nScTab ) +
+ ::std::min( nOffset / 1024.0, 1.0 ) * rDoc.GetColWidth( nScCol, nScTab )) + 0.5 );
+}
+
+/** Calculates a drawing layer Y position (in twips) from an object row position. */
+long lclGetYFromRow( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nXclRow, sal_uInt16 nOffset, double fScale )
+{
+ SCROW nScRow = static_cast< SCROW >( nXclRow );
+ return static_cast< long >( fScale * (rDoc.GetRowOffset( nScRow, nScTab ) +
+ ::std::min( nOffset / 256.0, 1.0 ) * rDoc.GetRowHeight( nScRow, nScTab )) + 0.5 );
+}
+
+/** Calculates an object column position from a drawing layer X position (in twips). */
+void lclGetColFromX(
+ ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnXclCol,
+ sal_uInt16& rnOffset, sal_uInt16 nXclStartCol, sal_uInt16 nXclMaxCol,
+ long& rnStartW, long nX, double fScale )
+{
+ // rnStartW in conjunction with nXclStartCol is used as buffer for previously calculated width
+ long nTwipsX = static_cast< long >( nX / fScale + 0.5 );
+ long nColW = 0;
+ for( rnXclCol = nXclStartCol; rnXclCol <= nXclMaxCol; ++rnXclCol )
+ {
+ nColW = rDoc.GetColWidth( static_cast< SCCOL >( rnXclCol ), nScTab );
+ if( rnStartW + nColW > nTwipsX )
+ break;
+ rnStartW += nColW;
+ }
+ rnOffset = nColW ? static_cast< sal_uInt16 >( (nTwipsX - rnStartW) * 1024.0 / nColW + 0.5 ) : 0;
+}
+
+/** Calculates an object row position from a drawing layer Y position (in twips). */
+void lclGetRowFromY(
+ ScDocument& rDoc, SCTAB nScTab, sal_uInt32& rnXclRow,
+ sal_uInt32& rnOffset, sal_uInt32 nXclStartRow, sal_uInt32 nXclMaxRow,
+ long& rnStartH, long nY, double fScale )
+{
+ // rnStartH in conjunction with nXclStartRow is used as buffer for previously calculated height
+ long nTwipsY = static_cast< long >( nY / fScale + 0.5 );
+ long nRowH = 0;
+ bool bFound = false;
+ for( SCROW nRow = static_cast< SCROW >( nXclStartRow ); static_cast<unsigned>(nRow) <= nXclMaxRow; ++nRow )
+ {
+ nRowH = rDoc.GetRowHeight( nRow, nScTab );
+ if( rnStartH + nRowH > nTwipsY )
+ {
+ rnXclRow = static_cast< sal_uInt32 >( nRow );
+ bFound = true;
+ break;
+ }
+ rnStartH += nRowH;
+ }
+ if( !bFound )
+ rnXclRow = nXclMaxRow;
+ rnOffset = static_cast< sal_uInt32 >( nRowH ? ((nTwipsY - rnStartH) * 256.0 / nRowH + 0.5) : 0 );
+}
+
+/** Mirrors a rectangle (from LTR to RTL layout or vice versa). */
+void lclMirrorRectangle( Rectangle& rRect )
+{
+ long nLeft = rRect.Left();
+ rRect.Left() = -rRect.Right();
+ rRect.Right() = -nLeft;
+}
+
+sal_uInt16 lclGetEmbeddedScale( long nPageSize, sal_Int32 nPageScale, long nPos, double fPosScale )
+{
+ return static_cast< sal_uInt16 >( nPos * fPosScale / nPageSize * nPageScale + 0.5 );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclObjAnchor::XclObjAnchor() :
+ mnLX( 0 ),
+ mnTY( 0 ),
+ mnRX( 0 ),
+ mnBY( 0 )
+{
+}
+
+Rectangle XclObjAnchor::GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ double fScale = lclGetTwipsScale( eMapUnit );
+ Rectangle aRect(
+ lclGetXFromCol( rDoc, nScTab, maFirst.mnCol, mnLX, fScale ),
+ lclGetYFromRow( rDoc, nScTab, maFirst.mnRow, mnTY, fScale ),
+ lclGetXFromCol( rDoc, nScTab, maLast.mnCol, mnRX + 1, fScale ),
+ lclGetYFromRow( rDoc, nScTab, maLast.mnRow, mnBY, fScale ) );
+
+ // adjust coordinates in mirrored sheets
+ if( rDoc.IsLayoutRTL( nScTab ) )
+ lclMirrorRectangle( aRect );
+ return aRect;
+}
+
+void XclObjAnchor::SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ sal_uInt16 nXclMaxCol = rRoot.GetXclMaxPos().Col();
+ sal_uInt16 nXclMaxRow = static_cast<sal_uInt16>( rRoot.GetXclMaxPos().Row());
+
+ // adjust coordinates in mirrored sheets
+ Rectangle aRect( rRect );
+ if( rDoc.IsLayoutRTL( nScTab ) )
+ lclMirrorRectangle( aRect );
+
+ double fScale = lclGetTwipsScale( eMapUnit );
+ long nDummy = 0;
+ lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nXclMaxCol, nDummy, aRect.Left(), fScale );
+ lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nXclMaxCol, nDummy, aRect.Right(), fScale );
+ nDummy = 0;
+ lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nXclMaxRow, nDummy, aRect.Top(), fScale );
+ lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nXclMaxRow, nDummy, aRect.Bottom(), fScale );
+}
+
+void XclObjAnchor::SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY,
+ const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor )
+{
+ double fScale = 1.0;
+ switch( eMapUnit )
+ {
+ case MAP_TWIP: fScale = HMM_PER_TWIPS; break; // Calc twips -> 1/100mm
+ case MAP_100TH_MM: fScale = 1.0; break; // Calc 1/100mm -> 1/100mm
+ default: DBG_ERRORFILE( "XclObjAnchor::SetRect - map unit not implemented" );
+ }
+
+ /* In objects with DFF client anchor, the position of the shape is stored
+ in the cell address components of the client anchor. In old BIFF3-BIFF5
+ objects, the position is stored in the offset components of the anchor. */
+ (bDffAnchor ? maFirst.mnCol : mnLX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Left(), fScale );
+ (bDffAnchor ? maFirst.mnRow : mnTY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Top(), fScale );
+ (bDffAnchor ? maLast.mnCol : mnRX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Right(), fScale );
+ (bDffAnchor ? maLast.mnRow : mnBY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Bottom(), fScale );
+
+ // for safety, clear the other members
+ if( bDffAnchor )
+ mnLX = mnTY = mnRX = mnBY = 0;
+ else
+ Set( 0, 0, 0, 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjLineData::XclObjLineData() :
+ mnColorIdx( EXC_OBJ_LINE_AUTOCOLOR ),
+ mnStyle( EXC_OBJ_LINE_SOLID ),
+ mnWidth( EXC_OBJ_LINE_HAIR ),
+ mnAuto( EXC_OBJ_LINE_AUTO )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjLineData& rLineData )
+{
+ return rStrm
+ >> rLineData.mnColorIdx
+ >> rLineData.mnStyle
+ >> rLineData.mnWidth
+ >> rLineData.mnAuto;
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjFillData::XclObjFillData() :
+ mnBackColorIdx( EXC_OBJ_LINE_AUTOCOLOR ),
+ mnPattColorIdx( EXC_OBJ_FILL_AUTOCOLOR ),
+ mnPattern( EXC_PATT_SOLID ),
+ mnAuto( EXC_OBJ_FILL_AUTO )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjFillData& rFillData )
+{
+ return rStrm
+ >> rFillData.mnBackColorIdx
+ >> rFillData.mnPattColorIdx
+ >> rFillData.mnPattern
+ >> rFillData.mnAuto;
+}
+
+// ----------------------------------------------------------------------------
+
+XclObjTextData::XclObjTextData() :
+ mnTextLen( 0 ),
+ mnFormatSize( 0 ),
+ mnLinkSize( 0 ),
+ mnDefFontIdx( EXC_FONT_APP ),
+ mnFlags( 0 ),
+ mnOrient( EXC_OBJ_ORIENT_NONE ),
+ mnButtonFlags( 0 ),
+ mnShortcut( 0 ),
+ mnShortcutEA( 0 )
+{
+}
+
+void XclObjTextData::ReadObj3( XclImpStream& rStrm )
+{
+ rStrm >> mnTextLen;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFormatSize >> mnDefFontIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFlags >> mnOrient;
+ rStrm.Ignore( 8 );
+}
+
+void XclObjTextData::ReadObj5( XclImpStream& rStrm )
+{
+ rStrm >> mnTextLen;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFormatSize >> mnDefFontIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> mnFlags >> mnOrient;
+ rStrm.Ignore( 2 );
+ rStrm >> mnLinkSize;
+ rStrm.Ignore( 2 );
+ rStrm >> mnButtonFlags >> mnShortcut >> mnShortcutEA;
+}
+
+void XclObjTextData::ReadTxo8( XclImpStream& rStrm )
+{
+ rStrm >> mnFlags >> mnOrient >> mnButtonFlags >> mnShortcut >> mnShortcutEA >> mnTextLen >> mnFormatSize;
+}
+
+// ============================================================================
+
+Reference< XControlModel > XclControlHelper::GetControlModel( Reference< XShape > xShape )
+{
+ Reference< XControlModel > xCtrlModel;
+ Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY );
+ if( xCtrlShape.is() )
+ xCtrlModel = xCtrlShape->getControl();
+ return xCtrlModel;
+}
+
+namespace {
+
+static const struct
+{
+ const sal_Char* mpcListenerType;
+ const sal_Char* mpcEventMethod;
+}
+spTbxListenerData[] =
+{
+ // Attention: MUST be in order of the XclTbxEventType enum!
+ /*EXC_TBX_EVENT_ACTION*/ { "XActionListener", "actionPerformed" },
+ /*EXC_TBX_EVENT_MOUSE*/ { "XMouseListener", "mouseReleased" },
+ /*EXC_TBX_EVENT_TEXT*/ { "XTextListener", "textChanged" },
+ /*EXC_TBX_EVENT_VALUE*/ { "XAdjustmentListener", "adjustmentValueChanged" },
+ /*EXC_TBX_EVENT_CHANGE*/ { "XChangeListener", "changed" }
+};
+
+} // namespace
+
+bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pDocShell )
+{
+ if( rXclMacroName.Len() > 0 )
+ {
+ rDescriptor.ListenerType = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcListenerType );
+ rDescriptor.EventMethod = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcEventMethod );
+ rDescriptor.ScriptType = CREATE_OUSTRING( "Script" );
+ rDescriptor.ScriptCode = XclTools::GetSbMacroUrl( rXclMacroName, pDocShell );
+ return true;
+ }
+ return false;
+}
+
+String XclControlHelper::ExtractFromMacroDescriptor(
+ const ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType, SfxObjectShell* /*pShell*/ )
+{
+ if( (rDescriptor.ScriptCode.getLength() > 0) &&
+ rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( "Script" ) &&
+ rDescriptor.ListenerType.equalsAscii( spTbxListenerData[ eEventType ].mpcListenerType ) &&
+ rDescriptor.EventMethod.equalsAscii( spTbxListenerData[ eEventType ].mpcEventMethod ) )
+ return XclTools::GetXclMacroName( rDescriptor.ScriptCode );
+ return String::EmptyString();
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
new file mode 100644
index 000000000000..336de4ded284
--- /dev/null
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -0,0 +1,788 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlformula.hxx"
+
+#include "compiler.hxx"
+#include "rangenam.hxx"
+#include "token.hxx"
+#include "tokenarray.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xlroot.hxx"
+
+using namespace ::formula;
+
+// Function data ==============================================================
+
+String XclFunctionInfo::GetMacroFuncName() const
+{
+ if( IsMacroFunc() )
+ return String( mpcMacroName, RTL_TEXTENCODING_UTF8 );
+ return EMPTY_STRING;
+}
+
+// abbreviations for function return token class
+const sal_uInt8 R = EXC_TOKCLASS_REF;
+const sal_uInt8 V = EXC_TOKCLASS_VAL;
+const sal_uInt8 A = EXC_TOKCLASS_ARR;
+
+// abbreviations for parameter infos
+#define RO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, false }
+#define RV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, false }
+#define RA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, false }
+#define RR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, false }
+#define RX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, false }
+#define VO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, true }
+#define VV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, true }
+#define VA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, true }
+#define VR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, true }
+#define VX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, true }
+#define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
+#define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true }
+#define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false }
+
+const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available.
+const sal_uInt8 MX = 30; /// Maximum parameter count.
+
+#define EXC_FUNCNAME( ascii ) "_xlfn." ascii
+#define EXC_FUNCNAME_ODF( ascii ) "_xlfnodf." ascii
+
+/** Functions new in BIFF2. */
+static const XclFunctionInfo saFuncTable_2[] =
+{
+ { ocCount, 0, 0, MX, V, { RX }, 0, 0 },
+ { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 },
+ { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 },
+ { ocIsError, 3, 1, 1, V, { VR }, 0, 0 },
+ { ocSum, 4, 0, MX, V, { RX }, 0, 0 },
+ { ocAverage, 5, 1, MX, V, { RX }, 0, 0 },
+ { ocMin, 6, 1, MX, V, { RX }, 0, 0 },
+ { ocMax, 7, 1, MX, V, { RX }, 0, 0 },
+ { ocRow, 8, 0, 1, V, { RO }, 0, 0 },
+ { ocColumn, 9, 0, 1, V, { RO }, 0, 0 },
+ { ocNotAvail, 10, 0, 0, V, {}, 0, 0 },
+ { ocNPV, 11, 2, MX, V, { VR, RX }, 0, 0 },
+ { ocStDev, 12, 1, MX, V, { RX }, 0, 0 },
+ { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 },
+ { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 },
+ { ocSin, 15, 1, 1, V, { VR }, 0, 0 },
+ { ocCos, 16, 1, 1, V, { VR }, 0, 0 },
+ { ocTan, 17, 1, 1, V, { VR }, 0, 0 },
+ { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCot, 18, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocPi, 19, 0, 0, V, {}, 0, 0 },
+ { ocSqrt, 20, 1, 1, V, { VR }, 0, 0 },
+ { ocExp, 21, 1, 1, V, { VR }, 0, 0 },
+ { ocLn, 22, 1, 1, V, { VR }, 0, 0 },
+ { ocLog10, 23, 1, 1, V, { VR }, 0, 0 },
+ { ocAbs, 24, 1, 1, V, { VR }, 0, 0 },
+ { ocInt, 25, 1, 1, V, { VR }, 0, 0 },
+ { ocPlusMinus, 26, 1, 1, V, { VR }, 0, 0 },
+ { ocRound, 27, 2, 2, V, { VR }, 0, 0 },
+ { ocLookup, 28, 2, 3, V, { VR, RA }, 0, 0 },
+ { ocIndex, 29, 2, 4, R, { RA, VV }, 0, 0 },
+ { ocRept, 30, 2, 2, V, { VR }, 0, 0 },
+ { ocMid, 31, 3, 3, V, { VR }, 0, 0 },
+ { ocLen, 32, 1, 1, V, { VR }, 0, 0 },
+ { ocValue, 33, 1, 1, V, { VR }, 0, 0 },
+ { ocTrue, 34, 0, 0, V, {}, 0, 0 },
+ { ocFalse, 35, 0, 0, V, {}, 0, 0 },
+ { ocAnd, 36, 1, MX, V, { RX }, 0, 0 },
+ { ocOr, 37, 1, MX, V, { RX }, 0, 0 },
+ { ocNot, 38, 1, 1, V, { VR }, 0, 0 },
+ { ocMod, 39, 2, 2, V, { VR }, 0, 0 },
+ { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBSum, 41, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBAverage, 42, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocVar, 46, 1, MX, V, { RX }, 0, 0 },
+ { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocText, 48, 2, 2, V, { VR }, 0, 0 },
+ { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocTrend, 50, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocRKP, 51, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocGrowth, 52, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocBW, 56, 3, 5, V, { VR }, 0, 0 },
+ { ocZW, 57, 3, 5, V, { VR }, 0, 0 },
+ { ocZZR, 58, 3, 5, V, { VR }, 0, 0 },
+ { ocRMZ, 59, 3, 5, V, { VR }, 0, 0 },
+ { ocZins, 60, 3, 6, V, { VR }, 0, 0 },
+ { ocMIRR, 61, 3, 3, V, { RA, VR }, 0, 0 },
+ { ocIRR, 62, 1, 2, V, { RA, VR }, 0, 0 },
+ { ocRandom, 63, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocMatch, 64, 2, 3, V, { VR, RX, RR }, 0, 0 },
+ { ocGetDate, 65, 3, 3, V, { VR }, 0, 0 },
+ { ocGetTime, 66, 3, 3, V, { VR }, 0, 0 },
+ { ocGetDay, 67, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMonth, 68, 1, 1, V, { VR }, 0, 0 },
+ { ocGetYear, 69, 1, 1, V, { VR }, 0, 0 },
+ { ocGetDayOfWeek, 70, 1, 1, V, { VR, C }, 0, 0 },
+ { ocGetHour, 71, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMin, 72, 1, 1, V, { VR }, 0, 0 },
+ { ocGetSec, 73, 1, 1, V, { VR }, 0, 0 },
+ { ocGetActTime, 74, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocAreas, 75, 1, 1, V, { RO }, 0, 0 },
+ { ocRows, 76, 1, 1, V, { RO }, 0, 0 },
+ { ocColumns, 77, 1, 1, V, { RO }, 0, 0 },
+ { ocOffset, 78, 3, 5, R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocSearch, 82, 2, 3, V, { VR }, 0, 0 },
+ { ocMatTrans, 83, 1, 1, A, { VO }, 0, 0 },
+ { ocType, 86, 1, 1, V, { VX }, 0, 0 },
+ { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 },
+ { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 },
+ { ocChose, 100, 2, MX, R, { VO, RO }, 0, 0 },
+ { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 },
+ { ocLog, 109, 1, 2, V, { VR }, 0, 0 },
+ { ocChar, 111, 1, 1, V, { VR }, 0, 0 },
+ { ocLower, 112, 1, 1, V, { VR }, 0, 0 },
+ { ocUpper, 113, 1, 1, V, { VR }, 0, 0 },
+ { ocPropper, 114, 1, 1, V, { VR }, 0, 0 },
+ { ocLeft, 115, 1, 2, V, { VR }, 0, 0 },
+ { ocRight, 116, 1, 2, V, { VR }, 0, 0 },
+ { ocExact, 117, 2, 2, V, { VR }, 0, 0 },
+ { ocTrim, 118, 1, 1, V, { VR }, 0, 0 },
+ { ocReplace, 119, 4, 4, V, { VR }, 0, 0 },
+ { ocSubstitute, 120, 3, 4, V, { VR }, 0, 0 },
+ { ocCode, 121, 1, 1, V, { VR }, 0, 0 },
+ { ocFind, 124, 2, 3, V, { VR }, 0, 0 },
+ { ocCell, 125, 1, 2, V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocIsErr, 126, 1, 1, V, { VR }, 0, 0 },
+ { ocIsString, 127, 1, 1, V, { VR }, 0, 0 },
+ { ocIsValue, 128, 1, 1, V, { VR }, 0, 0 },
+ { ocIsEmpty, 129, 1, 1, V, { VR }, 0, 0 },
+ { ocT, 130, 1, 1, V, { RO }, 0, 0 },
+ { ocN, 131, 1, 1, V, { RO }, 0, 0 },
+ { ocGetDateValue, 140, 1, 1, V, { VR }, 0, 0 },
+ { ocGetTimeValue, 141, 1, 1, V, { VR }, 0, 0 },
+ { ocLIA, 142, 3, 3, V, { VR }, 0, 0 },
+ { ocDIA, 143, 4, 4, V, { VR }, 0, 0 },
+ { ocGDA, 144, 4, 5, V, { VR }, 0, 0 },
+ { ocIndirect, 148, 1, 2, R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocClean, 162, 1, 1, V, { VR }, 0, 0 },
+ { ocMatDet, 163, 1, 1, V, { VA }, 0, 0 },
+ { ocMatInv, 164, 1, 1, A, { VA }, 0, 0 },
+ { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 },
+ { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 },
+ { ocKapz, 168, 4, 6, V, { VR }, 0, 0 },
+ { ocCount2, 169, 0, MX, V, { RX }, 0, 0 },
+ { ocProduct, 183, 0, MX, V, { RX }, 0, 0 },
+ { ocFact, 184, 1, 1, V, { VR }, 0, 0 },
+ { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 },
+ { ocStDevP, 193, 1, MX, V, { RX }, 0, 0 },
+ { ocVarP, 194, 1, MX, V, { RX }, 0, 0 },
+ { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 },
+ { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
+ { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
+ { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
+ { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
+ { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
+};
+
+/** Functions new in BIFF3. */
+static const XclFunctionInfo saFuncTable_3[] =
+{
+ { ocRGP, 49, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocTrend, 50, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocRKP, 51, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocGrowth, 52, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocTrunc, 197, 1, 2, V, { VR }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
+ { ocAddress, 219, 2, 5, V, { VR }, 0, 0 },
+ { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocVBD, 222, 5, 7, V, { VR }, 0, 0 },
+ { ocMedian, 227, 1, MX, V, { RX }, 0, 0 },
+ { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 },
+ { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 },
+ { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 },
+ { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 },
+ { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCosHyp, 233, 1, 1, V, { VR }, 0, 0 },
+ { ocArcTanHyp, 234, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCotHyp, 234, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocDBGet, 235, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocInfo, 244, 1, 1, V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
+};
+
+/** Functions new in BIFF4. */
+static const XclFunctionInfo saFuncTable_4[] =
+{
+ { ocFixed, 14, 1, 3, V, { VR }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
+ { ocAsc, 214, 1, 1, V, { VR }, 0, 0 },
+ { ocJis, 215, 1, 1, V, { VR }, 0, 0 },
+ { ocRank, 216, 2, 3, V, { VR, RO, VR }, 0, 0 },
+ { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 },
+ { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 },
+ { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 },
+ { ocAveDev, 269, 1, MX, V, { RX }, 0, 0 },
+ { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 },
+ { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 },
+ { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 },
+ { ocBinomDist, 273, 4, 4, V, { VR }, 0, 0 },
+ { ocChiDist, 274, 2, 2, V, { VR }, 0, 0 },
+ { ocChiInv, 275, 2, 2, V, { VR }, 0, 0 },
+ { ocKombin, 276, 2, 2, V, { VR }, 0, 0 },
+ { ocConfidence, 277, 3, 3, V, { VR }, 0, 0 },
+ { ocKritBinom, 278, 3, 3, V, { VR }, 0, 0 },
+ { ocEven, 279, 1, 1, V, { VR }, 0, 0 },
+ { ocExpDist, 280, 3, 3, V, { VR }, 0, 0 },
+ { ocFDist, 281, 3, 3, V, { VR }, 0, 0 },
+ { ocFInv, 282, 3, 3, V, { VR }, 0, 0 },
+ { ocFisher, 283, 1, 1, V, { VR }, 0, 0 },
+ { ocFisherInv, 284, 1, 1, V, { VR }, 0, 0 },
+ { ocFloor, 285, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocGammaDist, 286, 4, 4, V, { VR }, 0, 0 },
+ { ocGammaInv, 287, 3, 3, V, { VR }, 0, 0 },
+ { ocCeil, 288, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocHypGeomDist, 289, 4, 4, V, { VR }, 0, 0 },
+ { ocLogNormDist, 290, 3, 3, V, { VR }, 0, 0 },
+ { ocLogInv, 291, 3, 3, V, { VR }, 0, 0 },
+ { ocNegBinomVert, 292, 3, 3, V, { VR }, 0, 0 },
+ { ocNormDist, 293, 4, 4, V, { VR }, 0, 0 },
+ { ocStdNormDist, 294, 1, 1, V, { VR }, 0, 0 },
+ { ocNormInv, 295, 3, 3, V, { VR }, 0, 0 },
+ { ocSNormInv, 296, 1, 1, V, { VR }, 0, 0 },
+ { ocStandard, 297, 3, 3, V, { VR }, 0, 0 },
+ { ocOdd, 298, 1, 1, V, { VR }, 0, 0 },
+ { ocVariationen, 299, 2, 2, V, { VR }, 0, 0 },
+ { ocPoissonDist, 300, 3, 3, V, { VR }, 0, 0 },
+ { ocTDist, 301, 3, 3, V, { VR }, 0, 0 },
+ { ocWeibull, 302, 4, 4, V, { VR }, 0, 0 },
+ { ocSumXMY2, 303, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2MY2, 304, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2DY2, 305, 2, 2, V, { VA }, 0, 0 },
+ { ocChiTest, 306, 2, 2, V, { VA }, 0, 0 },
+ { ocCorrel, 307, 2, 2, V, { VA }, 0, 0 },
+ { ocCovar, 308, 2, 2, V, { VA }, 0, 0 },
+ { ocForecast, 309, 3, 3, V, { VR, VA }, 0, 0 },
+ { ocFTest, 310, 2, 2, V, { VA }, 0, 0 },
+ { ocIntercept, 311, 2, 2, V, { VA }, 0, 0 },
+ { ocPearson, 312, 2, 2, V, { VA }, 0, 0 },
+ { ocRSQ, 313, 2, 2, V, { VA }, 0, 0 },
+ { ocSTEYX, 314, 2, 2, V, { VA }, 0, 0 },
+ { ocSlope, 315, 2, 2, V, { VA }, 0, 0 },
+ { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocDevSq, 318, 1, MX, V, { RX }, 0, 0 },
+ { ocGeoMean, 319, 1, MX, V, { RX }, 0, 0 },
+ { ocHarMean, 320, 1, MX, V, { RX }, 0, 0 },
+ { ocSumSQ, 321, 0, MX, V, { RX }, 0, 0 },
+ { ocKurt, 322, 1, MX, V, { RX }, 0, 0 },
+ { ocSchiefe, 323, 1, MX, V, { RX }, 0, 0 },
+ { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 },
+ { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 },
+ { ocModalValue, 330, 1, MX, V, { VA }, 0, 0 },
+ { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocTInv, 332, 2, 2, V, { VR }, 0, 0 }
+};
+
+/** Functions new in BIFF5/BIFF7. Unsupported functions: DATEDIF, DATESTRING, NUMBERSTRING. */
+static const XclFunctionInfo saFuncTable_5[] =
+{
+ { ocGetDayOfWeek, 70, 1, 2, V, { VR }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
+ { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
+ { ocMacro, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocConcat, 336, 0, MX, V, { VR }, 0, 0 },
+ { ocPower, 337, 2, 2, V, { VR }, 0, 0 },
+ { ocRad, 342, 1, 1, V, { VR }, 0, 0 },
+ { ocDeg, 343, 1, 1, V, { VR }, 0, 0 },
+ { ocSubTotal, 344, 2, MX, V, { VR, RO }, 0, 0 },
+ { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 },
+ { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 },
+ { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 },
+ { ocISPMT, 350, 4, 4, V, { VR }, 0, 0 },
+ { ocNoName, 351, 3, 3, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATEDIF
+ { ocNoName, 352, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
+ { ocNoName, 353, 2, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
+ { ocRoman, 354, 1, 2, V, { VR }, 0, 0 }
+};
+
+/** Functions new in BIFF8. Unsupported functions: PHONETIC. */
+static const XclFunctionInfo saFuncTable_8[] =
+{
+ { ocGetPivotData, 358, 2, MX, V, { RR, RR, VR }, 0, 0 },
+ { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 },
+ { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
+ { ocAverageA, 361, 1, MX, V, { RX }, 0, 0 },
+ { ocMaxA, 362, 1, MX, V, { RX }, 0, 0 },
+ { ocMinA, 363, 1, MX, V, { RX }, 0, 0 },
+ { ocStDevPA, 364, 1, MX, V, { RX }, 0, 0 },
+ { ocVarPA, 365, 1, MX, V, { RX }, 0, 0 },
+ { ocStDevA, 366, 1, MX, V, { RX }, 0, 0 },
+ { ocVarA, 367, 1, MX, V, { RX }, 0, 0 },
+ { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
+ { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
+ { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
+};
+
+#define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
+ { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
+ { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
+
+/** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */
+static const XclFunctionInfo saFuncTable_Odf[] =
+{
+ EXC_FUNCENTRY_ODF( ocArabic, 1, 1, 0, "ARABIC" ),
+ EXC_FUNCENTRY_ODF( ocB, 3, 4, 0, "B" ),
+ EXC_FUNCENTRY_ODF( ocBase, 2, 3, 0, "BASE" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITAND" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITLSHIFT" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITOR" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITRSHIFT" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITXOR" ),
+ EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
+ EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ),
+ EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ),
+ EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ),
+ EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ),
+ EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ),
+ EXC_FUNCENTRY_ODF( ocFInv, 3, 3, 0, "FINV" ),
+ EXC_FUNCENTRY_ODF( ocFormula, 1, 1, 0, "FORMULA" ),
+ EXC_FUNCENTRY_ODF( ocGamma, 1, 1, 0, "GAMMA" ),
+ EXC_FUNCENTRY_ODF( ocGauss, 1, 1, 0, "GAUSS" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" ),
+ EXC_FUNCENTRY_ODF( ocIsFormula, 1, 1, 0, "ISFORMULA" ),
+ EXC_FUNCENTRY_ODF( ocWeek, 1, 2, 0, "ISOWEEKNUM" ),
+ EXC_FUNCENTRY_ODF( ocMatrixUnit, 1, 1, 0, "MUNIT" ),
+ EXC_FUNCENTRY_ODF( ocNumberValue, 2, 2, 0, "NUMBERVALUE" ),
+ EXC_FUNCENTRY_ODF( ocLaufz, 3, 3, 0, "PDURATION" ),
+ EXC_FUNCENTRY_ODF( ocVariationen2, 2, 2, 0, "PERMUTATIONA" ),
+ EXC_FUNCENTRY_ODF( ocPhi, 1, 1, 0, "PHI" ),
+ EXC_FUNCENTRY_ODF( ocZGZ, 3, 3, 0, "RRI" ),
+ EXC_FUNCENTRY_ODF( ocTable, 0, 1, 0, "SHEET" ),
+ EXC_FUNCENTRY_ODF( ocTables, 0, 1, 0, "SHEETS" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "SKEWP" ),
+ EXC_FUNCENTRY_ODF( ocUnichar, 1, 1, 0, "UNICHAR" ),
+ EXC_FUNCENTRY_ODF( ocUnicode, 1, 1, 0, "UNICODE" ),
+ EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "XOR" )
+};
+
+#undef EXC_FUNCENTRY_ODF
+
+// ----------------------------------------------------------------------------
+
+XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
+{
+ void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) =
+ rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap;
+
+ /* Only read/write functions supported in the current BIFF version.
+ Function tables from later BIFF versions may overwrite single functions
+ from earlier tables. */
+ XclBiff eBiff = rRoot.GetBiff();
+ if( eBiff >= EXC_BIFF2 )
+ (this->*pFillFunc)( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) );
+ if( eBiff >= EXC_BIFF3 )
+ (this->*pFillFunc)( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) );
+ if( eBiff >= EXC_BIFF4 )
+ (this->*pFillFunc)( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) );
+ if( eBiff >= EXC_BIFF5 )
+ (this->*pFillFunc)( saFuncTable_5, STATIC_TABLE_END( saFuncTable_5 ) );
+ if( eBiff >= EXC_BIFF8 )
+ (this->*pFillFunc)( saFuncTable_8, STATIC_TABLE_END( saFuncTable_8 ) );
+ (this->*pFillFunc)( saFuncTable_Odf, STATIC_TABLE_END( saFuncTable_Odf ) );
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const
+{
+ // only in import filter allowed
+ DBG_ASSERT( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclFunc - wrong filter" );
+ XclFuncMap::const_iterator aIt = maXclFuncMap.find( nXclFunc );
+ return (aIt == maXclFuncMap.end()) ? 0 : aIt->second;
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const
+{
+ // only in import filter allowed, but do not test maXclMacroNameMap, it may be empty for old BIFF versions
+ DBG_ASSERT( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclMacroName - wrong filter" );
+ XclMacroNameMap::const_iterator aIt = maXclMacroNameMap.find( rXclMacroName );
+ return (aIt == maXclMacroNameMap.end()) ? 0 : aIt->second;
+}
+
+const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromOpCode( OpCode eOpCode ) const
+{
+ // only in export filter allowed
+ DBG_ASSERT( !maScFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromOpCode - wrong filter" );
+ ScFuncMap::const_iterator aIt = maScFuncMap.find( eOpCode );
+ return (aIt == maScFuncMap.end()) ? 0 : aIt->second;
+}
+
+void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
+{
+ for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
+ {
+ maXclFuncMap[ pIt->mnXclFunc ] = pIt;
+ if( pIt->IsMacroFunc() )
+ maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
+ }
+ }
+}
+
+void XclFunctionProvider::FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
+{
+ for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
+ if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_IMPORTONLY ) )
+ maScFuncMap[ pIt->meOpCode ] = pIt;
+}
+
+// Token array ================================================================
+
+XclTokenArray::XclTokenArray( bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+}
+
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+ maTokVec.swap( rTokVec );
+}
+
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+ maTokVec.swap( rTokVec );
+ maExtDataVec.swap( rExtDataVec );
+}
+
+sal_uInt16 XclTokenArray::GetSize() const
+{
+ DBG_ASSERT( maTokVec.size() <= 0xFFFF, "XclTokenArray::GetSize - array too long" );
+ return limit_cast< sal_uInt16 >( maTokVec.size() );
+}
+
+void XclTokenArray::ReadSize( XclImpStream& rStrm )
+{
+ sal_uInt16 nSize;
+ rStrm >> nSize;
+ maTokVec.resize( nSize );
+}
+
+void XclTokenArray::ReadArray( XclImpStream& rStrm )
+{
+ if( !maTokVec.empty() )
+ rStrm.Read( &maTokVec.front(), GetSize() );
+}
+
+void XclTokenArray::Read( XclImpStream& rStrm )
+{
+ ReadSize( rStrm );
+ ReadArray( rStrm );
+}
+
+void XclTokenArray::WriteSize( XclExpStream& rStrm ) const
+{
+ rStrm << GetSize();
+}
+
+void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
+{
+ if( !maTokVec.empty() )
+ rStrm.Write( &maTokVec.front(), GetSize() );
+ if( !maExtDataVec.empty() )
+ rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
+}
+
+void XclTokenArray::Write( XclExpStream& rStrm ) const
+{
+ WriteSize( rStrm );
+ WriteArray( rStrm );
+}
+
+bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
+{
+ return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
+{
+ rTokArr.Read( rStrm );
+ return rStrm;
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr )
+{
+ if( !rxTokArr )
+ rxTokArr.reset( new XclTokenArray );
+ rxTokArr->Read( rStrm );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr )
+{
+ rTokArr.Write( rStrm );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr )
+{
+ if( rxTokArr )
+ rxTokArr->Write( rStrm );
+ else
+ rStrm << sal_uInt16( 0 );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+XclTokenArrayIterator::XclTokenArrayIterator() :
+ mppScTokenBeg( 0 ),
+ mppScTokenEnd( 0 ),
+ mppScToken( 0 ),
+ mbSkipSpaces( false )
+{
+}
+
+XclTokenArrayIterator::XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces )
+{
+ Init( rScTokArr, bSkipSpaces );
+}
+
+XclTokenArrayIterator::XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces ) :
+ mppScTokenBeg( rTokArrIt.mppScTokenBeg ),
+ mppScTokenEnd( rTokArrIt.mppScTokenEnd ),
+ mppScToken( rTokArrIt.mppScToken ),
+ mbSkipSpaces( bSkipSpaces )
+{
+ SkipSpaces();
+}
+
+void XclTokenArrayIterator::Init()
+{
+ mppScTokenBeg = mppScTokenEnd = mppScToken = 0;
+}
+
+void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
+{
+ sal_uInt16 nTokArrLen = rScTokArr.GetLen();
+ mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
+ mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
+ mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
+ mbSkipSpaces = bSkipSpaces;
+ SkipSpaces();
+}
+
+XclTokenArrayIterator& XclTokenArrayIterator::operator++()
+{
+ NextRawToken();
+ SkipSpaces();
+ return *this;
+}
+
+void XclTokenArrayIterator::NextRawToken()
+{
+ if( mppScToken )
+ if( (++mppScToken == mppScTokenEnd) || !*mppScToken )
+ mppScToken = 0;
+}
+
+void XclTokenArrayIterator::SkipSpaces()
+{
+ if( mbSkipSpaces )
+ while( Is() && ((*this)->GetOpCode() == ocSpaces) )
+ NextRawToken();
+}
+
+// strings and string lists ---------------------------------------------------
+
+bool XclTokenArrayHelper::GetTokenString( String& rString, const FormulaToken& rScToken )
+{
+ bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
+ if( bIsStr ) rString = rScToken.GetString();
+ return bIsStr;
+}
+
+bool XclTokenArrayHelper::GetString( String& rString, const ScTokenArray& rScTokArr )
+{
+ XclTokenArrayIterator aIt( rScTokArr, true );
+ // something is following the string token -> error
+ return aIt.Is() && GetTokenString( rString, *aIt ) && !++aIt;
+}
+
+bool XclTokenArrayHelper::GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep )
+{
+ bool bRet = true;
+ String aString;
+ XclTokenArrayIterator aIt( rScTokArr, true );
+ enum { STATE_START, STATE_STR, STATE_SEP, STATE_END } eState = STATE_START;
+ while( eState != STATE_END ) switch( eState )
+ {
+ case STATE_START:
+ eState = aIt.Is() ? STATE_STR : STATE_END;
+ break;
+ case STATE_STR:
+ bRet = GetTokenString( aString, *aIt );
+ if( bRet ) rStringList.Append( aString );
+ eState = (bRet && (++aIt).Is()) ? STATE_SEP : STATE_END;
+ break;
+ case STATE_SEP:
+ bRet = aIt->GetOpCode() == ocSep;
+ if( bRet ) rStringList.Append( cSep );
+ eState = (bRet && (++aIt).Is()) ? STATE_STR : STATE_END;
+ break;
+ default:;
+ }
+ return bRet;
+}
+
+void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces )
+{
+ String aString;
+ if( GetString( aString, rScTokArr ) )
+ {
+ rScTokArr.Clear();
+ xub_StrLen nTokenCnt = aString.GetTokenCount( cStringSep );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
+ {
+ String aToken( aString.GetToken( 0, cStringSep, nStringIx ) );
+ if( bTrimLeadingSpaces )
+ aToken.EraseLeadingChars( ' ' );
+ if( nToken > 0 )
+ rScTokArr.AddOpCode( ocSep );
+ rScTokArr.AddString( aToken );
+ }
+ }
+}
+
+// shared formulas ------------------------------------------------------------
+
+const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr )
+{
+ if( rScTokArr.GetLen() == 1 )
+ if( const FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
+ if( pScToken->GetOpCode() == ocName )
+ if( ScRangeData* pData = rRoot.GetNamedRanges().findByIndex( pScToken->GetIndex() ) )
+ if( pData->HasType( RT_SHARED ) )
+ return pData->GetCode();
+ return 0;
+}
+
+// multiple operations --------------------------------------------------------
+
+namespace {
+
+inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken )
+{
+ OpCode eOpCode = rToken.GetOpCode();
+ bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
+ if( bIsSingleRef )
+ {
+ const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef();
+ rAddress.Set( rRef.nCol, rRef.nRow, rRef.nTab );
+ bIsSingleRef = !rRef.IsDeleted();
+ }
+ return bIsSingleRef;
+}
+
+} // namespace
+
+bool XclTokenArrayHelper::GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr )
+{
+ rRefs.mbDblRefMode = false;
+ enum
+ {
+ stBegin, stTableOp, stOpen, stFormula, stFormulaSep,
+ stColFirst, stColFirstSep, stColRel, stColRelSep,
+ stRowFirst, stRowFirstSep, stRowRel, stClose, stError
+ } eState = stBegin; // last read token
+ for( XclTokenArrayIterator aIt( rScTokArr, true ); aIt.Is() && (eState != stError); ++aIt )
+ {
+ OpCode eOpCode = aIt->GetOpCode();
+ bool bIsSep = eOpCode == ocSep;
+ switch( eState )
+ {
+ case stBegin:
+ eState = (eOpCode == ocTableOp) ? stTableOp : stError;
+ break;
+ case stTableOp:
+ eState = (eOpCode == ocOpen) ? stOpen : stError;
+ break;
+ case stOpen:
+ eState = lclGetAddress( rRefs.maFmlaScPos, *aIt ) ? stFormula : stError;
+ break;
+ case stFormula:
+ eState = bIsSep ? stFormulaSep : stError;
+ break;
+ case stFormulaSep:
+ eState = lclGetAddress( rRefs.maColFirstScPos, *aIt ) ? stColFirst : stError;
+ break;
+ case stColFirst:
+ eState = bIsSep ? stColFirstSep : stError;
+ break;
+ case stColFirstSep:
+ eState = lclGetAddress( rRefs.maColRelScPos, *aIt ) ? stColRel : stError;
+ break;
+ case stColRel:
+ eState = bIsSep ? stColRelSep : ((eOpCode == ocClose) ? stClose : stError);
+ break;
+ case stColRelSep:
+ eState = lclGetAddress( rRefs.maRowFirstScPos, *aIt ) ? stRowFirst : stError;
+ rRefs.mbDblRefMode = true;
+ break;
+ case stRowFirst:
+ eState = bIsSep ? stRowFirstSep : stError;
+ break;
+ case stRowFirstSep:
+ eState = lclGetAddress( rRefs.maRowRelScPos, *aIt ) ? stRowRel : stError;
+ break;
+ case stRowRel:
+ eState = (eOpCode == ocClose) ? stClose : stError;
+ break;
+ default:
+ eState = stError;
+ }
+ }
+ return eState == stClose;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlpage.cxx b/sc/source/filter/excel/xlpage.cxx
new file mode 100644
index 000000000000..1fd4d155f5c4
--- /dev/null
+++ b/sc/source/filter/excel/xlpage.cxx
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlpage.hxx"
+#include <sfx2/printer.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/paperinf.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/macros.h>
+#include "scitems.hxx"
+#include <editeng/brshitem.hxx>
+#include "global.hxx"
+#include "xlconst.hxx"
+#include <oox/core/xmlfilterbase.hxx>
+
+// Paper size =================================================================
+
+struct XclPaperSize
+{
+ Paper mePaper; /// SVX paper size identifier.
+ long mnWidth; /// Paper width in twips.
+ long mnHeight; /// Paper height in twips.
+};
+
+#define IN2TWIPS( v ) ((long)((v) * EXC_TWIPS_PER_INCH + 0.5))
+#define MM2TWIPS( v ) ((long)((v) * EXC_TWIPS_PER_INCH / CM_PER_INCH / 10.0 + 0.5))
+#define TWIPS2MM( v ) ((long)((v - 0.5) / EXC_TWIPS_PER_INCH * CM_PER_INCH * 10.0))
+
+
+static const XclPaperSize pPaperSizeTable[] =
+{
+/* 0*/ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_LETTER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Small
+ { PAPER_TABLOID, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // Tabloid
+ { PAPER_LEDGER, IN2TWIPS( 17 ), IN2TWIPS( 11 ) }, // Ledger
+/* 5*/ { PAPER_LEGAL, IN2TWIPS( 8.5 ), IN2TWIPS( 14 ) }, // Legal
+ { PAPER_STATEMENT, IN2TWIPS( 5.5 ), IN2TWIPS( 8.5 ) }, // Statement
+ { PAPER_EXECUTIVE, IN2TWIPS( 7.25 ), IN2TWIPS( 10.5 ) }, // Executive
+ { PAPER_A3, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3
+ { PAPER_A4, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4
+/* 10*/ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Small
+ { PAPER_A5, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5
+ //See: http://wiki.services.openoffice.org/wiki/DefaultPaperSize comments
+ //near DMPAPER_B4 in vcl
+ //i.e.
+ //http://msdn.microsoft.com/en-us/library/bb241398.aspx makes the claim:
+ //xlPaperB4 12 B4 (250 mm x 354 mm)
+ //xlPaperB5 13 A5 (148 mm x 210 mm)
+ //but, a paper enum called B5 is surely not actually "A5", and furthermore
+ //the XlPaperSize enumeration otherwise follows the DMPAPER values
+ //http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx
+ //which has
+ //DMPAPER_B4 12 B4 (JIS) 250 x 354
+ //DMPAPER_B5 13 B5 (JIS) 182 x 257 mm
+ //which claim them to be the JIS sizes. Though that document then gives
+ //"B4 (JIS)" an *ISO* B4 size in the text, but
+ //http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf
+ //claims that the MS DMPAPER_B4 and DMPAPER_B5 truly are the JIS sizes
+ //which at least makes some sort of sense. (cmc)
+ { PAPER_B4_JIS, MM2TWIPS( 257 ), MM2TWIPS( 364 ) }, // B4 (JIS)
+ { PAPER_B5_JIS, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS)
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // Folio
+/* 15*/ { PAPER_QUARTO, MM2TWIPS( 215 ), MM2TWIPS( 275 ) }, // Quarto
+ { PAPER_10x14, IN2TWIPS( 10 ), IN2TWIPS( 14 ) }, // 10x14
+ { PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // 11x17
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Note
+ { PAPER_ENV_9, IN2TWIPS( 3.875 ), IN2TWIPS( 8.875 ) }, // Envelope #9
+/* 20*/ { PAPER_ENV_10, IN2TWIPS( 4.125 ), IN2TWIPS( 9.5 ) }, // Envelope #10
+ { PAPER_ENV_11, IN2TWIPS( 4.5 ), IN2TWIPS( 10.375 ) }, // Envelope #11
+ { PAPER_ENV_12, IN2TWIPS( 4.75 ), IN2TWIPS( 11 ) }, // Envelope #12
+ { PAPER_ENV_14, IN2TWIPS( 5 ), IN2TWIPS( 11.5 ) }, // Envelope #14
+ { PAPER_C, IN2TWIPS( 17 ), IN2TWIPS( 22 ) }, // ANSI-C
+/* 25*/ { PAPER_D, IN2TWIPS( 22 ), IN2TWIPS( 34 ) }, // ANSI-D
+ { PAPER_E, IN2TWIPS( 34 ), IN2TWIPS( 44 ) }, // ANSI-E
+ { PAPER_ENV_DL, MM2TWIPS( 110 ), MM2TWIPS( 220 ) }, // Envelope DL
+ { PAPER_ENV_C5, MM2TWIPS( 162 ), MM2TWIPS( 229 ) }, // Envelope C5
+ { PAPER_ENV_C3, MM2TWIPS( 324 ), MM2TWIPS( 458 ) }, // Envelope C3
+/* 30*/ { PAPER_ENV_C4, MM2TWIPS( 229 ), MM2TWIPS( 324 ) }, // Envelope C4
+ { PAPER_ENV_C6, MM2TWIPS( 114 ), MM2TWIPS( 162 ) }, // Envelope C6
+ { PAPER_ENV_C65, MM2TWIPS( 114 ), MM2TWIPS( 229 ) }, // Envelope C65
+ { PAPER_B4_ISO, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
+ { PAPER_B5_ISO, MM2TWIPS( 176 ), MM2TWIPS( 250 ) }, // B5 (ISO)
+/* 35*/ { PAPER_B6_ISO, MM2TWIPS( 125 ), MM2TWIPS( 176 ) }, // B6 (ISO)
+ { PAPER_ENV_ITALY, MM2TWIPS( 110 ), MM2TWIPS( 230 ) }, // Envelope Italy
+ { PAPER_ENV_MONARCH, IN2TWIPS( 3.875 ), IN2TWIPS( 7.5 ) }, // Envelope Monarch
+ { PAPER_ENV_PERSONAL, IN2TWIPS( 3.625 ), IN2TWIPS( 6.5 ) }, // 6 3/4 Envelope
+ { PAPER_FANFOLD_US, IN2TWIPS( 14.875 ), IN2TWIPS( 11 ) }, // US Std Fanfold
+/* 40*/ { PAPER_FANFOLD_DE, IN2TWIPS( 8.5 ), IN2TWIPS( 12 ) }, // German Std Fanfold
+ { PAPER_FANFOLD_LEGAL_DE, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // German Legal Fanfold
+ { PAPER_B4_ISO, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
+ { PAPER_POSTCARD_JP,MM2TWIPS( 100 ), MM2TWIPS( 148 ) }, // Japanese Postcard
+ { PAPER_9x11, IN2TWIPS( 9 ), IN2TWIPS( 11 ) }, // 9x11
+/* 45*/ { PAPER_10x11, IN2TWIPS( 10 ), IN2TWIPS( 11 ) }, // 10x11
+ { PAPER_15x11, IN2TWIPS( 15 ), IN2TWIPS( 11 ) }, // 15x11
+ { PAPER_ENV_INVITE, MM2TWIPS( 220 ), MM2TWIPS( 220 ) }, // Envelope Invite
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+/* 50*/ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra
+ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 15 ) }, // Legal Extra
+ { PAPER_USER, IN2TWIPS( 11.69 ), IN2TWIPS( 18 ) }, // Tabloid Extra
+ { PAPER_USER, MM2TWIPS( 235 ), MM2TWIPS( 322 ) }, // A4 Extra
+ { PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Transverse
+/* 55*/ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Transverse
+ { PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra Transverse
+ { PAPER_A_PLUS, MM2TWIPS( 227 ), MM2TWIPS( 356 ) }, // Super A/A4
+ { PAPER_B_PLUS, MM2TWIPS( 305 ), MM2TWIPS( 487 ) }, // Super B/A3
+ { PAPER_LETTER_PLUS,IN2TWIPS( 8.5 ), IN2TWIPS( 12.69 ) }, // Letter Plus
+/* 60*/ { PAPER_A4_PLUS, MM2TWIPS( 210 ), MM2TWIPS( 330 ) }, // A4 Plus
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5 Transverse
+ { PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS) Transverse
+ { PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra
+ { PAPER_USER, MM2TWIPS( 174 ), MM2TWIPS( 235 ) }, // A5 Extra
+/* 65*/ { PAPER_USER, MM2TWIPS( 201 ), MM2TWIPS( 276 ) }, // B5 (ISO) Extra
+ { PAPER_A2, MM2TWIPS( 420 ), MM2TWIPS( 594 ) }, // A2
+ { PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3 Transverse
+ { PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra Transverse
+ { PAPER_DOUBLEPOSTCARD_JP, MM2TWIPS( 200 ), MM2TWIPS( 148 ) }, // Double Japanese Postcard
+/* 70*/ { PAPER_A6, MM2TWIPS( 105 ), MM2TWIPS( 148 ) }, // A6
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+/* 75*/ { PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 8.5 ) }, // Letter Rotated
+ { PAPER_USER, MM2TWIPS( 420 ), MM2TWIPS( 297 ) }, // A3 Rotated
+ { PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 210 ) }, // A4 Rotated
+ { PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 148 ) }, // A5 Rotated
+ { PAPER_USER, MM2TWIPS( 364 ), MM2TWIPS( 257 ) }, // B4 (JIS) Rotated
+/* 80*/ { PAPER_USER, MM2TWIPS( 257 ), MM2TWIPS( 182 ) }, // B5 (JIS) Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 100 ) }, // Japanese Postcard Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 200 ) }, // Double Japanese Postcard Rotated
+ { PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 105 ) }, // A6 Rotated
+ { PAPER_USER, 0, 0 }, // undefined
+/* 85*/ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_USER, 0, 0 }, // undefined
+ { PAPER_B6_JIS, MM2TWIPS( 128 ), MM2TWIPS( 182 ) }, // B6 (JIS)
+ { PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 128 ) }, // B6 (JIS) Rotated
+/* 90*/ { PAPER_12x11, IN2TWIPS( 12 ), IN2TWIPS( 11 ) } // 12x11
+};
+
+#undef IN2TWIPS
+#undef MM2TWIPS
+
+// Page settings ==============================================================
+
+XclPageData::XclPageData()
+{
+ SetDefaults();
+}
+
+XclPageData::~XclPageData()
+{
+ // SvxBrushItem incomplete in header
+}
+
+void XclPageData::SetDefaults()
+{
+ maHorPageBreaks.clear();
+ maVerPageBreaks.clear();
+ mxBrushItem.reset();
+ maHeader.Erase();
+ maFooter.Erase();
+ mfLeftMargin = mfRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_LR );
+ mfTopMargin = mfBottomMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_TB );
+ mfHeaderMargin = mfFooterMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_HF );
+ mfHdrLeftMargin = mfHdrRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_HLR );
+ mfFtrLeftMargin = mfFtrRightMargin = XclTools::GetInchFromHmm( EXC_MARGIN_DEFAULT_FLR );
+ mnPaperSize = EXC_PAPERSIZE_DEFAULT;
+ mnPaperWidth = 0;
+ mnPaperHeight = 0;
+ mnCopies = 1;
+ mnStartPage = 0;
+ mnScaling = 100;
+ mnFitToWidth = mnFitToHeight = 1;
+ mnHorPrintRes = mnVerPrintRes = 300;
+ mbValid = false;
+ mbPortrait = true;
+ mbPrintInRows = mbBlackWhite = mbDraftQuality = mbPrintNotes = mbManualStart = mbFitToPages = false;
+ mbHorCenter = mbVerCenter = mbPrintHeadings = mbPrintGrid = false;
+}
+
+Size XclPageData::GetScPaperSize() const
+{
+ const XclPaperSize* pEntry = pPaperSizeTable;
+ if( mnPaperSize < SAL_N_ELEMENTS( pPaperSizeTable ) )
+ pEntry += mnPaperSize;
+
+ Size aSize;
+ if( pEntry->mePaper == PAPER_USER )
+ aSize = Size( pEntry->mnWidth, pEntry->mnHeight );
+ else
+ aSize = SvxPaperInfo::GetPaperSize( pEntry->mePaper );
+
+ // invalid size -> back to default
+ if( !aSize.Width() || !aSize.Height() )
+ aSize = SvxPaperInfo::GetDefaultPaperSize();
+
+ if( !mbPortrait )
+ ::std::swap( aSize.Width(), aSize.Height() );
+
+ return aSize;
+}
+
+void XclPageData::SetScPaperSize( const Size& rSize, bool bPortrait, bool bStrictSize )
+{
+ mbPortrait = bPortrait;
+ mnPaperSize = 0;
+ long nWidth = bPortrait ? rSize.Width() : rSize.Height();
+ long nHeight = bPortrait ? rSize.Height() : rSize.Width();
+ long nMaxWDiff = 80;
+ long nMaxHDiff = 50;
+
+ mnPaperWidth = TWIPS2MM( nWidth );
+ mnPaperHeight = TWIPS2MM( nHeight );
+ if( bStrictSize )
+ {
+ nMaxWDiff = 5;
+ nMaxHDiff = 5;
+ mnStrictPaperSize = EXC_PAPERSIZE_USER;
+ }
+ else
+ {
+ mnPaperSize = 0;
+ }
+
+ for( const XclPaperSize* pEntry = pPaperSizeTable; pEntry != STATIC_TABLE_END( pPaperSizeTable ); ++pEntry )
+ {
+ long nWDiff = Abs( pEntry->mnWidth - nWidth );
+ long nHDiff = Abs( pEntry->mnHeight - nHeight );
+ if( ((nWDiff <= nMaxWDiff) && (nHDiff < nMaxHDiff)) ||
+ ((nWDiff < nMaxWDiff) && (nHDiff <= nMaxHDiff)) )
+ {
+ sal_uInt16 nIndex = static_cast< sal_uInt16 >( pEntry - pPaperSizeTable );
+ if( !bStrictSize )
+ mnPaperSize = nIndex;
+ else
+ mnStrictPaperSize = mnPaperSize = nIndex;
+
+ nMaxWDiff = nWDiff;
+ nMaxHDiff = nHDiff;
+ }
+ }
+ if( !bStrictSize )
+ SetScPaperSize( rSize, bPortrait, sal_True );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx
new file mode 100644
index 000000000000..fb0a7bbb64fe
--- /dev/null
+++ b/sc/source/filter/excel/xlpivot.cxx
@@ -0,0 +1,1028 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "dpgroup.hxx"
+#include "dpsave.hxx"
+#include "xestream.hxx"
+#include "xistream.hxx"
+#include "xestring.hxx"
+#include "xlpivot.hxx"
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using ::com::sun::star::sheet::GeneralFunction;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+
+namespace ScDPSortMode = ::com::sun::star::sheet::DataPilotFieldSortMode;
+namespace ScDPShowItemsMode = ::com::sun::star::sheet::DataPilotFieldShowItemsMode;
+namespace ScDPLayoutMode = ::com::sun::star::sheet::DataPilotFieldLayoutMode;
+namespace ScDPRefItemType = ::com::sun::star::sheet::DataPilotFieldReferenceItemType;
+namespace ScDPGroupBy = ::com::sun::star::sheet::DataPilotFieldGroupBy;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+XclPCItem::XclPCItem() :
+ meType( EXC_PCITEM_INVALID )
+{
+}
+
+XclPCItem::~XclPCItem()
+{
+}
+
+void XclPCItem::SetEmpty()
+{
+ meType = EXC_PCITEM_EMPTY;
+ maText.Erase();
+}
+
+void XclPCItem::SetText( const String& rText )
+{
+ meType = EXC_PCITEM_TEXT;
+ maText = rText;
+}
+
+void XclPCItem::SetDouble( double fValue )
+{
+ meType = EXC_PCITEM_DOUBLE;
+ //! TODO convert double to string
+ maText.Erase();
+ mfValue = fValue;
+}
+
+void XclPCItem::SetDateTime( const DateTime& rDateTime )
+{
+ meType = EXC_PCITEM_DATETIME;
+ //! TODO convert date to string
+ maText.Erase();
+ maDateTime = rDateTime;
+}
+
+void XclPCItem::SetInteger( sal_Int16 nValue )
+{
+ meType = EXC_PCITEM_INTEGER;
+ maText = String::CreateFromInt32( nValue );
+ mnValue = nValue;
+}
+
+void XclPCItem::SetError( sal_uInt16 nError )
+{
+ meType = EXC_PCITEM_ERROR;
+ //! TODO convert error to string
+ maText.Erase();
+ mnError = nError;
+}
+
+void XclPCItem::SetBool( bool bValue )
+{
+ meType = EXC_PCITEM_BOOL;
+ //! TODO convert boolean to string
+ maText.Erase();
+ mbValue = bValue;
+}
+
+// ----------------------------------------------------------------------------
+
+bool XclPCItem::IsEqual( const XclPCItem& rItem ) const
+{
+ if( meType == rItem.meType ) switch( meType )
+ {
+ case EXC_PCITEM_INVALID: return true;
+ case EXC_PCITEM_EMPTY: return true;
+ case EXC_PCITEM_TEXT: return maText == rItem.maText;
+ case EXC_PCITEM_DOUBLE: return mfValue == rItem.mfValue;
+ case EXC_PCITEM_DATETIME: return maDateTime == rItem.maDateTime;
+ case EXC_PCITEM_INTEGER: return mnValue == rItem.mnValue;
+ case EXC_PCITEM_BOOL: return mbValue == rItem.mbValue;
+ case EXC_PCITEM_ERROR: return mnError == rItem.mnError;
+ default: DBG_ERRORFILE( "XclPCItem::IsEqual - unknown pivot cache item type" );
+ }
+ return false;
+}
+
+bool XclPCItem::IsEmpty() const
+{
+ return meType == EXC_PCITEM_EMPTY;
+}
+
+const String* XclPCItem::GetText() const
+{
+ return (meType == EXC_PCITEM_TEXT) ? &maText : 0;
+}
+
+const double* XclPCItem::GetDouble() const
+{
+ return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : 0;
+}
+
+const DateTime* XclPCItem::GetDateTime() const
+{
+ return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : 0;
+}
+
+const sal_Int16* XclPCItem::GetInteger() const
+{
+ return (meType == EXC_PCITEM_INTEGER) ? &mnValue : 0;
+}
+
+const sal_uInt16* XclPCItem::GetError() const
+{
+ return (meType == EXC_PCITEM_ERROR) ? &mnError : 0;
+}
+
+const bool* XclPCItem::GetBool() const
+{
+ return (meType == EXC_PCITEM_BOOL) ? &mbValue : 0;
+}
+
+// Field settings =============================================================
+
+XclPCFieldInfo::XclPCFieldInfo() :
+ mnFlags( 0 ),
+ mnGroupChild( 0 ),
+ mnGroupBase( 0 ),
+ mnVisItems( 0 ),
+ mnGroupItems( 0 ),
+ mnBaseItems( 0 ),
+ mnOrigItems( 0 )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo )
+{
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnGroupChild
+ >> rInfo.mnGroupBase
+ >> rInfo.mnVisItems
+ >> rInfo.mnGroupItems
+ >> rInfo.mnBaseItems
+ >> rInfo.mnOrigItems;
+ if( rStrm.GetRecLeft() >= 3 )
+ rInfo.maName = rStrm.ReadUniString();
+ else
+ rInfo.maName.Erase();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnFlags
+ << rInfo.mnGroupChild
+ << rInfo.mnGroupBase
+ << rInfo.mnVisItems
+ << rInfo.mnGroupItems
+ << rInfo.mnBaseItems
+ << rInfo.mnOrigItems
+ << XclExpString( rInfo.maName );
+}
+
+// Numeric grouping field settings ============================================
+
+XclPCNumGroupInfo::XclPCNumGroupInfo() :
+ mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX )
+{
+ SetNumType();
+}
+
+void XclPCNumGroupInfo::SetNumType()
+{
+ SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM );
+}
+
+sal_Int32 XclPCNumGroupInfo::GetScDateType() const
+{
+ sal_Int32 nScType = 0;
+ switch( GetXclDataType() )
+ {
+ case EXC_SXNUMGROUP_TYPE_SEC: nScType = ScDPGroupBy::SECONDS; break;
+ case EXC_SXNUMGROUP_TYPE_MIN: nScType = ScDPGroupBy::MINUTES; break;
+ case EXC_SXNUMGROUP_TYPE_HOUR: nScType = ScDPGroupBy::HOURS; break;
+ case EXC_SXNUMGROUP_TYPE_DAY: nScType = ScDPGroupBy::DAYS; break;
+ case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS; break;
+ case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS; break;
+ case EXC_SXNUMGROUP_TYPE_YEAR: nScType = ScDPGroupBy::YEARS; break;
+ default: OSL_TRACE( "XclPCNumGroupInfo::GetScDateType - unexpected date type %d", GetXclDataType() );
+ }
+ return nScType;
+}
+
+void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType )
+{
+ sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM;
+ switch( nScType )
+ {
+ case ScDPGroupBy::SECONDS: nXclType = EXC_SXNUMGROUP_TYPE_SEC; break;
+ case ScDPGroupBy::MINUTES: nXclType = EXC_SXNUMGROUP_TYPE_MIN; break;
+ case ScDPGroupBy::HOURS: nXclType = EXC_SXNUMGROUP_TYPE_HOUR; break;
+ case ScDPGroupBy::DAYS: nXclType = EXC_SXNUMGROUP_TYPE_DAY; break;
+ case ScDPGroupBy::MONTHS: nXclType = EXC_SXNUMGROUP_TYPE_MONTH; break;
+ case ScDPGroupBy::QUARTERS: nXclType = EXC_SXNUMGROUP_TYPE_QUART; break;
+ case ScDPGroupBy::YEARS: nXclType = EXC_SXNUMGROUP_TYPE_YEAR; break;
+ default: OSL_TRACE( "XclPCNumGroupInfo::SetScDateType - unexpected date type %d", nScType );
+ }
+ SetXclDataType( nXclType );
+}
+
+sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const
+{
+ return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 );
+}
+
+void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType )
+{
+ ::insert_value( mnFlags, nXclType, 2, 4 );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo )
+{
+ return rStrm >> rInfo.mnFlags;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo )
+{
+ return rStrm << rInfo.mnFlags;
+}
+
+// Base class for pivot cache fields ==========================================
+
+XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) :
+ meFieldType( eFieldType ),
+ mnFieldIdx( nFieldIdx )
+{
+}
+
+XclPCField::~XclPCField()
+{
+}
+
+bool XclPCField::IsSupportedField() const
+{
+ return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN);
+}
+
+bool XclPCField::IsStandardField() const
+{
+ return meFieldType == EXC_PCFIELD_STANDARD;
+}
+
+bool XclPCField::IsStdGroupField() const
+{
+ return meFieldType == EXC_PCFIELD_STDGROUP;
+}
+
+bool XclPCField::IsNumGroupField() const
+{
+ return meFieldType == EXC_PCFIELD_NUMGROUP;
+}
+
+bool XclPCField::IsDateGroupField() const
+{
+ return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
+}
+
+bool XclPCField::IsGroupField() const
+{
+ return IsStdGroupField() || IsNumGroupField() || IsDateGroupField();
+}
+
+bool XclPCField::IsGroupBaseField() const
+{
+ return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
+}
+
+bool XclPCField::IsGroupChildField() const
+{
+ return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
+}
+
+sal_uInt16 XclPCField::GetBaseFieldIndex() const
+{
+ return IsGroupChildField() ? maFieldInfo.mnGroupBase : mnFieldIdx;
+}
+
+bool XclPCField::HasOrigItems() const
+{
+ return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems());
+}
+
+bool XclPCField::HasInlineItems() const
+{
+ return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0));
+}
+
+bool XclPCField::HasPostponedItems() const
+{
+ return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
+}
+
+bool XclPCField::Has16BitIndexes() const
+{
+ return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT );
+}
+
+// Pivot cache settings =======================================================
+
+/** Contains data for a pivot cache (SXDB record). */
+XclPCInfo::XclPCInfo() :
+ mnSrcRecs( 0 ),
+ mnStrmId( 0xFFFF ),
+ mnFlags( EXC_SXDB_DEFAULTFLAGS ),
+ mnBlockRecs( EXC_SXDB_BLOCKRECS ),
+ mnStdFields( 0 ),
+ mnTotalFields( 0 ),
+ mnSrcType( EXC_SXDB_SRC_SHEET )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo )
+{
+ rStrm >> rInfo.mnSrcRecs
+ >> rInfo.mnStrmId
+ >> rInfo.mnFlags
+ >> rInfo.mnBlockRecs
+ >> rInfo.mnStdFields
+ >> rInfo.mnTotalFields;
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mnSrcType;
+ rInfo.maUserName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnSrcRecs
+ << rInfo.mnStrmId
+ << rInfo.mnFlags
+ << rInfo.mnBlockRecs
+ << rInfo.mnStdFields
+ << rInfo.mnTotalFields
+ << sal_uInt16( 0 )
+ << rInfo.mnSrcType
+ << XclExpString( rInfo.maUserName );
+}
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+// cached name ================================================================
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName )
+{
+ sal_uInt16 nStrLen;
+ rStrm >> nStrLen;
+ rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING;
+ if( rCachedName.mbUseCache )
+ rCachedName.maName.Erase();
+ else
+ rCachedName.maName = rStrm.ReadUniString( nStrLen );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName )
+{
+ if( rCachedName.mbUseCache )
+ rStrm << EXC_PT_NOSTRING;
+ else
+ rStrm << XclExpString( rCachedName.maName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+const String* XclPTVisNameInfo::GetVisName() const
+{
+ return HasVisName() ? &maVisName.maName : 0;
+}
+
+void XclPTVisNameInfo::SetVisName( const String& rName )
+{
+ maVisName.maName = rName;
+ maVisName.mbUseCache = rName.Len() == 0;
+}
+
+// Field item settings ========================================================
+
+XclPTItemInfo::XclPTItemInfo() :
+ mnType( EXC_SXVI_TYPE_DATA ),
+ mnFlags( EXC_SXVI_DEFAULTFLAGS ),
+ mnCacheIdx( EXC_SXVI_DEFAULT_CACHE )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnType
+ >> rInfo.mnFlags
+ >> rInfo.mnCacheIdx
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnType
+ << rInfo.mnFlags
+ << rInfo.mnCacheIdx
+ << rInfo.maVisName;
+}
+
+// General field settings =====================================================
+
+XclPTFieldInfo::XclPTFieldInfo() :
+ mnAxes( EXC_SXVD_AXIS_NONE ),
+ mnSubtCount( 1 ),
+ mnSubtotals( EXC_SXVD_SUBT_DEFAULT ),
+ mnItemCount( 0 ),
+ mnCacheIdx( EXC_SXVD_DEFAULT_CACHE )
+{
+}
+
+DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const
+{
+ using namespace ::com::sun::star::sheet;
+ DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN;
+ sal_uInt16 nUsedAxes = mnAxes & nMask;
+ if( nUsedAxes & EXC_SXVD_AXIS_ROW )
+ eOrient = DataPilotFieldOrientation_ROW;
+ else if( nUsedAxes & EXC_SXVD_AXIS_COL )
+ eOrient = DataPilotFieldOrientation_COLUMN;
+ else if( nUsedAxes & EXC_SXVD_AXIS_PAGE )
+ eOrient = DataPilotFieldOrientation_PAGE;
+ else if( nUsedAxes & EXC_SXVD_AXIS_DATA )
+ eOrient = DataPilotFieldOrientation_DATA;
+ return eOrient;
+}
+
+void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient )
+{
+ using namespace ::com::sun::star::sheet;
+ switch( eOrient )
+ {
+ case DataPilotFieldOrientation_ROW: mnAxes |= EXC_SXVD_AXIS_ROW; break;
+ case DataPilotFieldOrientation_COLUMN: mnAxes |= EXC_SXVD_AXIS_COL; break;
+ case DataPilotFieldOrientation_PAGE: mnAxes |= EXC_SXVD_AXIS_PAGE; break;
+ case DataPilotFieldOrientation_DATA: mnAxes |= EXC_SXVD_AXIS_DATA; break;
+ default:;
+ }
+}
+
+//! TODO: should be a Sequence<GeneralFunction> in ScDPSaveData
+void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const
+{
+ rSubtotals.clear();
+ rSubtotals.reserve( 16 );
+
+ using namespace ::com::sun::star::sheet;
+ if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) rSubtotals.push_back( GeneralFunction_AUTO );
+ if( mnSubtotals & EXC_SXVD_SUBT_SUM ) rSubtotals.push_back( GeneralFunction_SUM );
+ if( mnSubtotals & EXC_SXVD_SUBT_COUNT ) rSubtotals.push_back( GeneralFunction_COUNT );
+ if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) rSubtotals.push_back( GeneralFunction_AVERAGE );
+ if( mnSubtotals & EXC_SXVD_SUBT_MAX ) rSubtotals.push_back( GeneralFunction_MAX );
+ if( mnSubtotals & EXC_SXVD_SUBT_MIN ) rSubtotals.push_back( GeneralFunction_MIN );
+ if( mnSubtotals & EXC_SXVD_SUBT_PROD ) rSubtotals.push_back( GeneralFunction_PRODUCT );
+ if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) rSubtotals.push_back( GeneralFunction_COUNTNUMS );
+ if( mnSubtotals & EXC_SXVD_SUBT_STDDEV ) rSubtotals.push_back( GeneralFunction_STDEV );
+ if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) rSubtotals.push_back( GeneralFunction_STDEVP );
+ if( mnSubtotals & EXC_SXVD_SUBT_VAR ) rSubtotals.push_back( GeneralFunction_VAR );
+ if( mnSubtotals & EXC_SXVD_SUBT_VARP ) rSubtotals.push_back( GeneralFunction_VARP );
+}
+
+void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals )
+{
+ mnSubtotals = EXC_SXVD_SUBT_NONE;
+ using namespace ::com::sun::star::sheet;
+ for( XclPTSubtotalVec::const_iterator aIt = rSubtotals.begin(), aEnd = rSubtotals.end(); aIt != aEnd; ++aIt )
+ {
+ switch( *aIt )
+ {
+ case GeneralFunction_AUTO: mnSubtotals |= EXC_SXVD_SUBT_DEFAULT; break;
+ case GeneralFunction_SUM: mnSubtotals |= EXC_SXVD_SUBT_SUM; break;
+ case GeneralFunction_COUNT: mnSubtotals |= EXC_SXVD_SUBT_COUNT; break;
+ case GeneralFunction_AVERAGE: mnSubtotals |= EXC_SXVD_SUBT_AVERAGE; break;
+ case GeneralFunction_MAX: mnSubtotals |= EXC_SXVD_SUBT_MAX; break;
+ case GeneralFunction_MIN: mnSubtotals |= EXC_SXVD_SUBT_MIN; break;
+ case GeneralFunction_PRODUCT: mnSubtotals |= EXC_SXVD_SUBT_PROD; break;
+ case GeneralFunction_COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM; break;
+ case GeneralFunction_STDEV: mnSubtotals |= EXC_SXVD_SUBT_STDDEV; break;
+ case GeneralFunction_STDEVP: mnSubtotals |= EXC_SXVD_SUBT_STDDEVP; break;
+ case GeneralFunction_VAR: mnSubtotals |= EXC_SXVD_SUBT_VAR; break;
+ case GeneralFunction_VARP: mnSubtotals |= EXC_SXVD_SUBT_VARP; break;
+ }
+ }
+
+ mnSubtCount = 0;
+ for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 )
+ if( mnSubtotals & nMask )
+ ++mnSubtCount;
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo )
+{
+ // rInfo.mnCacheIdx is not part of the SXVD record
+ return rStrm
+ >> rInfo.mnAxes
+ >> rInfo.mnSubtCount
+ >> rInfo.mnSubtotals
+ >> rInfo.mnItemCount
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
+{
+ // rInfo.mnCacheIdx is not part of the SXVD record
+ return rStrm
+ << rInfo.mnAxes
+ << rInfo.mnSubtCount
+ << rInfo.mnSubtotals
+ << rInfo.mnItemCount
+ << rInfo.maVisName;
+}
+
+// Extended field settings ====================================================
+
+XclPTFieldExtInfo::XclPTFieldExtInfo() :
+ mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
+ mnSortField( EXC_SXVDEX_SORT_OWN ),
+ mnShowField( EXC_SXVDEX_SHOW_NONE ),
+ mnNumFmt(0),
+ mpFieldTotalName(NULL)
+{
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const
+{
+ sal_Int32 nSortMode = ScDPSortMode::MANUAL;
+ if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) )
+ nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA;
+ return nSortMode;
+}
+
+void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode )
+{
+ bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA);
+ ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort );
+ if( nSortMode == ScDPSortMode::NAME )
+ mnSortField = EXC_SXVDEX_SORT_OWN; // otherwise sort field has to be set by caller
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const
+{
+ return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC,
+ ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM );
+}
+
+void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode )
+{
+ ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP );
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const
+{
+ return ::extract_value< sal_Int32 >( mnFlags, 24, 8 );
+}
+
+void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount )
+{
+ ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 );
+}
+
+sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const
+{
+ sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT;
+ if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) )
+ nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ?
+ ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
+ return nLayoutMode;
+}
+
+void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
+{
+ ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT );
+ ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
+{
+ sal_uInt8 nNameLen = 0;
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnSortField
+ >> rInfo.mnShowField
+ >> rInfo.mnNumFmt
+ >> nNameLen;
+
+ rStrm.Ignore(10);
+ if (nNameLen != 0xFF)
+ // Custom field total name is used. Pick it up.
+ rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
+
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
+{
+ rStrm << rInfo.mnFlags
+ << rInfo.mnSortField
+ << rInfo.mnShowField
+ << EXC_SXVDEX_FORMAT_NONE;
+
+ if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
+ {
+ rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
+ if (aFinalName.getLength() >= 254)
+ aFinalName = aFinalName.copy(0, 254);
+ sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
+ rStrm << nNameLen;
+ rStrm.WriteZeroBytes(10);
+ rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
+ }
+ else
+ {
+ rStrm << sal_uInt16(0xFFFF);
+ rStrm.WriteZeroBytes(8);
+ }
+ return rStrm;
+}
+
+// Page field settings ========================================================
+
+XclPTPageFieldInfo::XclPTPageFieldInfo() :
+ mnField( 0 ),
+ mnSelItem( EXC_SXPI_ALLITEMS ),
+ mnObjId( 0xFFFF )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnField
+ >> rInfo.mnSelItem
+ >> rInfo.mnObjId;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnField
+ << rInfo.mnSelItem
+ << rInfo.mnObjId;
+}
+
+// Data field settings ========================================================
+
+XclPTDataFieldInfo::XclPTDataFieldInfo() :
+ mnField( 0 ),
+ mnAggFunc( EXC_SXDI_FUNC_SUM ),
+ mnRefType( EXC_SXDI_REF_NORMAL ),
+ mnRefField( 0 ),
+ mnRefItem( 0 ),
+ mnNumFmt( 0 )
+{
+}
+
+GeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const
+{
+ using namespace ::com::sun::star::sheet;
+ GeneralFunction eAggFunc;
+ switch( mnAggFunc )
+ {
+ case EXC_SXDI_FUNC_SUM: eAggFunc = GeneralFunction_SUM; break;
+ case EXC_SXDI_FUNC_COUNT: eAggFunc = GeneralFunction_COUNT; break;
+ case EXC_SXDI_FUNC_AVERAGE: eAggFunc = GeneralFunction_AVERAGE; break;
+ case EXC_SXDI_FUNC_MAX: eAggFunc = GeneralFunction_MAX; break;
+ case EXC_SXDI_FUNC_MIN: eAggFunc = GeneralFunction_MIN; break;
+ case EXC_SXDI_FUNC_PRODUCT: eAggFunc = GeneralFunction_PRODUCT; break;
+ case EXC_SXDI_FUNC_COUNTNUM: eAggFunc = GeneralFunction_COUNTNUMS; break;
+ case EXC_SXDI_FUNC_STDDEV: eAggFunc = GeneralFunction_STDEV; break;
+ case EXC_SXDI_FUNC_STDDEVP: eAggFunc = GeneralFunction_STDEVP; break;
+ case EXC_SXDI_FUNC_VAR: eAggFunc = GeneralFunction_VAR; break;
+ case EXC_SXDI_FUNC_VARP: eAggFunc = GeneralFunction_VARP; break;
+ default: eAggFunc = GeneralFunction_SUM;
+ }
+ return eAggFunc;
+}
+
+void XclPTDataFieldInfo::SetApiAggFunc( GeneralFunction eAggFunc )
+{
+ using namespace ::com::sun::star::sheet;
+ switch( eAggFunc )
+ {
+ case GeneralFunction_SUM: mnAggFunc = EXC_SXDI_FUNC_SUM; break;
+ case GeneralFunction_COUNT: mnAggFunc = EXC_SXDI_FUNC_COUNT; break;
+ case GeneralFunction_AVERAGE: mnAggFunc = EXC_SXDI_FUNC_AVERAGE; break;
+ case GeneralFunction_MAX: mnAggFunc = EXC_SXDI_FUNC_MAX; break;
+ case GeneralFunction_MIN: mnAggFunc = EXC_SXDI_FUNC_MIN; break;
+ case GeneralFunction_PRODUCT: mnAggFunc = EXC_SXDI_FUNC_PRODUCT; break;
+ case GeneralFunction_COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break;
+ case GeneralFunction_STDEV: mnAggFunc = EXC_SXDI_FUNC_STDDEV; break;
+ case GeneralFunction_STDEVP: mnAggFunc = EXC_SXDI_FUNC_STDDEVP; break;
+ case GeneralFunction_VAR: mnAggFunc = EXC_SXDI_FUNC_VAR; break;
+ case GeneralFunction_VARP: mnAggFunc = EXC_SXDI_FUNC_VARP; break;
+ default: mnAggFunc = EXC_SXDI_FUNC_SUM;
+ }
+}
+
+sal_Int32 XclPTDataFieldInfo::GetApiRefType() const
+{
+ namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
+ sal_Int32 nRefType;
+ switch( mnRefType )
+ {
+ case EXC_SXDI_REF_DIFF: nRefType = ScDPRefType::ITEM_DIFFERENCE; break;
+ case EXC_SXDI_REF_PERC: nRefType = ScDPRefType::ITEM_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_DIFF: nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break;
+ case EXC_SXDI_REF_RUN_TOTAL: nRefType = ScDPRefType::RUNNING_TOTAL; break;
+ case EXC_SXDI_REF_PERC_ROW: nRefType = ScDPRefType::ROW_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_COL: nRefType = ScDPRefType::COLUMN_PERCENTAGE; break;
+ case EXC_SXDI_REF_PERC_TOTAL: nRefType = ScDPRefType::TOTAL_PERCENTAGE; break;
+ case EXC_SXDI_REF_INDEX: nRefType = ScDPRefType::INDEX; break;
+ default: nRefType = ScDPRefType::NONE;
+ }
+ return nRefType;
+}
+
+void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType )
+{
+ namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
+ switch( nRefType )
+ {
+ case ScDPRefType::ITEM_DIFFERENCE: mnRefType = EXC_SXDI_REF_DIFF; break;
+ case ScDPRefType::ITEM_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC; break;
+ case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE: mnRefType = EXC_SXDI_REF_PERC_DIFF; break;
+ case ScDPRefType::RUNNING_TOTAL: mnRefType = EXC_SXDI_REF_RUN_TOTAL; break;
+ case ScDPRefType::ROW_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_ROW; break;
+ case ScDPRefType::COLUMN_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_COL; break;
+ case ScDPRefType::TOTAL_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_TOTAL;break;
+ case ScDPRefType::INDEX: mnRefType = EXC_SXDI_REF_INDEX; break;
+ default: mnRefType = EXC_SXDI_REF_NORMAL;
+ }
+}
+
+sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const
+{
+ sal_Int32 nRefItemType;
+ switch( mnRefItem )
+ {
+ case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS; break;
+ case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT; break;
+ default: nRefItemType = ScDPRefItemType::NAMED;
+ }
+ return nRefItemType;
+}
+
+void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType )
+{
+ switch( nRefItemType )
+ {
+ case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM; break;
+ case ScDPRefItemType::NEXT: mnRefItem = EXC_SXDI_NEXTITEM; break;
+ // nothing for named item reference
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo )
+{
+ return rStrm
+ >> rInfo.mnField
+ >> rInfo.mnAggFunc
+ >> rInfo.mnRefType
+ >> rInfo.mnRefField
+ >> rInfo.mnRefItem
+ >> rInfo.mnNumFmt
+ >> rInfo.maVisName;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnField
+ << rInfo.mnAggFunc
+ << rInfo.mnRefType
+ << rInfo.mnRefField
+ << rInfo.mnRefItem
+ << rInfo.mnNumFmt
+ << rInfo.maVisName;
+}
+
+// Pivot table settings =======================================================
+
+XclPTInfo::XclPTInfo() :
+ mnFirstHeadRow( 0 ),
+ mnCacheIdx( 0xFFFF ),
+ mnDataAxis( EXC_SXVD_AXIS_NONE ),
+ mnDataPos( EXC_SXVIEW_DATALAST ),
+ mnFields( 0 ),
+ mnRowFields( 0 ),
+ mnColFields( 0 ),
+ mnPageFields( 0 ),
+ mnDataFields( 0 ),
+ mnDataRows( 0 ),
+ mnDataCols( 0 ),
+ mnFlags( EXC_SXVIEW_DEFAULTFLAGS ),
+ mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo )
+{
+ sal_uInt16 nTabLen, nDataLen;
+
+ rStrm >> rInfo.maOutXclRange
+ >> rInfo.mnFirstHeadRow
+ >> rInfo.maDataXclPos
+ >> rInfo.mnCacheIdx;
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mnDataAxis >> rInfo.mnDataPos
+ >> rInfo.mnFields
+ >> rInfo.mnRowFields >> rInfo.mnColFields
+ >> rInfo.mnPageFields >> rInfo.mnDataFields
+ >> rInfo.mnDataRows >> rInfo.mnDataCols
+ >> rInfo.mnFlags
+ >> rInfo.mnAutoFmtIdx
+ >> nTabLen >> nDataLen;
+ rInfo.maTableName = rStrm.ReadUniString( nTabLen );
+ rInfo.maDataName = rStrm.ReadUniString( nDataLen );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo )
+{
+ XclExpString aXclTableName( rInfo.maTableName );
+ XclExpString aXclDataName( rInfo.maDataName );
+
+ rStrm << rInfo.maOutXclRange
+ << rInfo.mnFirstHeadRow
+ << rInfo.maDataXclPos
+ << rInfo.mnCacheIdx
+ << sal_uInt16( 0 )
+ << rInfo.mnDataAxis << rInfo.mnDataPos
+ << rInfo.mnFields
+ << rInfo.mnRowFields << rInfo.mnColFields
+ << rInfo.mnPageFields << rInfo.mnDataFields
+ << rInfo.mnDataRows << rInfo.mnDataCols
+ << rInfo.mnFlags
+ << rInfo.mnAutoFmtIdx
+ << aXclTableName.Len() << aXclDataName.Len();
+ aXclTableName.WriteFlagField( rStrm );
+ aXclTableName.WriteBuffer( rStrm );
+ aXclDataName.WriteFlagField( rStrm );
+ aXclDataName.WriteBuffer( rStrm );
+ return rStrm;
+}
+
+// Extended pivot table settings ==============================================
+
+XclPTExtInfo::XclPTExtInfo() :
+ mnSxformulaRecs( 0 ),
+ mnSxselectRecs( 0 ),
+ mnPagePerRow( 0 ),
+ mnPagePerCol( 0 ),
+ mnFlags( EXC_SXEX_DEFAULTFLAGS )
+{
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo )
+{
+ rStrm >> rInfo.mnSxformulaRecs;
+ rStrm.Ignore( 6 );
+ return rStrm
+ >> rInfo.mnSxselectRecs
+ >> rInfo.mnPagePerRow
+ >> rInfo.mnPagePerCol
+ >> rInfo.mnFlags;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
+{
+ return rStrm
+ << rInfo.mnSxformulaRecs
+ << EXC_PT_NOSTRING // length of alt. error text
+ << EXC_PT_NOSTRING // length of alt. empty text
+ << EXC_PT_NOSTRING // length of tag
+ << rInfo.mnSxselectRecs
+ << rInfo.mnPagePerRow
+ << rInfo.mnPagePerCol
+ << rInfo.mnFlags
+ << EXC_PT_NOSTRING // length of page field style name
+ << EXC_PT_NOSTRING // length of table style name
+ << EXC_PT_NOSTRING; // length of vacate style name
+}
+
+// ============================================================================
+
+// Pivot table autoformat settings ============================================
+
+/**
+classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
+report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
+report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
+report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
+report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
+report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
+report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
+report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
+report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
+report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
+table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
+table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
+table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
+table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
+table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
+table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
+table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
+table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
+table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
+table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
+none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
+**/
+
+XclPTViewEx9Info::XclPTViewEx9Info() :
+ mbReport( 0 ),
+ mnAutoFormat( 0 ),
+ mnGridLayout( 0x10 )
+{
+}
+
+void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
+{
+ if( rDPObj.GetHeaderLayout() )
+ {
+ mbReport = 0;
+ mnAutoFormat = 1;
+ mnGridLayout = 0;
+ }
+ else
+ {
+ // Report1 for now
+ // TODO : sync with autoformat indicies
+ mbReport = 2;
+ mnAutoFormat = 1;
+ mnGridLayout = 0x10;
+ }
+
+ const ScDPSaveData* pData = rDPObj.GetSaveData();
+ if (pData)
+ {
+ const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
+ if (pGrandTotal)
+ maGrandTotalName = *pGrandTotal;
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
+ rStrm.Ignore( 6 );
+ rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
+ rInfo.maGrandTotalName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
+{
+ return rStrm
+ << EXC_PT_AUTOFMT_HEADER
+ << rInfo.mbReport
+ << EXC_PT_AUTOFMT_ZERO
+ << EXC_PT_AUTOFMT_FLAGS
+ << rInfo.mnAutoFormat
+ << rInfo.mnGridLayout
+ << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx
new file mode 100644
index 000000000000..3dc0fda96dc0
--- /dev/null
+++ b/sc/source/filter/excel/xlroot.cxx
@@ -0,0 +1,440 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlroot.hxx"
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/stritem.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/docfile.hxx>
+#include <vcl/font.hxx>
+#include <editeng/editstat.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "docuno.hxx"
+#include "editutil.hxx"
+#include "drwlayer.hxx"
+#include "scextopt.hxx"
+#include "patattr.hxx"
+#include "fapihelper.hxx"
+#include "xlconst.hxx"
+#include "xlstyle.hxx"
+#include "xlchart.hxx"
+#include "xltracer.hxx"
+#include <unotools/useroptions.hxx>
+#include "root.hxx"
+
+namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::awt::XDevice;
+using ::com::sun::star::awt::DeviceInfo;
+using ::com::sun::star::frame::XFrame;
+using ::com::sun::star::frame::XFramesSupplier;
+using ::com::sun::star::lang::XMultiServiceFactory;
+
+using namespace ::com::sun::star;
+
+// Global data ================================================================
+
+#ifdef DBG_UTIL
+XclDebugObjCounter::~XclDebugObjCounter()
+{
+ DBG_ASSERT( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" );
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
+ meBiff( eBiff ),
+ meOutput( EXC_OUTPUT_BINARY ),
+ mrMedium( rMedium ),
+ mxRootStrg( xRootStrg ),
+ mrDoc( rDoc ),
+ maDefPassword( CREATE_STRING( "VelvetSweatshop" ) ),
+ meTextEnc( eTextEnc ),
+ meSysLang( Application::GetSettings().GetLanguage() ),
+ meDocLang( Application::GetSettings().GetLanguage() ),
+ meUILang( Application::GetSettings().GetUILanguage() ),
+ mnDefApiScript( ApiScriptType::LATIN ),
+ maScMaxPos( MAXCOL, MAXROW, MAXTAB ),
+ maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
+ maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
+ mxFontPropSetHlp( new XclFontPropSetHelper ),
+ mxChPropSetHlp( new XclChPropSetHelper ),
+ mxRD( new RootData ),//!
+ mfScreenPixelX( 50.0 ),
+ mfScreenPixelY( 50.0 ),
+ mnCharWidth( 110 ),
+ mnScTab( 0 ),
+ mbExport( bExport )
+{
+ maUserName = SvtUserOptions().GetLastName();
+ if( maUserName.Len() == 0 )
+ maUserName = CREATE_STRING( "Calc" );
+
+ switch( ScGlobal::GetDefaultScriptType() )
+ {
+ case SCRIPTTYPE_LATIN: mnDefApiScript = ApiScriptType::LATIN; break;
+ case SCRIPTTYPE_ASIAN: mnDefApiScript = ApiScriptType::ASIAN; break;
+ case SCRIPTTYPE_COMPLEX: mnDefApiScript = ApiScriptType::COMPLEX; break;
+ default: DBG_ERRORFILE( "XclRootData::XclRootData - unknown script type" );
+ }
+
+ // maximum cell position
+ switch( meBiff )
+ {
+ case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ); break;
+ case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 ); break;
+ case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 ); break;
+ case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 ); break;
+ case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 ); break;
+ default: DBG_ERROR_BIFF();
+ }
+ maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) );
+ maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) );
+ maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) );
+
+ // document URL and path
+ if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() )
+ if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
+ maDocUrl = pItem->GetValue();
+ maBasePath = maDocUrl.Copy( 0, maDocUrl.SearchBackward( '/' ) + 1 );
+
+ // extended document options - always own object, try to copy existing data from document
+ if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() )
+ mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) );
+ else
+ mxExtDocOpt.reset( new ScExtDocOptions );
+
+ // screen pixel size
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
+ Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW );
+ Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
+ Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
+ DeviceInfo aDeviceInfo = xDevice->getInfo();
+ mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
+ mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
+ }
+ catch( Exception& )
+ {
+ OSL_FAIL( "XclRootData::XclRootData - cannot get output device info" );
+ }
+}
+
+XclRootData::~XclRootData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclRoot::XclRoot( XclRootData& rRootData ) :
+ mrData( rRootData )
+{
+#ifdef DBG_UTIL
+ ++mrData.mnObjCnt;
+#endif
+
+ // filter tracer
+ // do not use CREATE_OUSTRING for conditional expression
+ mrData.mxTracer.reset( new XclTracer( GetDocUrl(), IsExport() ?
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Tracing/Export/Excel"))
+ : OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Tracing/Import/Excel" )) ) );
+}
+
+XclRoot::XclRoot( const XclRoot& rRoot ) :
+ mrData( rRoot.mrData )
+{
+#ifdef DBG_UTIL
+ ++mrData.mnObjCnt;
+#endif
+}
+
+XclRoot::~XclRoot()
+{
+#ifdef DBG_UTIL
+ --mrData.mnObjCnt;
+#endif
+}
+
+XclRoot& XclRoot::operator=( const XclRoot& rRoot )
+{
+ (void)rRoot; // avoid compiler warning
+ // allowed for assignment in derived classes - but test if the same root data is used
+ DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
+ return *this;
+}
+
+void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ mrData.meTextEnc = eTextEnc;
+}
+
+void XclRoot::SetCharWidth( const XclFontData& rFontData )
+{
+ mrData.mnCharWidth = 0;
+ if( OutputDevice* pPrinter = GetPrinter() )
+ {
+ Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
+ aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) );
+ aFont.SetCharSet( rFontData.GetFontEncoding() );
+ aFont.SetWeight( rFontData.GetScWeight() );
+ pPrinter->SetFont( aFont );
+ mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) );
+ }
+ if( mrData.mnCharWidth <= 0 )
+ {
+ // #i48717# Win98 with HP LaserJet returns 0
+ DBG_ERRORFILE( "XclRoot::SetCharWidth - invalid character width (no printer?)" );
+ mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
+ }
+}
+
+sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
+{
+ return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
+}
+
+sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
+{
+ return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
+}
+
+double XclRoot::GetPixelXFromHmm( sal_Int32 nX ) const
+{
+ return static_cast< double >( (nX - 0.5) / mrData.mfScreenPixelX );
+}
+
+double XclRoot::GetPixelYFromHmm( sal_Int32 nY ) const
+{
+ return static_cast< double >( (nY - 0.5) / mrData.mfScreenPixelY );
+}
+
+uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
+{
+ ::std::vector< OUString > aDefaultPasswords;
+ aDefaultPasswords.push_back( mrData.maDefPassword );
+ return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords );
+}
+
+bool XclRoot::HasVbaStorage() const
+{
+ SotStorageRef xRootStrg = GetRootStorage();
+ return xRootStrg.Is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT );
+}
+
+SotStorageRef XclRoot::OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const
+{
+ return mrData.mbExport ?
+ ScfTools::OpenStorageWrite( xStrg, rStrgName ) :
+ ScfTools::OpenStorageRead( xStrg, rStrgName );
+}
+
+SotStorageRef XclRoot::OpenStorage( const String& rStrgName ) const
+{
+ return OpenStorage( GetRootStorage(), rStrgName );
+}
+
+SotStorageStreamRef XclRoot::OpenStream( SotStorageRef xStrg, const String& rStrmName ) const
+{
+ return mrData.mbExport ?
+ ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) :
+ ScfTools::OpenStorageStreamRead( xStrg, rStrmName );
+}
+
+SotStorageStreamRef XclRoot::OpenStream( const String& rStrmName ) const
+{
+ return OpenStream( GetRootStorage(), rStrmName );
+}
+
+SfxObjectShell* XclRoot::GetDocShell() const
+{
+ return GetDoc().GetDocumentShell();
+}
+
+ScModelObj* XclRoot::GetDocModelObj() const
+{
+ SfxObjectShell* pDocShell = GetDocShell();
+ return pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : 0;
+}
+
+OutputDevice* XclRoot::GetPrinter() const
+{
+ return GetDoc().GetRefDevice();
+}
+
+ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
+{
+ return *GetDoc().GetStyleSheetPool();
+}
+
+ScRangeName& XclRoot::GetNamedRanges() const
+{
+ return *GetDoc().GetRangeName();
+}
+
+ScDBCollection& XclRoot::GetDatabaseRanges() const
+{
+ return *GetDoc().GetDBCollection();
+}
+
+SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const
+{
+ return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ?
+ GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : 0;
+}
+
+SvNumberFormatter& XclRoot::GetFormatter() const
+{
+ return *GetDoc().GetFormatTable();
+}
+
+DateTime XclRoot::GetNullDate() const
+{
+ return *GetFormatter().GetNullDate();
+}
+
+sal_uInt16 XclRoot::GetBaseYear() const
+{
+ // return 1904 for 1904-01-01, and 1900 for 1899-12-30
+ return (GetNullDate().GetYear() == 1904) ? 1904 : 1900;
+}
+
+double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const
+{
+ double fValue = rDateTime - GetNullDate();
+ // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0)
+ if( rDateTime < DateTime( Date( 1, 3, 1900 ) ) )
+ fValue -= 1.0;
+ return fValue;
+}
+
+DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const
+{
+ DateTime aDateTime = GetNullDate() + fValue;
+ // adjust dates before 1900-03-01 to get correct time values
+ if( aDateTime < DateTime( Date( 1, 3, 1900 ) ) )
+ aDateTime += 1L;
+ return aDateTime;
+}
+
+ScEditEngineDefaulter& XclRoot::GetEditEngine() const
+{
+ if( !mrData.mxEditEngine.get() )
+ {
+ mrData.mxEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
+ ScEditEngineDefaulter& rEE = *mrData.mxEditEngine;
+ rEE.SetRefMapMode( MAP_100TH_MM );
+ rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
+ rEE.SetUpdateMode( false );
+ rEE.EnableUndo( false );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+ }
+ return *mrData.mxEditEngine;
+}
+
+ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
+{
+ if( !mrData.mxHFEditEngine.get() )
+ {
+ mrData.mxHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True ) );
+ ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine;
+ rEE.SetRefMapMode( MAP_TWIP ); // headers/footers use twips as default metric
+ rEE.SetUpdateMode( false );
+ rEE.EnableUndo( false );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+
+ // set Calc header/footer defaults
+ SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
+ SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
+ ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
+ // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
+ pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
+ pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
+ pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
+ rEE.SetDefaults( pEditSet ); // takes ownership
+ }
+ return *mrData.mxHFEditEngine;
+}
+
+EditEngine& XclRoot::GetDrawEditEngine() const
+{
+ if( !mrData.mxDrawEditEng.get() )
+ {
+ mrData.mxDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
+ EditEngine& rEE = *mrData.mxDrawEditEng;
+ rEE.SetRefMapMode( MAP_100TH_MM );
+ rEE.SetUpdateMode( false );
+ rEE.EnableUndo( false );
+ rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
+ }
+ return *mrData.mxDrawEditEng;
+}
+
+XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const
+{
+ return *mrData.mxFontPropSetHlp;
+}
+
+XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const
+{
+ return *mrData.mxChPropSetHlp;
+}
+
+ScExtDocOptions& XclRoot::GetExtDocOptions() const
+{
+ return *mrData.mxExtDocOpt;
+}
+
+XclTracer& XclRoot::GetTracer() const
+{
+ return *mrData.mxTracer;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlstyle.cxx b/sc/source/filter/excel/xlstyle.cxx
new file mode 100644
index 000000000000..85537d32e547
--- /dev/null
+++ b/sc/source/filter/excel/xlstyle.cxx
@@ -0,0 +1,1772 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "xlstyle.hxx"
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/font.hxx>
+#include <sal/macros.h>
+#include <rtl/tencinfo.h>
+#include <toolkit/unohlp.hxx>
+#include <editeng/svxfont.hxx>
+#include "global.hxx"
+#include "xlroot.hxx"
+
+// Color data =================================================================
+
+/** Standard EGA colors, bright. */
+#define EXC_PALETTE_EGA_COLORS_LIGHT \
+ 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
+/** Standard EGA colors, dark. */
+#define EXC_PALETTE_EGA_COLORS_DARK \
+ 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
+
+/** Default color table for BIFF2. */
+static const ColorData spnDefColorTable2[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT
+};
+
+/** Default color table for BIFF3/BIFF4. */
+static const ColorData spnDefColorTable3[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_PALETTE_EGA_COLORS_DARK
+};
+
+/** Default color table for BIFF5/BIFF7. */
+static const ColorData spnDefColorTable5[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_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. */
+static const ColorData spnDefColorTable8[] =
+{
+/* 0 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ EXC_PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ EXC_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 EXC_PALETTE_EGA_COLORS_LIGHT
+#undef EXC_PALETTE_EGA_COLORS_DARK
+
+// ----------------------------------------------------------------------------
+
+XclDefaultPalette::XclDefaultPalette( const XclRoot& rRoot ) :
+ mpnColorTable( 0 ),
+ mnTableSize( 0 )
+{
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+ mnWindowText = rSett.GetWindowTextColor().GetColor();
+ mnWindowBack = rSett.GetWindowColor().GetColor();
+ mnFaceColor = rSett.GetFaceColor().GetColor();
+ mnNoteText = rSett.GetHelpTextColor().GetColor();
+ mnNoteBack = rSett.GetHelpColor().GetColor();
+
+ // default colors
+ switch( rRoot.GetBiff() )
+ {
+ case EXC_BIFF2:
+ mpnColorTable = spnDefColorTable2;
+ mnTableSize = SAL_N_ELEMENTS( spnDefColorTable2 );
+ break;
+ case EXC_BIFF3:
+ case EXC_BIFF4:
+ mpnColorTable = spnDefColorTable3;
+ mnTableSize = SAL_N_ELEMENTS( spnDefColorTable3 );
+ break;
+ case EXC_BIFF5:
+ mpnColorTable = spnDefColorTable5;
+ mnTableSize = SAL_N_ELEMENTS( spnDefColorTable5 );
+ break;
+ case EXC_BIFF8:
+ mpnColorTable = spnDefColorTable8;
+ mnTableSize = SAL_N_ELEMENTS( spnDefColorTable8 );
+ break;
+ default:
+ DBG_ERROR_BIFF();
+ }
+}
+
+ColorData XclDefaultPalette::GetDefColorData( sal_uInt16 nXclIndex ) const
+{
+ ColorData nColor;
+ if( nXclIndex < mnTableSize )
+ nColor = mpnColorTable[ nXclIndex ];
+ else switch( nXclIndex )
+ {
+ case EXC_COLOR_WINDOWTEXT3:
+ case EXC_COLOR_WINDOWTEXT:
+ case EXC_COLOR_CHWINDOWTEXT: nColor = mnWindowText; break;
+ case EXC_COLOR_WINDOWBACK3:
+ case EXC_COLOR_WINDOWBACK:
+ case EXC_COLOR_CHWINDOWBACK: nColor = mnWindowBack; break;
+ case EXC_COLOR_BUTTONBACK: nColor = mnFaceColor; break;
+ case EXC_COLOR_CHBORDERAUTO: nColor = COL_BLACK; break; // TODO: really always black?
+ case EXC_COLOR_NOTEBACK: nColor = mnNoteBack; break;
+ case EXC_COLOR_NOTETEXT: nColor = mnNoteText; break;
+ case EXC_COLOR_FONTAUTO: nColor = COL_AUTO; break;
+ default:
+ OSL_TRACE( "XclDefaultPalette::GetDefColorData - unknown default color index: %d", nXclIndex );
+ nColor = COL_AUTO;
+ }
+ return nColor;
+}
+
+// Font Data ==================================================================
+
+namespace Awt = ::com::sun::star::awt;
+namespace AwtFontFamily = Awt::FontFamily;
+namespace AwtFontUnderline = Awt::FontUnderline;
+namespace AwtFontStrikeout = Awt::FontStrikeout;
+
+// ----------------------------------------------------------------------------
+
+XclFontData::XclFontData()
+{
+ Clear();
+}
+
+XclFontData::XclFontData( const Font& rFont )
+{
+ Clear();
+ FillFromVclFont( rFont );
+}
+
+XclFontData::XclFontData( const SvxFont& rFont )
+{
+ FillFromSvxFont( rFont );
+}
+
+void XclFontData::Clear()
+{
+ maName.Erase();
+ maStyle.Erase();
+ maColor.SetColor( COL_AUTO );
+ mnHeight = 0;
+ mnWeight = EXC_FONTWGHT_DONTKNOW;
+ mnEscapem = EXC_FONTESC_NONE;
+ mnFamily = EXC_FONTFAM_SYSTEM;
+ mnCharSet = EXC_FONTCSET_ANSI_LATIN;
+ mnUnderline = EXC_FONTUNDERL_NONE;
+ mbItalic = mbStrikeout = mbOutline = mbShadow = false;
+}
+
+void XclFontData::FillFromVclFont( const Font& rFont )
+{
+ maName = XclTools::GetXclFontName( rFont.GetName() ); // substitute with MS fonts
+ maStyle.Erase();
+ maColor = rFont.GetColor();
+ SetScUnderline( rFont.GetUnderline() );
+ mnEscapem = EXC_FONTESC_NONE;
+ SetScHeight( rFont.GetSize().Height() );
+ SetScWeight( rFont.GetWeight() );
+ SetScFamily( rFont.GetFamily() );
+ SetFontEncoding( rFont.GetCharSet() );
+ SetScPosture( rFont.GetItalic() );
+ SetScStrikeout( rFont.GetStrikeout() );
+ mbOutline = rFont.IsOutline();
+ mbShadow = rFont.IsShadow();
+}
+
+void XclFontData::FillFromSvxFont( const SvxFont& rFont )
+{
+ FillFromVclFont( rFont );
+ SetScEscapement( rFont.GetEscapement() );
+}
+
+// *** conversion of VCL/SVX constants *** ------------------------------------
+
+FontFamily XclFontData::GetScFamily( rtl_TextEncoding eDefTextEnc ) const
+{
+ FontFamily eScFamily;
+ // ! format differs from Windows documentation: family is in lower nibble, pitch unknown
+ switch( mnFamily & 0x0F )
+ {
+ case EXC_FONTFAM_ROMAN: eScFamily = FAMILY_ROMAN; break;
+ case EXC_FONTFAM_SWISS: eScFamily = FAMILY_SWISS; break;
+ case EXC_FONTFAM_MODERN: eScFamily = FAMILY_MODERN; break;
+ case EXC_FONTFAM_SCRIPT: eScFamily = FAMILY_SCRIPT; break;
+ case EXC_FONTFAM_DECORATIVE: eScFamily = FAMILY_DECORATIVE; break;
+ default:
+ eScFamily =
+ ((eDefTextEnc == RTL_TEXTENCODING_APPLE_ROMAN) &&
+ (maName.EqualsIgnoreCaseAscii( "Geneva" ) || maName.EqualsIgnoreCaseAscii( "Chicago" ))) ?
+ FAMILY_SWISS : FAMILY_DONTKNOW;
+ }
+ return eScFamily;
+}
+
+rtl_TextEncoding XclFontData::GetFontEncoding() const
+{
+ // convert Windows character set to text encoding identifier
+ return rtl_getTextEncodingFromWindowsCharset( mnCharSet );
+}
+
+FontItalic XclFontData::GetScPosture() const
+{
+ return mbItalic ? ITALIC_NORMAL : ITALIC_NONE;
+}
+
+FontWeight XclFontData::GetScWeight() const
+{
+ FontWeight eScWeight;
+
+ if( !mnWeight ) eScWeight = WEIGHT_DONTKNOW;
+ else if( mnWeight < 150 ) eScWeight = WEIGHT_THIN;
+ else if( mnWeight < 250 ) eScWeight = WEIGHT_ULTRALIGHT;
+ else if( mnWeight < 325 ) eScWeight = WEIGHT_LIGHT;
+ else if( mnWeight < 375 ) eScWeight = WEIGHT_SEMILIGHT;
+ else if( mnWeight < 450 ) eScWeight = WEIGHT_NORMAL;
+ else if( mnWeight < 550 ) eScWeight = WEIGHT_MEDIUM;
+ else if( mnWeight < 650 ) eScWeight = WEIGHT_SEMIBOLD;
+ else if( mnWeight < 750 ) eScWeight = WEIGHT_BOLD;
+ else if( mnWeight < 850 ) eScWeight = WEIGHT_ULTRABOLD;
+ else eScWeight = WEIGHT_BLACK;
+
+ return eScWeight;
+}
+
+FontUnderline XclFontData::GetScUnderline() const
+{
+ FontUnderline eScUnderl = UNDERLINE_NONE;
+ switch( mnUnderline )
+ {
+ case EXC_FONTUNDERL_SINGLE:
+ case EXC_FONTUNDERL_SINGLE_ACC: eScUnderl = UNDERLINE_SINGLE; break;
+ case EXC_FONTUNDERL_DOUBLE:
+ case EXC_FONTUNDERL_DOUBLE_ACC: eScUnderl = UNDERLINE_DOUBLE; break;
+ }
+ return eScUnderl;
+}
+
+SvxEscapement XclFontData::GetScEscapement() const
+{
+ SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
+ switch( mnEscapem )
+ {
+ case EXC_FONTESC_SUPER: eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT; break;
+ case EXC_FONTESC_SUB: eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT; break;
+ }
+ return eScEscapem;
+}
+
+FontStrikeout XclFontData::GetScStrikeout() const
+{
+ return mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE;
+}
+
+void XclFontData::SetScHeight( sal_Int32 nTwips )
+{
+ mnHeight = static_cast< sal_uInt16 >( ::std::min( nTwips, static_cast<sal_Int32>(0x7FFFL) ) );
+}
+
+void XclFontData::SetScFamily( FontFamily eScFamily )
+{
+ switch( eScFamily )
+ {
+ case FAMILY_DONTKNOW: mnFamily = EXC_FONTFAM_DONTKNOW; break;
+ case FAMILY_DECORATIVE: mnFamily = EXC_FONTFAM_DECORATIVE; break;
+ case FAMILY_MODERN: mnFamily = EXC_FONTFAM_MODERN; break;
+ case FAMILY_ROMAN: mnFamily = EXC_FONTFAM_ROMAN; break;
+ case FAMILY_SCRIPT: mnFamily = EXC_FONTFAM_SCRIPT; break;
+ case FAMILY_SWISS: mnFamily = EXC_FONTFAM_SWISS; break;
+ case FAMILY_SYSTEM: mnFamily = EXC_FONTFAM_SYSTEM; break;
+ default:
+ DBG_ERRORFILE( "XclFontData::SetScFamily - unknown font family" );
+ mnFamily = EXC_FONTFAM_DONTKNOW;
+ }
+}
+
+void XclFontData::SetFontEncoding( rtl_TextEncoding eFontEnc )
+{
+ // convert text encoding identifier to Windows character set
+ mnCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontEnc );
+}
+
+
+void XclFontData::SetScPosture( FontItalic eScPosture )
+{
+ mbItalic = (eScPosture == ITALIC_OBLIQUE) || (eScPosture == ITALIC_NORMAL);
+}
+
+void XclFontData::SetScWeight( FontWeight eScWeight )
+{
+ switch( eScWeight )
+ {
+ case WEIGHT_DONTKNOW: mnWeight = EXC_FONTWGHT_DONTKNOW; break;
+ case WEIGHT_THIN: mnWeight = EXC_FONTWGHT_THIN; break;
+ case WEIGHT_ULTRALIGHT: mnWeight = EXC_FONTWGHT_ULTRALIGHT; break;
+ case WEIGHT_LIGHT: mnWeight = EXC_FONTWGHT_LIGHT; break;
+ case WEIGHT_SEMILIGHT: mnWeight = EXC_FONTWGHT_SEMILIGHT; break;
+ case WEIGHT_NORMAL: mnWeight = EXC_FONTWGHT_NORMAL; break;
+ case WEIGHT_MEDIUM: mnWeight = EXC_FONTWGHT_MEDIUM; break;
+ case WEIGHT_SEMIBOLD: mnWeight = EXC_FONTWGHT_SEMIBOLD; break;
+ case WEIGHT_BOLD: mnWeight = EXC_FONTWGHT_BOLD; break;
+ case WEIGHT_ULTRABOLD: mnWeight = EXC_FONTWGHT_ULTRABOLD; break;
+ case WEIGHT_BLACK: mnWeight = EXC_FONTWGHT_BLACK; break;
+ default: mnWeight = EXC_FONTWGHT_NORMAL;
+ }
+}
+
+void XclFontData::SetScUnderline( FontUnderline eScUnderl )
+{
+ switch( eScUnderl )
+ {
+ case UNDERLINE_NONE:
+ case UNDERLINE_DONTKNOW: mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case UNDERLINE_DOUBLE:
+ case UNDERLINE_DOUBLEWAVE: mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+}
+
+void XclFontData::SetScEscapement( short nScEscapem )
+{
+ if( nScEscapem > 0 )
+ mnEscapem = EXC_FONTESC_SUPER;
+ else if( nScEscapem < 0 )
+ mnEscapem = EXC_FONTESC_SUB;
+ else
+ mnEscapem = EXC_FONTESC_NONE;
+}
+
+void XclFontData::SetScStrikeout( FontStrikeout eScStrikeout )
+{
+ mbStrikeout =
+ (eScStrikeout == STRIKEOUT_SINGLE) || (eScStrikeout == STRIKEOUT_DOUBLE) ||
+ (eScStrikeout == STRIKEOUT_BOLD) || (eScStrikeout == STRIKEOUT_SLASH) ||
+ (eScStrikeout == STRIKEOUT_X);
+}
+
+// *** conversion of API constants *** ----------------------------------------
+
+float XclFontData::GetApiHeight() const
+{
+ return static_cast< float >( mnHeight / TWIPS_PER_POINT );
+}
+
+sal_Int16 XclFontData::GetApiFamily() const
+{
+ sal_Int16 nApiFamily = AwtFontFamily::DONTKNOW;
+ switch( mnFamily )
+ {
+ case FAMILY_DECORATIVE: nApiFamily = AwtFontFamily::DECORATIVE; break;
+ case FAMILY_MODERN: nApiFamily = AwtFontFamily::MODERN; break;
+ case FAMILY_ROMAN: nApiFamily = AwtFontFamily::ROMAN; break;
+ case FAMILY_SCRIPT: nApiFamily = AwtFontFamily::SCRIPT; break;
+ case FAMILY_SWISS: nApiFamily = AwtFontFamily::SWISS; break;
+ case FAMILY_SYSTEM: nApiFamily = AwtFontFamily::SYSTEM; break;
+ }
+ return nApiFamily;
+}
+
+sal_Int16 XclFontData::GetApiFontEncoding() const
+{
+ // API constants are equal to rtl_TextEncoding constants
+ return static_cast< sal_Int16 >( GetFontEncoding() );
+}
+
+Awt::FontSlant XclFontData::GetApiPosture() const
+{
+ return mbItalic ? Awt::FontSlant_ITALIC : Awt::FontSlant_NONE;
+}
+
+float XclFontData::GetApiWeight() const
+{
+ return VCLUnoHelper::ConvertFontWeight( GetScWeight() );
+}
+
+sal_Int16 XclFontData::GetApiUnderline() const
+{
+ sal_Int16 nApiUnderl = AwtFontUnderline::NONE;
+ switch( mnUnderline )
+ {
+ case EXC_FONTUNDERL_SINGLE:
+ case EXC_FONTUNDERL_SINGLE_ACC: nApiUnderl = AwtFontUnderline::SINGLE; break;
+ case EXC_FONTUNDERL_DOUBLE:
+ case EXC_FONTUNDERL_DOUBLE_ACC: nApiUnderl = AwtFontUnderline::DOUBLE; break;
+ }
+ return nApiUnderl;
+}
+
+sal_Int16 XclFontData::GetApiEscapement() const
+{
+ sal_Int16 nApiEscapem = 0;
+ switch( mnEscapem )
+ {
+ case EXC_FONTESC_SUPER: nApiEscapem = 33; break;
+ case EXC_FONTESC_SUB: nApiEscapem = -33; break;
+ }
+ return nApiEscapem;
+}
+
+sal_Int16 XclFontData::GetApiStrikeout() const
+{
+ return mbStrikeout ? AwtFontStrikeout::SINGLE : AwtFontStrikeout::NONE;
+}
+
+void XclFontData::SetApiHeight( float fPoint )
+{
+ mnHeight = static_cast< sal_uInt16 >( ::std::min( fPoint * TWIPS_PER_POINT + 0.5, 32767.0 ) );
+}
+
+void XclFontData::SetApiFamily( sal_Int16 nApiFamily )
+{
+ switch( nApiFamily )
+ {
+ case AwtFontFamily::DECORATIVE: mnFamily = FAMILY_DECORATIVE; break;
+ case AwtFontFamily::MODERN: mnFamily = FAMILY_MODERN; break;
+ case AwtFontFamily::ROMAN: mnFamily = FAMILY_ROMAN; break;
+ case AwtFontFamily::SCRIPT: mnFamily = FAMILY_SCRIPT; break;
+ case AwtFontFamily::SWISS: mnFamily = FAMILY_SWISS; break;
+ case AwtFontFamily::SYSTEM: mnFamily = FAMILY_SYSTEM; break;
+ default: mnFamily = FAMILY_DONTKNOW;
+ }
+}
+
+void XclFontData::SetApiPosture( Awt::FontSlant eApiPosture )
+{
+ mbItalic =
+ (eApiPosture == Awt::FontSlant_OBLIQUE) ||
+ (eApiPosture == Awt::FontSlant_ITALIC) ||
+ (eApiPosture == Awt::FontSlant_REVERSE_OBLIQUE) ||
+ (eApiPosture == Awt::FontSlant_REVERSE_ITALIC);
+}
+
+void XclFontData::SetApiWeight( float fApiWeight )
+{
+ SetScWeight( VCLUnoHelper::ConvertFontWeight( fApiWeight ) );
+}
+
+void XclFontData::SetApiUnderline( sal_Int16 nApiUnderl )
+{
+ switch( nApiUnderl )
+ {
+ case AwtFontUnderline::NONE:
+ case AwtFontUnderline::DONTKNOW: mnUnderline = EXC_FONTUNDERL_NONE; break;
+ case AwtFontUnderline::DOUBLE:
+ case AwtFontUnderline::DOUBLEWAVE: mnUnderline = EXC_FONTUNDERL_DOUBLE; break;
+ default: mnUnderline = EXC_FONTUNDERL_SINGLE;
+ }
+}
+
+void XclFontData::SetApiEscapement( sal_Int16 nApiEscapem )
+{
+ if( nApiEscapem > 0 )
+ mnEscapem = EXC_FONTESC_SUPER;
+ else if( nApiEscapem < 0 )
+ mnEscapem = EXC_FONTESC_SUB;
+ else
+ mnEscapem = EXC_FONTESC_NONE;
+}
+
+void XclFontData::SetApiStrikeout( sal_Int16 nApiStrikeout )
+{
+ mbStrikeout =
+ (nApiStrikeout != AwtFontStrikeout::NONE) &&
+ (nApiStrikeout != AwtFontStrikeout::DONTKNOW);
+}
+
+// ----------------------------------------------------------------------------
+
+bool operator==( const XclFontData& rLeft, const XclFontData& rRight )
+{
+ return
+ (rLeft.mnHeight == rRight.mnHeight) &&
+ (rLeft.mnWeight == rRight.mnWeight) &&
+ (rLeft.mnUnderline == rRight.mnUnderline) &&
+ (rLeft.maColor == rRight.maColor) &&
+ (rLeft.mnEscapem == rRight.mnEscapem) &&
+ (rLeft.mnFamily == rRight.mnFamily) &&
+ (rLeft.mnCharSet == rRight.mnCharSet) &&
+ (rLeft.mbItalic == rRight.mbItalic) &&
+ (rLeft.mbStrikeout == rRight.mbStrikeout) &&
+ (rLeft.mbOutline == rRight.mbOutline) &&
+ (rLeft.mbShadow == rRight.mbShadow) &&
+ (rLeft.maName == rRight.maName);
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+/** Property names for common font settings. */
+const sal_Char *const sppcPropNamesChCommon[] =
+{
+ "CharUnderline", "CharStrikeout", "CharColor", "CharContoured", "CharShadowed", 0
+};
+/** Property names for Western font settings. */
+const sal_Char *const sppcPropNamesChWstrn[] =
+{
+ "CharFontName", "CharHeight", "CharPosture", "CharWeight", 0
+};
+/** Property names for Asian font settings. */
+const sal_Char *const sppcPropNamesChAsian[] =
+{
+ "CharFontNameAsian", "CharHeightAsian", "CharPostureAsian", "CharWeightAsian", 0
+};
+/** Property names for Complex font settings. */
+const sal_Char *const sppcPropNamesChCmplx[] =
+{
+ "CharFontNameComplex", "CharHeightComplex", "CharPostureComplex", "CharWeightComplex", 0
+};
+/** Property names for escapement. */
+const sal_Char *const sppcPropNamesChEscapement[] =
+{
+ "CharEscapement", "CharEscapementHeight", 0
+};
+const sal_Int8 EXC_API_ESC_HEIGHT = 58; /// Default escapement font height.
+
+/** Property names for Western font settings without font name. */
+const sal_Char *const *const sppcPropNamesChWstrnNoName = sppcPropNamesChWstrn + 1;
+/** Property names for Asian font settings without font name. */
+const sal_Char *const *const sppcPropNamesChAsianNoName = sppcPropNamesChAsian + 1;
+/** Property names for Complex font settings without font name. */
+const sal_Char *const *const sppcPropNamesChCmplxNoName = sppcPropNamesChCmplx + 1;
+
+/** Property names for font settings in form controls. */
+const sal_Char *const sppcPropNamesControl[] =
+{
+ "FontName", "FontFamily", "FontCharset", "FontHeight", "FontSlant",
+ "FontWeight", "FontUnderline", "FontStrikeout", "TextColor", 0
+};
+
+/** Inserts all passed API font settings into the font data object. */
+void lclSetApiFontSettings( XclFontData& rFontData,
+ const String& rApiFontName, float fApiHeight, float fApiWeight,
+ Awt::FontSlant eApiPosture, sal_Int16 nApiUnderl, sal_Int16 nApiStrikeout )
+{
+ rFontData.maName = XclTools::GetXclFontName( rApiFontName );
+ rFontData.SetApiHeight( fApiHeight );
+ rFontData.SetApiWeight( fApiWeight );
+ rFontData.SetApiPosture( eApiPosture );
+ rFontData.SetApiUnderline( nApiUnderl );
+ rFontData.SetApiStrikeout( nApiStrikeout );
+}
+
+/** Writes script dependent properties to a font property set helper. */
+void lclWriteChartFont( ScfPropertySet& rPropSet,
+ ScfPropSetHelper& rHlpName, ScfPropSetHelper& rHlpNoName,
+ const XclFontData& rFontData, bool bHasFontName )
+{
+ // select the font helper
+ ScfPropSetHelper& rPropSetHlp = bHasFontName ? rHlpName : rHlpNoName;
+ // initialize the font helper (must be called before writing any properties)
+ rPropSetHlp.InitializeWrite();
+ // write font name
+ if( bHasFontName )
+ rPropSetHlp << rFontData.maName;
+ // write remaining properties
+ rPropSetHlp << rFontData.GetApiHeight() << rFontData.GetApiPosture() << rFontData.GetApiWeight();
+ // write properties to property set
+ rPropSetHlp.WriteToPropertySet( rPropSet );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+XclFontPropSetHelper::XclFontPropSetHelper() :
+ maHlpChCommon( sppcPropNamesChCommon ),
+ maHlpChWstrn( sppcPropNamesChWstrn ),
+ maHlpChAsian( sppcPropNamesChAsian ),
+ maHlpChCmplx( sppcPropNamesChCmplx ),
+ maHlpChWstrnNoName( sppcPropNamesChWstrnNoName ),
+ maHlpChAsianNoName( sppcPropNamesChAsianNoName ),
+ maHlpChCmplxNoName( sppcPropNamesChCmplxNoName ),
+ maHlpChEscapement( sppcPropNamesChEscapement ),
+ maHlpControl( sppcPropNamesControl )
+{
+}
+
+void XclFontPropSetHelper::ReadFontProperties( XclFontData& rFontData,
+ const ScfPropertySet& rPropSet, XclFontPropSetType eType, sal_Int16 nScript )
+{
+ switch( eType )
+ {
+ case EXC_FONTPROPSET_CHART:
+ {
+ String aApiFontName;
+ float fApiHeight, fApiWeight;
+ sal_Int16 nApiUnderl = 0, nApiStrikeout = 0;
+ Awt::FontSlant eApiPosture;
+
+ // read script type dependent properties
+ ScfPropSetHelper& rPropSetHlp = GetChartHelper( nScript );
+ rPropSetHlp.ReadFromPropertySet( rPropSet );
+ rPropSetHlp >> aApiFontName >> fApiHeight >> eApiPosture >> fApiWeight;
+ // read common properties
+ maHlpChCommon.ReadFromPropertySet( rPropSet );
+ maHlpChCommon >> nApiUnderl
+ >> nApiStrikeout
+ >> rFontData.maColor
+ >> rFontData.mbOutline
+ >> rFontData.mbShadow;
+
+ // convert API property values to Excel settings
+ lclSetApiFontSettings( rFontData, aApiFontName,
+ fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
+
+ // font escapement
+ sal_Int16 nApiEscapement = 0;
+ sal_Int8 nApiEscHeight = 0;
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement >> nApiEscapement >> nApiEscHeight;
+ rFontData.SetApiEscapement( nApiEscapement );
+ }
+ break;
+
+ case EXC_FONTPROPSET_CONTROL:
+ {
+ String aApiFontName;
+ float fApiHeight, fApiWeight;
+ sal_Int16 nApiFamily, nApiCharSet, nApiPosture, nApiUnderl, nApiStrikeout;
+
+ // read font properties
+ maHlpControl.ReadFromPropertySet( rPropSet );
+ maHlpControl >> aApiFontName
+ >> nApiFamily
+ >> nApiCharSet
+ >> fApiHeight
+ >> nApiPosture
+ >> fApiWeight
+ >> nApiUnderl
+ >> nApiStrikeout
+ >> rFontData.maColor;
+
+ // convert API property values to Excel settings
+ Awt::FontSlant eApiPosture = static_cast< Awt::FontSlant >( nApiPosture );
+ lclSetApiFontSettings( rFontData, aApiFontName,
+ fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
+ rFontData.SetApiFamily( nApiFamily );
+ rFontData.SetFontEncoding( nApiCharSet );
+ }
+ break;
+ }
+}
+
+void XclFontPropSetHelper::WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ const XclFontData& rFontData, bool bHasWstrn, bool bHasAsian, bool bHasCmplx,
+ const Color* pFontColor )
+{
+ switch( eType )
+ {
+ case EXC_FONTPROPSET_CHART:
+ {
+ // write common properties
+ maHlpChCommon.InitializeWrite();
+ const Color& rColor = pFontColor ? *pFontColor : rFontData.maColor;
+ maHlpChCommon << rFontData.GetApiUnderline()
+ << rFontData.GetApiStrikeout()
+ << rColor
+ << rFontData.mbOutline
+ << rFontData.mbShadow;
+ maHlpChCommon.WriteToPropertySet( rPropSet );
+
+ // write script type dependent properties
+ lclWriteChartFont( rPropSet, maHlpChWstrn, maHlpChWstrnNoName, rFontData, bHasWstrn );
+ lclWriteChartFont( rPropSet, maHlpChAsian, maHlpChAsianNoName, rFontData, bHasAsian );
+ lclWriteChartFont( rPropSet, maHlpChCmplx, maHlpChCmplxNoName, rFontData, bHasCmplx );
+
+ // font escapement
+ if( rFontData.GetScEscapement() != SVX_ESCAPEMENT_OFF )
+ {
+ maHlpChEscapement.InitializeWrite();
+ maHlpChEscapement << rFontData.GetApiEscapement() << EXC_API_ESC_HEIGHT;
+ maHlpChEscapement.WriteToPropertySet( rPropSet );
+ }
+ }
+ break;
+
+ case EXC_FONTPROPSET_CONTROL:
+ {
+ maHlpControl.InitializeWrite();
+ maHlpControl << rFontData.maName
+ << rFontData.GetApiFamily()
+ << rFontData.GetApiFontEncoding()
+ << static_cast< sal_Int16 >( rFontData.GetApiHeight() + 0.5 )
+ << rFontData.GetApiPosture()
+ << rFontData.GetApiWeight()
+ << rFontData.GetApiUnderline()
+ << rFontData.GetApiStrikeout()
+ << rFontData.maColor;
+ maHlpControl.WriteToPropertySet( rPropSet );
+ }
+ break;
+ }
+}
+
+ScfPropSetHelper& XclFontPropSetHelper::GetChartHelper( sal_Int16 nScript )
+{
+ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
+ switch( nScript )
+ {
+ case ApiScriptType::LATIN: return maHlpChWstrn;
+ case ApiScriptType::ASIAN: return maHlpChAsian;
+ case ApiScriptType::COMPLEX: return maHlpChCmplx;
+ default: DBG_ERRORFILE( "XclFontPropSetHelper::GetChartHelper - unknown script type" );
+ }
+ return maHlpChWstrn;
+}
+
+// Number formats =============================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+/** Special number format index describing a reused format. */
+const NfIndexTableOffset PRV_NF_INDEX_REUSE = NF_INDEX_TABLE_ENTRIES;
+
+/** German primary language not defined, LANGUAGE_GERMAN belongs to Germany. */
+const LanguageType PRV_LANGUAGE_GERMAN_PRIM = LANGUAGE_GERMAN & LANGUAGE_MASK_PRIMARY;
+/** French primary language not defined, LANGUAGE_FRENCH belongs to France. */
+const LanguageType PRV_LANGUAGE_FRENCH_PRIM = LANGUAGE_FRENCH & LANGUAGE_MASK_PRIMARY;
+/** Parent language identifier for Asian languages (LANGUAGE_CHINESE is a primary only ID). */
+const LanguageType PRV_LANGUAGE_ASIAN_PRIM = LANGUAGE_CHINESE;
+
+// ----------------------------------------------------------------------------
+
+/** Stores the number format used in Calc for an Excel built-in number format. */
+struct XclBuiltInFormat
+{
+ sal_uInt16 mnXclNumFmt; /// Excel built-in index.
+ const sal_Char* mpFormat; /// Format string, may be 0 (meOffset used then).
+ NfIndexTableOffset meOffset; /// SvNumberFormatter format index, if mpFormat==0.
+ sal_uInt16 mnXclReuseFmt; /// Use this Excel format, if meOffset==PRV_NF_INDEX_REUSE.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Defines a literal Excel built-in number format. */
+#define EXC_NUMFMT_STRING( nXclNumFmt, pcUtf8 ) \
+ { nXclNumFmt, pcUtf8, NF_NUMBER_STANDARD, 0 }
+
+/** Defines an Excel built-in number format that maps to an own built-in format. */
+#define EXC_NUMFMT_OFFSET( nXclNumFmt, eOffset ) \
+ { nXclNumFmt, 0, eOffset, 0 }
+
+/** Defines an Excel built-in number format that is the same as the specified. */
+#define EXC_NUMFMT_REUSE( nXclNumFmt, nXclReuse ) \
+ { nXclNumFmt, 0, PRV_NF_INDEX_REUSE, nXclReuse }
+
+/** Terminates an Excel built-in number format table. */
+#define EXC_NUMFMT_ENDTABLE() \
+ { EXC_FORMAT_NOTFOUND, 0, NF_NUMBER_STANDARD, 0 }
+
+// ----------------------------------------------------------------------------
+
+// Currency unit characters
+#define UTF8_BAHT "\340\270\277"
+#define UTF8_EURO "\342\202\254"
+#define UTF8_POUND_UK "\302\243"
+#define UTF8_SHEQEL "\342\202\252"
+#define UTF8_WON "\357\277\246"
+#define UTF8_YEN_CS "\357\277\245"
+#define UTF8_YEN_JP "\302\245"
+
+// 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_HOUR "\346\227\266"
+
+// 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 languages. */
+static const XclBuiltInFormat spBuiltInFormats_DONTKNOW[] =
+{
+ EXC_NUMFMT_OFFSET( 0, NF_NUMBER_STANDARD ), // General
+ EXC_NUMFMT_OFFSET( 1, NF_NUMBER_INT ), // 0
+ EXC_NUMFMT_OFFSET( 2, NF_NUMBER_DEC2 ), // 0.00
+ EXC_NUMFMT_OFFSET( 3, NF_NUMBER_1000INT ), // #,##0
+ EXC_NUMFMT_OFFSET( 4, NF_NUMBER_1000DEC2 ), // #,##0.00
+ // 5...8 contained in file
+ EXC_NUMFMT_OFFSET( 9, NF_PERCENT_INT ), // 0%
+ EXC_NUMFMT_OFFSET( 10, NF_PERCENT_DEC2 ), // 0.00%
+ EXC_NUMFMT_OFFSET( 11, NF_SCIENTIFIC_000E00 ), // 0.00E+00
+ EXC_NUMFMT_OFFSET( 12, NF_FRACTION_1 ), // # ?/?
+ EXC_NUMFMT_OFFSET( 13, NF_FRACTION_2 ), // # ??/??
+
+ // 14...22 date and time formats
+ EXC_NUMFMT_OFFSET( 14, NF_DATE_SYS_DDMMYYYY ),
+ EXC_NUMFMT_OFFSET( 15, NF_DATE_SYS_DMMMYY ),
+ EXC_NUMFMT_OFFSET( 16, NF_DATE_SYS_DDMMM ),
+ EXC_NUMFMT_OFFSET( 17, NF_DATE_SYS_MMYY ),
+ EXC_NUMFMT_OFFSET( 18, NF_TIME_HHMMAMPM ),
+ EXC_NUMFMT_OFFSET( 19, NF_TIME_HHMMSSAMPM ),
+ EXC_NUMFMT_OFFSET( 20, NF_TIME_HHMM ),
+ EXC_NUMFMT_OFFSET( 21, NF_TIME_HHMMSS ),
+ EXC_NUMFMT_OFFSET( 22, NF_DATETIME_SYSTEM_SHORT_HHMM ),
+
+ // 23...36 international formats
+ EXC_NUMFMT_REUSE( 23, 0 ),
+ EXC_NUMFMT_REUSE( 24, 0 ),
+ EXC_NUMFMT_REUSE( 25, 0 ),
+ EXC_NUMFMT_REUSE( 26, 0 ),
+ EXC_NUMFMT_REUSE( 27, 14 ),
+ EXC_NUMFMT_REUSE( 28, 14 ),
+ EXC_NUMFMT_REUSE( 29, 14 ),
+ EXC_NUMFMT_REUSE( 30, 14 ),
+ EXC_NUMFMT_REUSE( 31, 14 ),
+ EXC_NUMFMT_REUSE( 32, 21 ),
+ EXC_NUMFMT_REUSE( 33, 21 ),
+ EXC_NUMFMT_REUSE( 34, 21 ),
+ EXC_NUMFMT_REUSE( 35, 21 ),
+ EXC_NUMFMT_REUSE( 36, 14 ),
+
+ // 37...44 accounting formats
+ // 41...44 contained in file
+ EXC_NUMFMT_STRING( 37, "#,##0;-#,##0" ),
+ EXC_NUMFMT_STRING( 38, "#,##0;[RED]-#,##0" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00;-#,##0.00" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00;[RED]-#,##0.00" ),
+
+ // 45...49 more special formats
+ EXC_NUMFMT_STRING( 45, "mm:ss" ),
+ EXC_NUMFMT_STRING( 46, "[h]:mm:ss" ),
+ EXC_NUMFMT_STRING( 47, "mm:ss.0" ),
+ EXC_NUMFMT_STRING( 48, "##0.0E+0" ),
+ EXC_NUMFMT_OFFSET( 49, NF_TEXT ),
+
+ // 50...81 international formats
+ EXC_NUMFMT_REUSE( 50, 14 ),
+ EXC_NUMFMT_REUSE( 51, 14 ),
+ EXC_NUMFMT_REUSE( 52, 14 ),
+ EXC_NUMFMT_REUSE( 53, 14 ),
+ EXC_NUMFMT_REUSE( 54, 14 ),
+ EXC_NUMFMT_REUSE( 55, 14 ),
+ EXC_NUMFMT_REUSE( 56, 14 ),
+ EXC_NUMFMT_REUSE( 57, 14 ),
+ EXC_NUMFMT_REUSE( 58, 14 ),
+ EXC_NUMFMT_REUSE( 59, 1 ),
+ EXC_NUMFMT_REUSE( 60, 2 ),
+ EXC_NUMFMT_REUSE( 61, 3 ),
+ EXC_NUMFMT_REUSE( 62, 4 ),
+ EXC_NUMFMT_REUSE( 67, 9 ),
+ EXC_NUMFMT_REUSE( 68, 10 ),
+ EXC_NUMFMT_REUSE( 69, 12 ),
+ EXC_NUMFMT_REUSE( 70, 13 ),
+ EXC_NUMFMT_REUSE( 71, 14 ),
+ EXC_NUMFMT_REUSE( 72, 14 ),
+ EXC_NUMFMT_REUSE( 73, 15 ),
+ EXC_NUMFMT_REUSE( 74, 16 ),
+ EXC_NUMFMT_REUSE( 75, 17 ),
+ EXC_NUMFMT_REUSE( 76, 20 ),
+ EXC_NUMFMT_REUSE( 77, 21 ),
+ EXC_NUMFMT_REUSE( 78, 22 ),
+ EXC_NUMFMT_REUSE( 79, 45 ),
+ EXC_NUMFMT_REUSE( 80, 46 ),
+ EXC_NUMFMT_REUSE( 81, 47 ),
+
+ // 82...163 not used, must not occur in a file (Excel may crash)
+
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ENGLISH --------------------------------------------------------------------
+
+/** Base table for English locales. */
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY hh:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_UK[] =
+{
+ EXC_NUMFMT_STRING( 63, UTF8_POUND_UK "#,##0;-" UTF8_POUND_UK "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_POUND_UK "#,##0;[RED]-" UTF8_POUND_UK "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_POUND_UK "#,##0.00;-" UTF8_POUND_UK "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_POUND_UK "#,##0.00;[RED]-" UTF8_POUND_UK "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_EIRE[] =
+{
+ EXC_NUMFMT_STRING( 63, UTF8_EURO "#,##0;-" UTF8_EURO "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO "#,##0;[RED]-" UTF8_EURO "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO "#,##0.00;-" UTF8_EURO "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO "#,##0.00;[RED]-" UTF8_EURO "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_US[] =
+{
+ EXC_NUMFMT_STRING( 14, "M/D/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "M/D/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0_);(#,##0)" ),
+ EXC_NUMFMT_STRING( 38, "#,##0_);[RED](#,##0)" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00_);(#,##0.00)" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00_);[RED](#,##0.00)" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0_);($#,##0)" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0_);[RED]($#,##0)" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00_);($#,##0.00)" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00_);[RED]($#,##0.00)" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_CAN[] =
+{
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_AUS[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/MM/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "D/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ENGLISH_SAFRICA[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY/MM/DD" ),
+ EXC_NUMFMT_OFFSET( 18, NF_TIME_HHMMAMPM ),
+ EXC_NUMFMT_OFFSET( 19, NF_TIME_HHMMSSAMPM ),
+ EXC_NUMFMT_STRING( 22, "YYYY/MM/DD hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\\R #,##0;\\R -#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\\R #,##0;[RED]\\R -#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\\R #,##0.00;\\R -#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\\R #,##0.00;[RED]\\R -#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// FRENCH ---------------------------------------------------------------------
+
+/** Base table for French locales. */
+static const XclBuiltInFormat spBuiltInFormats_FRENCH[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_FRANCE[] =
+{
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0\\ _" UTF8_EURO ";-#,##0\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0\\ _" UTF8_EURO ";[RED]-#,##0\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00\\ _" UTF8_EURO ";-#,##0.00\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00\\ _" UTF8_EURO ";[RED]-#,##0.00\\ _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0\\ " UTF8_EURO ";-#,##0\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0\\ " UTF8_EURO ";[RED]-#,##0\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00\\ " UTF8_EURO ";-#,##0.00\\ " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00\\ " UTF8_EURO ";[RED]-#,##0.00\\ " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_CANADIAN[] =
+{
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0\\ _$_-;#,##0\\ _$-" ),
+ EXC_NUMFMT_STRING( 38, "#,##0\\ _$_-;[RED]#,##0\\ _$-" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00\\ _$_-;#,##0.00\\ _$-" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00\\ _$_-;[RED]#,##0.00\\ _$-" ),
+ EXC_NUMFMT_STRING( 63, "#,##0\\ $_-;#,##0\\ $-" ),
+ EXC_NUMFMT_STRING( 64, "#,##0\\ $_-;[RED]#,##0\\ $-" ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00\\ $_-;#,##0.00\\ $-" ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00\\ $_-;[RED]#,##0.00\\ $-" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_FRENCH_BELGIAN[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/MM/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "D/MM/YYYY h:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// GERMAN ---------------------------------------------------------------------
+
+/** Base table for German locales. */
+static const XclBuiltInFormat spBuiltInFormats_GERMAN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD. MMM YY" ),
+ EXC_NUMFMT_STRING( 16, "DD. MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_GERMANY[] =
+{
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_AUSTRIAN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_LUXEMBOURG[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_GERMAN_LIECHTENSTEIN[] =
+{
+ EXC_NUMFMT_STRING( 63, "\"CHF \"#,##0;\"CHF \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"CHF \"#,##0;[RED]\"CHF \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"CHF \"#,##0.00;\"CHF \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"CHF \"#,##0.00;[RED]\"CHF \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ITALIAN --------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_ITALIAN_ITALY[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 22, "DD/MM/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_ITALIAN_SWISS[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "DD.MM.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
+ EXC_NUMFMT_STRING( 65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// SWEDISH --------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_SWEDISH_SWEDEN[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _k_r;-#,##0 _k_r" ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _k_r;[RED]-#,##0 _k_r" ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _k_r;-#,##0.00 _k_r" ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _k_r;[RED]-#,##0.00 _k_r" ),
+ EXC_NUMFMT_STRING( 63, "#,##0 \"kr\";-#,##0 \"kr\"" ),
+ EXC_NUMFMT_STRING( 64, "#,##0 \"kr\";[RED]-#,##0 \"kr\"" ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 \"kr\";-#,##0.00 \"kr\"" ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 \"kr\";[RED]-#,##0.00 \"kr\"" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_SWEDISH_FINLAND[] =
+{
+ EXC_NUMFMT_STRING( 9, "0 %" ),
+ EXC_NUMFMT_STRING( 10, "0.00 %" ),
+ EXC_NUMFMT_STRING( 15, "DD.MMM.YY" ),
+ EXC_NUMFMT_STRING( 16, "DD.MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM.YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "D.M.YYYY hh:mm" ),
+ EXC_NUMFMT_STRING( 37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
+ EXC_NUMFMT_STRING( 63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_STRING( 66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ASIAN ----------------------------------------------------------------------
+
+/** Base table for Asian locales. */
+static const XclBuiltInFormat spBuiltInFormats_ASIAN[] =
+{
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 20, "h:mm" ),
+ EXC_NUMFMT_STRING( 21, "h:mm:ss" ),
+ EXC_NUMFMT_STRING( 23, "$#,##0_);($#,##0)" ),
+ EXC_NUMFMT_STRING( 24, "$#,##0_);[RED]($#,##0)" ),
+ EXC_NUMFMT_STRING( 25, "$#,##0.00_);($#,##0.00)" ),
+ EXC_NUMFMT_STRING( 26, "$#,##0.00_);[RED]($#,##0.00)" ),
+ EXC_NUMFMT_REUSE( 29, 28 ),
+ EXC_NUMFMT_REUSE( 36, 27 ),
+ EXC_NUMFMT_REUSE( 50, 27 ),
+ EXC_NUMFMT_REUSE( 51, 28 ),
+ EXC_NUMFMT_REUSE( 52, 34 ),
+ EXC_NUMFMT_REUSE( 53, 35 ),
+ EXC_NUMFMT_REUSE( 54, 28 ),
+ EXC_NUMFMT_REUSE( 55, 34 ),
+ EXC_NUMFMT_REUSE( 56, 35 ),
+ EXC_NUMFMT_REUSE( 57, 27 ),
+ EXC_NUMFMT_REUSE( 58, 28 ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_JAPANESE[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY/M/D" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY/M/D h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0411]GE.M.D" ),
+ EXC_NUMFMT_STRING( 28, "[$-0411]GGGE" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0411]M/D/YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
+ EXC_NUMFMT_STRING( 35, "[$-0411]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 63, UTF8_YEN_JP "#,##0;-" UTF8_YEN_JP "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_YEN_JP "#,##0;[RED]-" UTF8_YEN_JP "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_YEN_JP "#,##0.00;-" UTF8_YEN_JP "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_YEN_JP "#,##0.00;[RED]-" UTF8_YEN_JP "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_KOREAN[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY-MM-DD" ),
+ EXC_NUMFMT_STRING( 15, "DD-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-MM-DD h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0412]YYYY" UTF8_CJ_YEAR " MM" UTF8_CJ_MON " DD" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 28, "[$-0412]MM-DD" ),
+ EXC_NUMFMT_STRING( 30, "[$-0412]MM-DD-YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0412]YYYY" UTF8_KO_YEAR " MM" UTF8_KO_MON " DD" UTF8_KO_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN " ss" UTF8_KO_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0412]YYYY\"/\"MM\"/\"DD" ),
+ EXC_NUMFMT_STRING( 35, "[$-0412]YYYY-MM-DD" ),
+ EXC_NUMFMT_STRING( 63, UTF8_WON "#,##0;-" UTF8_WON "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_WON "#,##0;[RED]-" UTF8_WON "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_WON "#,##0.00;-" UTF8_WON "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_WON "#,##0.00;[RED]-" UTF8_WON "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_CHINESE_SIMPLIFIED[] =
+{
+ EXC_NUMFMT_STRING( 14, "YYYY-M-D" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 22, "YYYY-M-D h:mm" ),
+ EXC_NUMFMT_STRING( 27, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
+ EXC_NUMFMT_STRING( 28, "[$-0804]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0804]M-D-YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 35, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_REUSE( 52, 27 ),
+ EXC_NUMFMT_REUSE( 53, 28 ),
+ EXC_NUMFMT_STRING( 63, UTF8_YEN_CS "#,##0;-" UTF8_YEN_CS "#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_YEN_CS "#,##0;[RED]-" UTF8_YEN_CS "#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_YEN_CS "#,##0.00;-" UTF8_YEN_CS "#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_YEN_CS "#,##0.00;[RED]-" UTF8_YEN_CS "#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_CHINESE_TRADITIONAL[] =
+{
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "hh:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "hh:mm:ss AM/PM" ),
+ EXC_NUMFMT_OFFSET( 20, NF_TIME_HHMM ),
+ EXC_NUMFMT_OFFSET( 21, NF_TIME_HHMMSS ),
+ EXC_NUMFMT_STRING( 22, "YYYY/M/D hh:mm" ),
+ EXC_NUMFMT_STRING( 23, "US$#,##0_);(US$#,##0)" ),
+ EXC_NUMFMT_STRING( 24, "US$#,##0_);[RED](US$#,##0)" ),
+ EXC_NUMFMT_STRING( 25, "US$#,##0.00_);(US$#,##0.00)" ),
+ EXC_NUMFMT_STRING( 26, "US$#,##0.00_);[RED](US$#,##0.00)" ),
+ EXC_NUMFMT_STRING( 27, "[$-0404]E/M/D" ),
+ EXC_NUMFMT_STRING( 28, "[$-0404]E" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 30, "[$-0404]M/D/YY" ),
+ EXC_NUMFMT_STRING( 31, "[$-0404]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
+ EXC_NUMFMT_STRING( 32, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 33, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 34, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
+ EXC_NUMFMT_STRING( 35, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
+ EXC_NUMFMT_STRING( 63, "$#,##0;-$#,##0" ),
+ EXC_NUMFMT_STRING( 64, "$#,##0;[RED]-$#,##0" ),
+ EXC_NUMFMT_STRING( 65, "$#,##0.00;-$#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, "$#,##0.00;[RED]-$#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// OTHER ----------------------------------------------------------------------
+
+static const XclBuiltInFormat spBuiltInFormats_HEBREW[] =
+{
+ EXC_NUMFMT_STRING( 15, "DD-MMMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "DD-MMMM" ),
+ EXC_NUMFMT_STRING( 17, "MMMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 63, UTF8_SHEQEL " #,##0;" UTF8_SHEQEL " -#,##0" ),
+ EXC_NUMFMT_STRING( 64, UTF8_SHEQEL " #,##0;[RED]" UTF8_SHEQEL " -#,##0" ),
+ EXC_NUMFMT_STRING( 65, UTF8_SHEQEL " #,##0.00;" UTF8_SHEQEL " -#,##0.00" ),
+ EXC_NUMFMT_STRING( 66, UTF8_SHEQEL " #,##0.00;[RED]" UTF8_SHEQEL " -#,##0.00" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+static const XclBuiltInFormat spBuiltInFormats_THAI[] =
+{
+ EXC_NUMFMT_STRING( 14, "D/M/YYYY" ),
+ EXC_NUMFMT_STRING( 15, "D-MMM-YY" ),
+ EXC_NUMFMT_STRING( 16, "D-MMM" ),
+ EXC_NUMFMT_STRING( 17, "MMM-YY" ),
+ EXC_NUMFMT_STRING( 18, "h:mm AM/PM" ),
+ EXC_NUMFMT_STRING( 19, "h:mm:ss AM/PM" ),
+ EXC_NUMFMT_STRING( 22, "D/M/YYYY h:mm" ),
+ EXC_NUMFMT_STRING( 59, "t0" ),
+ EXC_NUMFMT_STRING( 60, "t0.00" ),
+ EXC_NUMFMT_STRING( 61, "t#,##0" ),
+ EXC_NUMFMT_STRING( 62, "t#,##0.00" ),
+ EXC_NUMFMT_STRING( 63, "t" UTF8_BAHT "#,##0_);t(" UTF8_BAHT "#,##0)" ),
+ EXC_NUMFMT_STRING( 64, "t" UTF8_BAHT "#,##0_);[RED]t(" UTF8_BAHT "#,##0)" ),
+ EXC_NUMFMT_STRING( 65, "t" UTF8_BAHT "#,##0.00_);t(" UTF8_BAHT "#,##0.00)" ),
+ EXC_NUMFMT_STRING( 66, "t" UTF8_BAHT "#,##0.00_);[RED]t(" UTF8_BAHT "#,##0.00)" ),
+ EXC_NUMFMT_STRING( 67, "t0%" ),
+ EXC_NUMFMT_STRING( 68, "t0.00%" ),
+ EXC_NUMFMT_STRING( 69, "t# ?/?" ),
+ EXC_NUMFMT_STRING( 70, "t# ?\?/?\?" ),
+ EXC_NUMFMT_STRING( 71, "tD/M/EE" ),
+ EXC_NUMFMT_STRING( 72, "tD-MMM-E" ),
+ EXC_NUMFMT_STRING( 73, "tD-MMM" ),
+ EXC_NUMFMT_STRING( 74, "tMMM-E" ),
+ EXC_NUMFMT_STRING( 75, "th:mm" ),
+ EXC_NUMFMT_STRING( 76, "th:mm:ss" ),
+ EXC_NUMFMT_STRING( 77, "tD/M/EE h:mm" ),
+ EXC_NUMFMT_STRING( 78, "tmm:ss" ),
+ EXC_NUMFMT_STRING( 79, "t[h]:mm:ss" ),
+ EXC_NUMFMT_STRING( 80, "tmm:ss.0" ),
+ EXC_NUMFMT_STRING( 81, "D/M/E" ),
+ EXC_NUMFMT_ENDTABLE()
+};
+
+// ----------------------------------------------------------------------------
+
+#undef EXC_NUMFMT_ENDTABLE
+#undef EXC_NUMFMT_REUSE
+#undef EXC_NUMFMT_OFFSET
+#undef EXC_NUMFMT_STRING
+
+// ----------------------------------------------------------------------------
+
+/** Specifies a number format table for a specific langauge. */
+struct XclBuiltInFormatTable
+{
+ LanguageType meLanguage; /// The language of this table.
+ LanguageType meParentLang; /// The language of the parent table.
+ const XclBuiltInFormat* mpFormats; /// The number format table.
+};
+
+static const XclBuiltInFormatTable spBuiltInFormatTables[] =
+{ // language parent language format table
+ { LANGUAGE_DONTKNOW, LANGUAGE_NONE, spBuiltInFormats_DONTKNOW },
+
+ { LANGUAGE_ENGLISH, LANGUAGE_DONTKNOW, spBuiltInFormats_ENGLISH },
+ { LANGUAGE_ENGLISH_UK, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_UK },
+ { LANGUAGE_ENGLISH_EIRE, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_EIRE },
+ { LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_US },
+ { LANGUAGE_ENGLISH_CAN, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_CAN },
+ { LANGUAGE_ENGLISH_AUS, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_AUS },
+ { LANGUAGE_ENGLISH_SAFRICA, LANGUAGE_ENGLISH, spBuiltInFormats_ENGLISH_SAFRICA },
+ { LANGUAGE_ENGLISH_NZ, LANGUAGE_ENGLISH_AUS, 0 },
+
+ { PRV_LANGUAGE_FRENCH_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_FRENCH },
+ { LANGUAGE_FRENCH, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_FRANCE },
+ { LANGUAGE_FRENCH_CANADIAN, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_CANADIAN },
+ { LANGUAGE_FRENCH_SWISS, PRV_LANGUAGE_FRENCH_PRIM, spBuiltInFormats_FRENCH_SWISS },
+ { LANGUAGE_FRENCH_BELGIAN, LANGUAGE_FRENCH, spBuiltInFormats_FRENCH_BELGIAN },
+ { LANGUAGE_FRENCH_LUXEMBOURG, LANGUAGE_FRENCH, 0 },
+ { LANGUAGE_FRENCH_MONACO, LANGUAGE_FRENCH, 0 },
+
+ { PRV_LANGUAGE_GERMAN_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_GERMAN },
+ { LANGUAGE_GERMAN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_GERMANY },
+ { LANGUAGE_GERMAN_AUSTRIAN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_AUSTRIAN },
+ { LANGUAGE_GERMAN_SWISS, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_SWISS },
+ { LANGUAGE_GERMAN_LUXEMBOURG, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_LUXEMBOURG },
+ { LANGUAGE_GERMAN_LIECHTENSTEIN, PRV_LANGUAGE_GERMAN_PRIM, spBuiltInFormats_GERMAN_LIECHTENSTEIN },
+
+ { LANGUAGE_ITALIAN, LANGUAGE_DONTKNOW, spBuiltInFormats_ITALIAN_ITALY },
+ { LANGUAGE_ITALIAN_SWISS, LANGUAGE_DONTKNOW, spBuiltInFormats_ITALIAN_SWISS },
+
+ { LANGUAGE_SWEDISH, LANGUAGE_DONTKNOW, spBuiltInFormats_SWEDISH_SWEDEN },
+ { LANGUAGE_SWEDISH_FINLAND, LANGUAGE_DONTKNOW, spBuiltInFormats_SWEDISH_FINLAND },
+
+ { PRV_LANGUAGE_ASIAN_PRIM, LANGUAGE_DONTKNOW, spBuiltInFormats_ASIAN },
+ { LANGUAGE_JAPANESE, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_JAPANESE },
+ { LANGUAGE_KOREAN, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_KOREAN },
+ { LANGUAGE_CHINESE_SIMPLIFIED, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_CHINESE_SIMPLIFIED },
+ { LANGUAGE_CHINESE_TRADITIONAL, PRV_LANGUAGE_ASIAN_PRIM, spBuiltInFormats_CHINESE_TRADITIONAL },
+
+ { LANGUAGE_HEBREW, LANGUAGE_DONTKNOW, spBuiltInFormats_HEBREW },
+ { LANGUAGE_THAI, LANGUAGE_DONTKNOW, spBuiltInFormats_THAI }
+};
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// ============================================================================
+
+XclNumFmtBuffer::XclNumFmtBuffer( const XclRoot& rRoot ) :
+ meSysLang( rRoot.GetSysLanguage() ),
+ mnStdScNumFmt( rRoot.GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
+{
+ // *** insert default formats (BIFF5+ only)***
+
+ if( rRoot.GetBiff() >= EXC_BIFF5 )
+ InsertBuiltinFormats();
+}
+
+void XclNumFmtBuffer::InitializeImport()
+{
+ maFmtMap.clear();
+}
+
+void XclNumFmtBuffer::InsertFormat( sal_uInt16 nXclNumFmt, const String& rFormat )
+{
+ XclNumFmt& rNumFmt = maFmtMap[ nXclNumFmt ];
+ rNumFmt.maFormat = rFormat;
+ // #i62053# rFormat may be an empty string, meOffset must be initialized
+ rNumFmt.meOffset = NF_NUMBER_STANDARD;
+ rNumFmt.meLanguage = LANGUAGE_SYSTEM;
+}
+
+void XclNumFmtBuffer::InsertBuiltinFormats()
+{
+ // build a map containing tables for all languages
+ typedef ::std::map< LanguageType, const XclBuiltInFormatTable* > XclBuiltInMap;
+ XclBuiltInMap aBuiltInMap;
+ for( const XclBuiltInFormatTable* pTable = spBuiltInFormatTables;
+ pTable != STATIC_TABLE_END( spBuiltInFormatTables ); ++pTable )
+ aBuiltInMap[ pTable->meLanguage ] = pTable;
+
+ // build a list of table pointers for the current language, with all parent tables
+ typedef ::std::vector< const XclBuiltInFormatTable* > XclBuiltInVec;
+ XclBuiltInVec aBuiltInVec;
+ for( XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( meSysLang ), aMEnd = aBuiltInMap.end();
+ aMIt != aMEnd; aMIt = aBuiltInMap.find( aMIt->second->meParentLang ) )
+ aBuiltInVec.push_back( aMIt->second );
+ // language not supported
+ if( aBuiltInVec.empty() )
+ {
+ OSL_TRACE( "XclNumFmtBuffer::InsertBuiltinFormats - language 0x%04hX not supported (#i29949#)", meSysLang );
+ XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( LANGUAGE_DONTKNOW );
+ DBG_ASSERT( aMIt != aBuiltInMap.end(), "XclNumFmtBuffer::InsertBuiltinFormats - default map not found" );
+ if( aMIt != aBuiltInMap.end() )
+ aBuiltInVec.push_back( aMIt->second );
+ }
+
+ // insert the default formats in the format map, from root parent to system language
+ typedef ::std::map< sal_uInt16, sal_uInt16 > XclReuseMap;
+ XclReuseMap aReuseMap;
+ for( XclBuiltInVec::reverse_iterator aVIt = aBuiltInVec.rbegin(), aVEnd = aBuiltInVec.rend(); aVIt != aVEnd; ++aVIt )
+ {
+ // put LANGUAGE_SYSTEM for all entries in default table
+ LanguageType eLang = ((*aVIt)->meLanguage == LANGUAGE_DONTKNOW) ? LANGUAGE_SYSTEM : meSysLang;
+ for( const XclBuiltInFormat* pBuiltIn = (*aVIt)->mpFormats; pBuiltIn && (pBuiltIn->mnXclNumFmt != EXC_FORMAT_NOTFOUND); ++pBuiltIn )
+ {
+ XclNumFmt& rNumFmt = maFmtMap[ pBuiltIn->mnXclNumFmt ];
+
+ rNumFmt.meOffset = pBuiltIn->meOffset;
+ rNumFmt.meLanguage = eLang;
+
+ if( pBuiltIn->mpFormat )
+ rNumFmt.maFormat = String( pBuiltIn->mpFormat, RTL_TEXTENCODING_UTF8 );
+ else
+ rNumFmt.maFormat = EMPTY_STRING;
+
+ if( pBuiltIn->meOffset == PRV_NF_INDEX_REUSE )
+ aReuseMap[ pBuiltIn->mnXclNumFmt ] = pBuiltIn->mnXclReuseFmt;
+ else
+ aReuseMap.erase( pBuiltIn->mnXclNumFmt );
+ }
+ }
+
+ // copy reused number formats
+ for( XclReuseMap::const_iterator aRIt = aReuseMap.begin(), aREnd = aReuseMap.end(); aRIt != aREnd; ++aRIt )
+ maFmtMap[ aRIt->first ] = maFmtMap[ aRIt->second ];
+}
+
+// Cell formatting data (XF) ==================================================
+
+XclCellProt::XclCellProt() :
+ mbLocked( true ), // default in Excel and Calc
+ mbHidden( false )
+{
+}
+
+bool operator==( const XclCellProt& rLeft, const XclCellProt& rRight )
+{
+ return (rLeft.mbLocked == rRight.mbLocked) && (rLeft.mbHidden == rRight.mbHidden);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellAlign::XclCellAlign() :
+ mnHorAlign( EXC_XF_HOR_GENERAL ),
+ mnVerAlign( EXC_XF_VER_BOTTOM ),
+ mnOrient( EXC_ORIENT_NONE ),
+ mnTextDir( EXC_XF_TEXTDIR_CONTEXT ),
+ mnRotation( EXC_ROT_NONE ),
+ mnIndent( 0 ),
+ mbLineBreak( false ),
+ mbShrink( false )
+{
+}
+
+SvxCellHorJustify XclCellAlign::GetScHorAlign() const
+{
+ SvxCellHorJustify eHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ switch( mnHorAlign )
+ {
+ case EXC_XF_HOR_GENERAL: eHorJust = SVX_HOR_JUSTIFY_STANDARD; break;
+ case EXC_XF_HOR_LEFT: eHorJust = SVX_HOR_JUSTIFY_LEFT; break;
+ case EXC_XF_HOR_CENTER_AS:
+ case EXC_XF_HOR_CENTER: eHorJust = SVX_HOR_JUSTIFY_CENTER; break;
+ case EXC_XF_HOR_RIGHT: eHorJust = SVX_HOR_JUSTIFY_RIGHT; break;
+ case EXC_XF_HOR_FILL: eHorJust = SVX_HOR_JUSTIFY_REPEAT; break;
+ case EXC_XF_HOR_JUSTIFY:
+ case EXC_XF_HOR_DISTRIB: eHorJust = SVX_HOR_JUSTIFY_BLOCK; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScHorAlign - unknown horizontal alignment" );
+ }
+ return eHorJust;
+}
+
+SvxCellJustifyMethod XclCellAlign::GetScHorJustifyMethod() const
+{
+ return (mnHorAlign == EXC_XF_HOR_DISTRIB) ? SVX_JUSTIFY_METHOD_DISTRIBUTE : SVX_JUSTIFY_METHOD_AUTO;
+}
+
+SvxCellVerJustify XclCellAlign::GetScVerAlign() const
+{
+ SvxCellVerJustify eVerJust = SVX_VER_JUSTIFY_STANDARD;
+ switch( mnVerAlign )
+ {
+ case EXC_XF_VER_TOP: eVerJust = SVX_VER_JUSTIFY_TOP; break;
+ case EXC_XF_VER_CENTER: eVerJust = SVX_VER_JUSTIFY_CENTER; break;
+ case EXC_XF_VER_BOTTOM: eVerJust = SVX_VER_JUSTIFY_STANDARD; break;
+ case EXC_XF_VER_JUSTIFY:
+ case EXC_XF_VER_DISTRIB: eVerJust = SVX_VER_JUSTIFY_BLOCK; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScVerAlign - unknown vertical alignment" );
+ }
+ return eVerJust;
+}
+
+SvxCellJustifyMethod XclCellAlign::GetScVerJustifyMethod() const
+{
+ return (mnVerAlign == EXC_XF_VER_DISTRIB) ? SVX_JUSTIFY_METHOD_DISTRIBUTE : SVX_JUSTIFY_METHOD_AUTO;
+}
+
+SvxFrameDirection XclCellAlign::GetScFrameDir() const
+{
+ SvxFrameDirection eFrameDir = FRMDIR_ENVIRONMENT;
+ switch( mnTextDir )
+ {
+ case EXC_XF_TEXTDIR_CONTEXT: eFrameDir = FRMDIR_ENVIRONMENT; break;
+ case EXC_XF_TEXTDIR_LTR: eFrameDir = FRMDIR_HORI_LEFT_TOP; break;
+ case EXC_XF_TEXTDIR_RTL: eFrameDir = FRMDIR_HORI_RIGHT_TOP; break;
+ default: DBG_ERRORFILE( "XclCellAlign::GetScFrameDir - unknown CTL text direction" );
+ }
+ return eFrameDir;
+}
+
+void XclCellAlign::SetScHorAlign( SvxCellHorJustify eHorJust )
+{
+ switch( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD: mnHorAlign = EXC_XF_HOR_GENERAL; break;
+ case SVX_HOR_JUSTIFY_LEFT: mnHorAlign = EXC_XF_HOR_LEFT; break;
+ case SVX_HOR_JUSTIFY_CENTER: mnHorAlign = EXC_XF_HOR_CENTER; break;
+ case SVX_HOR_JUSTIFY_RIGHT: mnHorAlign = EXC_XF_HOR_RIGHT; break;
+ case SVX_HOR_JUSTIFY_BLOCK: mnHorAlign = EXC_XF_HOR_JUSTIFY; break;
+ case SVX_HOR_JUSTIFY_REPEAT: mnHorAlign = EXC_XF_HOR_FILL; break;
+ default: mnHorAlign = EXC_XF_HOR_GENERAL;
+ OSL_FAIL( "XclCellAlign::SetScHorAlign - unknown horizontal alignment" );
+ }
+}
+
+void XclCellAlign::SetScVerAlign( SvxCellVerJustify eVerJust )
+{
+ switch( eVerJust )
+ {
+ case SVX_VER_JUSTIFY_STANDARD: mnVerAlign = EXC_XF_VER_BOTTOM; break;
+ case SVX_VER_JUSTIFY_TOP: mnVerAlign = EXC_XF_VER_TOP; break;
+ case SVX_VER_JUSTIFY_CENTER: mnVerAlign = EXC_XF_VER_CENTER; break;
+ case SVX_VER_JUSTIFY_BOTTOM: mnVerAlign = EXC_XF_VER_BOTTOM; break;
+ default: mnVerAlign = EXC_XF_VER_BOTTOM;
+ OSL_FAIL( "XclCellAlign::SetScVerAlign - unknown vertical alignment" );
+ }
+}
+
+void XclCellAlign::SetScFrameDir( SvxFrameDirection eFrameDir )
+{
+ switch( eFrameDir )
+ {
+ case FRMDIR_ENVIRONMENT: mnTextDir = EXC_XF_TEXTDIR_CONTEXT; break;
+ case FRMDIR_HORI_LEFT_TOP: mnTextDir = EXC_XF_TEXTDIR_LTR; break;
+ case FRMDIR_HORI_RIGHT_TOP: mnTextDir = EXC_XF_TEXTDIR_RTL; break;
+ default: mnTextDir = EXC_XF_TEXTDIR_CONTEXT;
+ DBG_ERRORFILE( "XclCellAlign::SetScFrameDir - unknown CTL text direction" );
+ }
+}
+
+bool operator==( const XclCellAlign& rLeft, const XclCellAlign& rRight )
+{
+ return
+ (rLeft.mnHorAlign == rRight.mnHorAlign) && (rLeft.mnVerAlign == rRight.mnVerAlign) &&
+ (rLeft.mnTextDir == rRight.mnTextDir) && (rLeft.mnOrient == rRight.mnOrient) &&
+ (rLeft.mnRotation == rRight.mnRotation) && (rLeft.mnIndent == rRight.mnIndent) &&
+ (rLeft.mbLineBreak == rRight.mbLineBreak) && (rLeft.mbShrink == rRight.mbShrink);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellBorder::XclCellBorder() :
+ mnLeftColor( 0 ),
+ mnRightColor( 0 ),
+ mnTopColor( 0 ),
+ mnBottomColor( 0 ),
+ mnDiagColor( 0 ),
+ mnLeftLine( EXC_LINE_NONE ),
+ mnRightLine( EXC_LINE_NONE ),
+ mnTopLine( EXC_LINE_NONE ),
+ mnBottomLine( EXC_LINE_NONE ),
+ mnDiagLine( EXC_LINE_NONE ),
+ mbDiagTLtoBR( false ),
+ mbDiagBLtoTR( false )
+{
+}
+
+bool operator==( const XclCellBorder& rLeft, const XclCellBorder& rRight )
+{
+ return
+ (rLeft.mnLeftColor == rRight.mnLeftColor) && (rLeft.mnRightColor == rRight.mnRightColor) &&
+ (rLeft.mnTopColor == rRight.mnTopColor) && (rLeft.mnBottomColor == rRight.mnBottomColor) &&
+ (rLeft.mnLeftLine == rRight.mnLeftLine) && (rLeft.mnRightLine == rRight.mnRightLine) &&
+ (rLeft.mnTopLine == rRight.mnTopLine) && (rLeft.mnBottomLine == rRight.mnBottomLine) &&
+ (rLeft.mnDiagColor == rRight.mnDiagColor) && (rLeft.mnDiagLine == rRight.mnDiagLine) &&
+ (rLeft.mbDiagTLtoBR == rRight.mbDiagTLtoBR) && (rLeft.mbDiagBLtoTR == rRight.mbDiagBLtoTR);
+}
+
+// ----------------------------------------------------------------------------
+
+XclCellArea::XclCellArea() :
+ mnForeColor( EXC_COLOR_WINDOWTEXT ),
+ mnBackColor( EXC_COLOR_WINDOWBACK ),
+ mnPattern( EXC_PATT_NONE )
+{
+}
+
+bool XclCellArea::IsTransparent() const
+{
+ return (mnPattern == EXC_PATT_NONE) && (mnBackColor == EXC_COLOR_WINDOWBACK);
+}
+
+bool operator==( const XclCellArea& rLeft, const XclCellArea& rRight )
+{
+ return
+ (rLeft.mnForeColor == rRight.mnForeColor) && (rLeft.mnBackColor == rRight.mnBackColor) &&
+ (rLeft.mnPattern == rRight.mnPattern);
+}
+
+// ----------------------------------------------------------------------------
+
+XclXFBase::XclXFBase( bool bCellXF ) :
+ mnParent( bCellXF ? EXC_XF_DEFAULTSTYLE : EXC_XF_STYLEPARENT ),
+ mbCellXF( bCellXF )
+{
+ SetAllUsedFlags( false );
+}
+
+XclXFBase::~XclXFBase()
+{
+}
+
+void XclXFBase::SetAllUsedFlags( bool bUsed )
+{
+ mbProtUsed = mbFontUsed = mbFmtUsed = mbAlignUsed = mbBorderUsed = mbAreaUsed = bUsed;
+}
+
+bool XclXFBase::HasUsedFlags() const
+{
+ return mbProtUsed || mbFontUsed || mbFmtUsed || mbAlignUsed || mbBorderUsed || mbAreaUsed;
+}
+
+bool XclXFBase::Equals( const XclXFBase& rCmp ) const
+{
+ return
+ (mbCellXF == rCmp.mbCellXF) && (mnParent == rCmp.mnParent) &&
+ (mbProtUsed == rCmp.mbProtUsed) && (mbFontUsed == rCmp.mbFontUsed) &&
+ (mbFmtUsed == rCmp.mbFmtUsed) && (mbAlignUsed == rCmp.mbAlignUsed) &&
+ (mbBorderUsed == rCmp.mbBorderUsed) && (mbAreaUsed == rCmp.mbAreaUsed);
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xltoolbar.cxx b/sc/source/filter/excel/xltoolbar.cxx
new file mode 100644
index 000000000000..749cb4808fb1
--- /dev/null
+++ b/sc/source/filter/excel/xltoolbar.cxx
@@ -0,0 +1,447 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Noel Power <noel.power@novell.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Noel Power <noel.power@novell.com>
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include "xltoolbar.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <stdarg.h>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <fstream>
+#include <comphelper/processfactory.hxx>
+#include <vcl/graph.hxx>
+#include <map>
+using namespace com::sun::star;
+
+typedef std::map< sal_Int16, rtl::OUString > IdToString;
+
+class MSOExcelCommandConvertor : public MSOCommandConvertor
+{
+ IdToString msoToOOcmd;
+ IdToString tcidToOOcmd;
+public:
+ MSOExcelCommandConvertor();
+ virtual rtl::OUString MSOCommandToOOCommand( sal_Int16 msoCmd );
+ virtual rtl::OUString MSOTCIDToOOCommand( sal_Int16 key );
+};
+
+MSOExcelCommandConvertor::MSOExcelCommandConvertor()
+{
+/*
+ // mso command id to ooo command string
+ // #FIXME and *HUNDREDS* of id's to added here
+ msoToOOcmd[ 0x20b ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc") );
+ msoToOOcmd[ 0x50 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".uno:Open") );
+
+ // mso tcid to ooo command string
+ // #FIXME and *HUNDREDS* of id's to added here
+ tcidToOOcmd[ 0x9d9 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".uno:Print") );
+*/
+}
+
+rtl::OUString MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
+{
+ rtl::OUString sResult;
+ IdToString::iterator it = msoToOOcmd.find( key );
+ if ( it != msoToOOcmd.end() )
+ sResult = it->second;
+ return sResult;
+}
+
+rtl::OUString MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
+{
+ rtl::OUString sResult;
+ IdToString::iterator it = tcidToOOcmd.find( key );
+ if ( it != tcidToOOcmd.end() )
+ sResult = it->second;
+ return sResult;
+}
+
+
+
+CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
+{
+}
+
+CTB::CTB() : nViews( 0 ), ectbid(0)
+{
+}
+
+CTB::CTB(sal_uInt16 nNum ) : nViews( nNum ), ectbid(0)
+{
+}
+
+bool CTB::Read( SvStream *pS )
+{
+ OSL_TRACE("CTB::Read() stream pos 0x%x", pS->Tell() );
+ nOffSet = pS->Tell();
+ tb.Read( pS );
+ for ( sal_uInt16 index = 0; index < nViews; ++index )
+ {
+ TBVisualData aVisData;
+ aVisData.Read( pS );
+ rVisualData.push_back( aVisData );
+ }
+ *pS >> ectbid;
+
+ for ( sal_Int16 index = 0; index < tb.getcCL(); ++index )
+ {
+ TBC aTBC;
+ aTBC.Read( pS );
+ rTBC.push_back( aTBC );
+ }
+ return true;
+}
+
+void CTB::Print( FILE* fp )
+{
+ Indent a;
+ indent_printf( fp, "[ 0x%x ] CTB -- dump\n", nOffSet );
+ indent_printf( fp, " nViews 0x%x\n", nViews);
+ tb.Print( fp );
+
+ std::vector<TBVisualData>::iterator visData_end = rVisualData.end();
+ sal_Int32 counter = 0;
+ for ( std::vector<TBVisualData>::iterator it = rVisualData.begin(); it != visData_end; ++it )
+ {
+
+ indent_printf( fp, " TBVisualData [%d]\n", counter++ );
+ Indent b;
+ it->Print( fp );
+ }
+ indent_printf( fp, " ectbid 0x%x\n", ectbid);
+ std::vector<TBC>::iterator it_end = rTBC.end();
+ counter = 0;
+ for ( std::vector<TBC>::iterator it = rTBC.begin(); it != it_end; ++it )
+ {
+ indent_printf( fp, " TBC [%d]\n", counter++);
+ Indent c;
+ it->Print( fp );
+ }
+}
+
+bool CTB::IsMenuToolbar()
+{
+ return tb.IsMenuToolbar();
+}
+
+bool CTB::ImportMenuTB( CTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xMenuDesc, CustomToolBarImportHelper& helper )
+{
+ sal_Int32 index = 0;
+ for ( std::vector< TBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it, ++index )
+ {
+ if ( !it->ImportToolBarControl( rWrapper, xMenuDesc, helper, IsMenuToolbar() ) )
+ return false;
+ }
+ return true;
+}
+
+bool CTB::ImportCustomToolBar( CTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
+{
+
+ static rtl::OUString sToolbarPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/custom_" ) );
+ bool bRes = false;
+ try
+ {
+ if ( !tb.IsEnabled() )
+ return true; // didn't fail, just ignoring
+
+ // Create default setting
+ uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
+ WString& name = tb.getName();
+ // set UI name for toolbar
+ xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UIName") ), uno::makeAny( name.getString() ) );
+
+ rtl::OUString sToolBarName = sToolbarPrefix.concat( name.getString() );
+ for ( std::vector< TBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it )
+ {
+ if ( !it->ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
+ return false;
+ }
+
+ OSL_TRACE("Name of toolbar :-/ %s", rtl::OUStringToOString( sToolBarName, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
+ helper.applyIcons();
+
+ uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
+ xPersistence->store();
+
+ xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
+ xPersistence->store();
+
+ bRes = true;
+ }
+ catch( uno::Exception& )
+ {
+ bRes = false;
+ }
+ return bRes;
+}
+bool CTBS::Read( SvStream *pS )
+{
+ OSL_TRACE("CTBS::Read() stream pos 0x%x", pS->Tell() );
+ nOffSet = pS->Tell();
+ *pS >> bSignature >> bVersion >> reserved1 >> reserved2 >> reserved3 >> ctb >> ctbViews >> ictbView;
+ return true;
+}
+
+void CTBS::Print( FILE* fp )
+{
+ Indent a;
+ indent_printf( fp, "[ 0x%x ] CTBS -- dump\n", nOffSet );
+
+ indent_printf( fp, " bSignature 0x%x\n", bSignature);
+ indent_printf( fp, " bVersion 0x%x\n", bVersion);
+
+ indent_printf( fp, " reserved1 0x%x\n", reserved1 );
+ indent_printf( fp, " reserved2 0x%x\n", reserved2 );
+ indent_printf( fp, " reserved3 0x%x\n", reserved3 );
+
+ indent_printf( fp, " ctb 0x%x\n", ctb );
+ indent_printf( fp, " ctbViews 0x%x\n", ctbViews );
+ indent_printf( fp, " ictbView 0x%x\n", ictbView );
+}
+
+TBC::TBC()
+{
+}
+
+bool
+TBC::Read(SvStream *pS)
+{
+ OSL_TRACE("TBC::Read() stream pos 0x%x", pS->Tell() );
+ nOffSet = pS->Tell();
+ if ( !tbch.Read( pS ) )
+ return false;
+ sal_uInt16 tcid = tbch.getTcID();
+ sal_uInt8 tct = tbch.getTct();
+ if ( ( tcid != 0x0001 && tcid != 0x06CC && tcid != 0x03D8 && tcid != 0x03EC && tcid != 0x1051 ) && ( ( tct > 0 && tct < 0x0B ) || ( ( tct > 0x0B && tct < 0x10 ) || tct == 0x15 ) ) )
+ {
+ tbcCmd.reset( new TBCCmd );
+ if ( ! tbcCmd->Read( pS ) )
+ return false;
+ }
+ if ( tct != 0x16 )
+ {
+ tbcd.reset( new TBCData( tbch ) );
+ if ( !tbcd->Read( pS ) )
+ return false;
+ }
+ return true;
+}
+
+
+void
+TBC::Print(FILE* fp)
+{
+ Indent a;
+ indent_printf( fp, "[ 0x%x ] TBC -- dump\n", nOffSet );
+ tbch.Print( fp );
+ if ( tbcCmd.get() )
+ tbcCmd->Print( fp );
+ if ( tbcd.get() )
+ tbcd->Print( fp );
+}
+
+bool TBC::ImportToolBarControl( CTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuToolbar )
+{
+ // how to identify built-in-command ?
+// bool bBuiltin = false;
+ if ( tbcd.get() )
+ {
+ std::vector< css::beans::PropertyValue > props;
+ bool bBeginGroup = false;
+ if ( ! tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuToolbar ) )
+ return false;
+ TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
+ if ( pMenu )
+ {
+ // search for CTB with the appropriate name ( it contains the
+ // menu items, although we cannot import ( or create ) a menu on
+ // a custom toolbar we can import the menu items in a separate
+ // toolbar ( better than nothing )
+ CTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
+ if ( pCustTB )
+ {
+ uno::Reference< container::XIndexContainer > xMenuDesc;
+ uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ xMenuDesc.set( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.IndexedPropertyValues" ) ) ), uno::UNO_QUERY_THROW );
+ if ( !pCustTB->ImportMenuTB( rWrapper, xMenuDesc, helper ) )
+ return false;
+ if ( !bIsMenuToolbar )
+ {
+ if ( !helper.createMenu( pMenu->Name(), uno::Reference< container::XIndexAccess >( xMenuDesc, uno::UNO_QUERY ), true ) )
+ return false;
+ }
+ else
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ItemDescriptorContainer") );
+ aProp.Value <<= xMenuDesc;
+ props.push_back( aProp );
+ }
+ }
+ }
+
+ if ( bBeginGroup )
+ {
+ // insert spacer
+ uno::Sequence< beans::PropertyValue > sProps( 1 );
+ sProps[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Type") );
+ sProps[ 0 ].Value = uno::makeAny( ui::ItemType::SEPARATOR_LINE );
+ toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
+ }
+ uno::Sequence< beans::PropertyValue > sProps( props.size() );
+ beans::PropertyValue* pProp = sProps.getArray();
+
+ for ( std::vector< css::beans::PropertyValue >::iterator it = props.begin(); it != props.end(); ++it, ++pProp )
+ *pProp = *it;
+
+ toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
+ }
+ return true;
+}
+
+void
+TBCCmd::Print(FILE* fp)
+{
+ Indent a;
+ indent_printf( fp, " TBCCmd -- dump\n" );
+ indent_printf( fp, " cmdID 0x%x\n", cmdID );
+ indent_printf( fp, " A ( fHideDrawing ) %s\n", A ? "true" : "false" );
+ indent_printf( fp, " B ( reserved - ignored ) %s\n", A ? "true" : "false" );
+ indent_printf( fp, " cmdType 0x%x\n", cmdType );
+ indent_printf( fp, " C ( reserved - ignored ) %s\n", A ? "true" : "false" );
+ indent_printf( fp, " reserved3 0x%x\n", reserved3 );
+}
+
+bool TBCCmd::Read( SvStream *pS )
+{
+ OSL_TRACE("TBCCmd::Read() stream pos 0x%x", pS->Tell() );
+ nOffSet = pS->Tell();
+ *pS >> cmdID;
+ sal_uInt16 temp;
+ *pS >> temp;
+ OSL_TRACE("TBCmd temp = 0x%x", temp );
+ A = (temp & 0x8000 ) == 0x8000;
+ B = (temp & 0x4000) == 0x4000;
+ cmdType = ( temp & 0x3E00 ) >> 9;
+ C = ( temp & 0x100 ) == 0x100;
+ reserved3 = ( temp & 0xFF );
+ return true;
+}
+
+CTBWrapper::CTBWrapper()
+{
+}
+
+CTBWrapper::~CTBWrapper()
+{
+}
+
+bool
+CTBWrapper::Read( SvStream *pS)
+{
+ OSL_TRACE("CTBWrapper::Read() stream pos 0x%x", pS->Tell() );
+ nOffSet = pS->Tell();
+ if ( !ctbSet.Read( pS ) )
+ return false;
+ for ( sal_uInt16 index = 0; index < ctbSet.ctb; ++index )
+ {
+ CTB aCTB( ctbSet.ctbViews );
+ if ( !aCTB.Read( pS ) )
+ return false;
+ rCTB.push_back( aCTB );
+ }
+ return true;
+}
+
+void
+CTBWrapper::Print( FILE* fp )
+{
+ Indent a;
+ indent_printf( fp, "[ 0x%x ] CTBWrapper -- dump\n", nOffSet );
+ ctbSet.Print( fp );
+ std::vector<CTB>::iterator it_end = rCTB.end();
+ for ( std::vector<CTB>::iterator it = rCTB.begin(); it != it_end; ++it )
+ {
+ Indent b;
+ it->Print( fp );
+ }
+}
+
+CTB* CTBWrapper::GetCustomizationData( const rtl::OUString& sTBName )
+{
+ CTB* pCTB = NULL;
+ for ( std::vector< CTB >::iterator it = rCTB.begin(); it != rCTB.end(); ++it )
+ {
+ if ( it->GetName().equals( sTBName ) )
+ {
+ pCTB = &(*it);
+ break;
+ }
+ }
+ return pCTB;
+}
+
+bool CTBWrapper::ImportCustomToolBar( SfxObjectShell& rDocSh )
+{
+ std::vector<CTB>::iterator it_end = rCTB.end();
+ for ( std::vector<CTB>::iterator it = rCTB.begin(); it != it_end; ++it )
+ {
+ // for each customtoolbar
+ uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) ) ), uno::UNO_QUERY_THROW );
+ CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument" ) ) ) );
+ helper.setMSOCommandMap( new MSOExcelCommandConvertor() );
+ // Ignore menu toolbars, excel doesn't ( afaics ) store
+ // menu customizations ( but you can have menus in a customtoolbar
+ // such menus will be dealt with when they are encountered
+ // as part of importing the appropriate MenuSpecific toolbar control )
+
+
+ if ( !(*it).IsMenuToolbar() )
+ {
+ if ( !(*it).ImportCustomToolBar( *this, helper ) )
+ return false;
+ }
+ }
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xltoolbar.hxx b/sc/source/filter/excel/xltoolbar.hxx
new file mode 100644
index 000000000000..22e2bcd71f41
--- /dev/null
+++ b/sc/source/filter/excel/xltoolbar.hxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Noel Power <noel.power@novell.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Noel Power <noel.power@novell.com>
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#ifndef _XLTOOLBAR_HXX
+#define _XLTOOLBAR_HXX
+
+#include <filter/msfilter/mstoolbar.hxx>
+
+namespace css = ::com::sun::star;
+
+class CTBWrapper;
+// hmm I don't normally use these packed structures
+// but.. hey always good to do something different
+class TBCCmd : public TBBase
+{
+public:
+ TBCCmd() : cmdID(0), A(0), B(0), cmdType(0), C(0), reserved3(0) {}
+ sal_uInt16 cmdID;
+ sal_uInt16 A:1;
+ sal_uInt16 B:1;
+ sal_uInt16 cmdType:5;
+ sal_uInt16 C:1;
+ sal_uInt16 reserved3:8;
+ bool Read( SvStream* pS );
+ void Print(FILE* fp);
+};
+
+class TBC : public TBBase
+{
+ TBCHeader tbch;
+ boost::shared_ptr<TBCCmd> tbcCmd; // optional
+ boost::shared_ptr<TBCData> tbcd;
+public:
+ TBC();
+ ~TBC(){}
+ void Print( FILE* );
+ bool Read(SvStream *pS);
+ bool ImportToolBarControl( CTBWrapper&, const com::sun::star::uno::Reference< com::sun::star::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuBar );
+};
+
+class CTB : public TBBase
+{
+ sal_uInt16 nViews;
+ TB tb;
+ std::vector<TBVisualData> rVisualData;
+ sal_uInt32 ectbid;
+ std::vector< TBC > rTBC;
+ bool ImportCustomToolBar_Impl( CTBWrapper&, CustomToolBarImportHelper& );
+public:
+ CTB();
+ CTB(sal_uInt16);
+ ~CTB(){}
+ void Print( FILE* );
+ bool Read(SvStream *pS);
+ bool IsMenuToolbar();
+ bool ImportCustomToolBar( CTBWrapper&, CustomToolBarImportHelper& );
+ bool ImportMenuTB( CTBWrapper&, const css::uno::Reference< css::container::XIndexContainer >&, CustomToolBarImportHelper& );
+ rtl::OUString GetName() { return tb.getName().getString(); }
+
+
+};
+
+class CTBS : public TBBase
+{
+public:
+ sal_uInt8 bSignature;
+ sal_uInt8 bVersion;
+ sal_uInt16 reserved1;
+ sal_uInt16 reserved2;
+ sal_uInt16 reserved3;
+ sal_uInt16 ctb;
+ sal_uInt16 ctbViews;
+ sal_uInt16 ictbView;
+ CTBS(const CTBS&);
+ CTBS& operator = ( const CTBS&);
+ CTBS();
+ ~CTBS(){}
+ void Print( FILE* );
+ bool Read(SvStream *pS);
+};
+
+class CTBWrapper : public TBBase
+{
+ CTBS ctbSet;
+
+ std::vector< CTB > rCTB;
+
+public:
+ CTBWrapper();
+ ~CTBWrapper();
+ bool Read(SvStream *pS);
+ void Print( FILE* );
+ bool ImportCustomToolBar( SfxObjectShell& rDocSh );
+ CTB* GetCustomizationData( const rtl::OUString& name );
+};
+
+
+#endif //_XLTOOLBAR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx
new file mode 100644
index 000000000000..aba8b38fc340
--- /dev/null
+++ b/sc/source/filter/excel/xltools.cxx
@@ -0,0 +1,750 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <algorithm>
+#include <math.h>
+#include <sal/mathconf.h>
+#include <unotools/fontcvt.hxx>
+#include <sfx2/objsh.hxx>
+#include <sal/macros.h>
+#include <editeng/editstat.hxx>
+#include <filter/msfilter/msvbahelper.hxx>
+#include "xestream.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "editutil.hxx"
+#include "formula/errorcodes.hxx"
+#include "globstr.hrc"
+#include "xlstyle.hxx"
+#include "xlname.hxx"
+#include "xistream.hxx"
+#include "xiroot.hxx"
+#include "xltools.hxx"
+
+using ::rtl::OUString;
+
+// GUID import/export =========================================================
+
+XclGuid::XclGuid()
+{
+ ::std::fill( mpnData, STATIC_TABLE_END( mpnData ), 0 );
+}
+
+XclGuid::XclGuid(
+ sal_uInt32 nData1, sal_uInt16 nData2, sal_uInt16 nData3,
+ sal_uInt8 nData41, sal_uInt8 nData42, sal_uInt8 nData43, sal_uInt8 nData44,
+ sal_uInt8 nData45, sal_uInt8 nData46, sal_uInt8 nData47, sal_uInt8 nData48 )
+{
+ // convert to little endian -> makes streaming easy
+ UInt32ToSVBT32( nData1, mpnData );
+ ShortToSVBT16( nData2, mpnData + 4 );
+ ShortToSVBT16( nData3, mpnData + 6 );
+ mpnData[ 8 ] = nData41;
+ mpnData[ 9 ] = nData42;
+ mpnData[ 10 ] = nData43;
+ mpnData[ 11 ] = nData44;
+ mpnData[ 12 ] = nData45;
+ mpnData[ 13 ] = nData46;
+ mpnData[ 14 ] = nData47;
+ mpnData[ 15 ] = nData48;
+}
+
+bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 )
+{
+ return ::std::equal( rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), rCmp2.mpnData );
+}
+
+bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 )
+{
+ return ::std::lexicographical_compare(
+ rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ),
+ rCmp2.mpnData, STATIC_TABLE_END( rCmp2.mpnData ) );
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid )
+{
+ rStrm.Read( rGuid.mpnData, 16 ); // mpnData always in little endian
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid )
+{
+ rStrm.Write( rGuid.mpnData, 16 ); // mpnData already in little endian
+ return rStrm;
+}
+
+// Excel Tools ================================================================
+
+// GUID's ---------------------------------------------------------------------
+
+const XclGuid XclTools::maGuidStdLink(
+ 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const XclGuid XclTools::maGuidUrlMoniker(
+ 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const XclGuid XclTools::maGuidFileMoniker(
+ 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
+
+// numeric conversion ---------------------------------------------------------
+
+double XclTools::GetDoubleFromRK( sal_Int32 nRKValue )
+{
+ union
+ {
+ double fVal;
+ sal_math_Double smD;
+ };
+ fVal = 0.0;
+
+ if( ::get_flag( nRKValue, EXC_RK_INTFLAG ) )
+ {
+ sal_Int32 nTemp = nRKValue >> 2;
+ ::set_flag< sal_Int32 >( nTemp, 0xE0000000, nRKValue < 0 );
+ fVal = nTemp;
+ }
+ else
+ {
+ smD.w32_parts.msw = nRKValue & EXC_RK_VALUEMASK;
+ }
+
+ if( ::get_flag( nRKValue, EXC_RK_100FLAG ) )
+ fVal /= 100.0;
+
+ return fVal;
+}
+
+bool XclTools::GetRKFromDouble( sal_Int32& rnRKValue, double fValue )
+{
+ double fFrac, fInt;
+
+ // integer
+ fFrac = modf( fValue, &fInt );
+ if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) ) // 2^29
+ {
+ rnRKValue = static_cast< sal_Int32 >( fInt );
+ rnRKValue <<= 2;
+ rnRKValue |= EXC_RK_INT;
+ return true;
+ }
+
+ // integer/100
+ fFrac = modf( fValue * 100.0, &fInt );
+ if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) )
+ {
+ rnRKValue = static_cast< sal_Int32 >( fInt );
+ rnRKValue <<= 2;
+ rnRKValue |= EXC_RK_INT100;
+ return true;
+ }
+
+ // double
+ return false;
+}
+
+sal_Int32 XclTools::GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked )
+{
+ if( nXclRot == EXC_ROT_STACKED )
+ return nRotForStacked;
+ DBG_ASSERT( nXclRot <= 180, "XclTools::GetScRotation - illegal rotation angle" );
+ return static_cast< sal_Int32 >( (nXclRot <= 180) ? (100 * ((nXclRot > 90) ? (450 - nXclRot) : nXclRot)) : 0 );
+}
+
+sal_uInt8 XclTools::GetXclRotation( sal_Int32 nScRot )
+{
+ sal_Int32 nXclRot = nScRot / 100;
+ if( (0 <= nXclRot) && (nXclRot <= 90) )
+ return static_cast< sal_uInt8 >( nXclRot );
+ if( nXclRot < 180 )
+ return static_cast< sal_uInt8 >( 270 - nXclRot );
+ if( nXclRot < 270 )
+ return static_cast< sal_uInt8 >( nXclRot - 180 );
+ if( nXclRot < 360 )
+ return static_cast< sal_uInt8 >( 450 - nXclRot );
+ return 0;
+}
+
+sal_uInt8 XclTools::GetXclRotFromOrient( sal_uInt8 nXclOrient )
+{
+ switch( nXclOrient )
+ {
+ case EXC_ORIENT_NONE: return EXC_ROT_NONE;
+ case EXC_ORIENT_STACKED: return EXC_ROT_STACKED;
+ case EXC_ORIENT_90CCW: return EXC_ROT_90CCW;
+ case EXC_ORIENT_90CW: return EXC_ROT_90CW;
+ default: DBG_ERRORFILE( "XclTools::GetXclRotFromOrient - unknown text orientation" );
+ }
+ return EXC_ROT_NONE;
+}
+
+sal_uInt8 XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot )
+{
+ if( nXclRot == EXC_ROT_STACKED )
+ return EXC_ORIENT_STACKED;
+ DBG_ASSERT( nXclRot <= 180, "XclTools::GetXclOrientFromRot - unknown text rotation" );
+ if( (45 < nXclRot) && (nXclRot <= 90) )
+ return EXC_ORIENT_90CCW;
+ if( (135 < nXclRot) && (nXclRot <= 180) )
+ return EXC_ORIENT_90CW;
+ return EXC_ORIENT_NONE;
+}
+
+sal_uInt8 XclTools::GetXclErrorCode( sal_uInt16 nScError )
+{
+ using namespace ScErrorCodes;
+ switch( nScError )
+ {
+ case errIllegalArgument: return EXC_ERR_VALUE;
+ case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM...
+ case errDivisionByZero: return EXC_ERR_DIV0;
+ case errIllegalParameter: return EXC_ERR_VALUE;
+ case errPairExpected: return EXC_ERR_VALUE;
+ case errOperatorExpected: return EXC_ERR_VALUE;
+ case errVariableExpected: return EXC_ERR_VALUE;
+ case errParameterExpected: return EXC_ERR_VALUE;
+ case errNoValue: return EXC_ERR_VALUE;
+ case errCircularReference: return EXC_ERR_VALUE;
+ case errNoCode: return EXC_ERR_NULL;
+ case errNoRef: return EXC_ERR_REF;
+ case errNoName: return EXC_ERR_NAME;
+ case errNoAddin: return EXC_ERR_NAME;
+ case errNoMacro: return EXC_ERR_NAME;
+ case NOTAVAILABLE: return EXC_ERR_NA;
+ }
+ return EXC_ERR_NA;
+}
+
+sal_uInt16 XclTools::GetScErrorCode( sal_uInt8 nXclError )
+{
+ using namespace ScErrorCodes;
+ switch( nXclError )
+ {
+ case EXC_ERR_NULL: return errNoCode;
+ case EXC_ERR_DIV0: return errDivisionByZero;
+ case EXC_ERR_VALUE: return errNoValue;
+ case EXC_ERR_REF: return errNoRef;
+ case EXC_ERR_NAME: return errNoName;
+ case EXC_ERR_NUM: return errIllegalFPOperation;
+ case EXC_ERR_NA: return NOTAVAILABLE;
+ default: DBG_ERRORFILE( "XclTools::GetScErrorCode - unknown error code" );
+ }
+ return NOTAVAILABLE;
+}
+
+double XclTools::ErrorToDouble( sal_uInt8 nXclError )
+{
+ union
+ {
+ double fVal;
+ sal_math_Double smD;
+ };
+ ::rtl::math::setNan( &fVal );
+ smD.nan_parts.fraction_lo = GetScErrorCode( nXclError );
+ return fVal;
+}
+
+XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue )
+{
+ XclBoolError eType;
+ if( bErrOrBool )
+ {
+ // error value
+ switch( nValue )
+ {
+ case EXC_ERR_NULL: eType = xlErrNull; break;
+ case EXC_ERR_DIV0: eType = xlErrDiv0; break;
+ case EXC_ERR_VALUE: eType = xlErrValue; break;
+ case EXC_ERR_REF: eType = xlErrRef; break;
+ case EXC_ERR_NAME: eType = xlErrName; break;
+ case EXC_ERR_NUM: eType = xlErrNum; break;
+ case EXC_ERR_NA: eType = xlErrNA; break;
+ default: eType = xlErrUnknown;
+ }
+ rfDblValue = 0.0;
+ }
+ else
+ {
+ // Boolean value
+ eType = nValue ? xlErrTrue : xlErrFalse;
+ rfDblValue = nValue ? 1.0 : 0.0;
+ }
+ return eType;
+}
+
+sal_uInt16 XclTools::GetTwipsFromInch( double fInches )
+{
+ return static_cast< sal_uInt16 >(
+ ::std::min( ::std::max( (fInches * EXC_TWIPS_PER_INCH + 0.5), 0.0 ), 65535.0 ) );
+}
+
+sal_uInt16 XclTools::GetTwipsFromHmm( sal_Int32 nHmm )
+{
+ return GetTwipsFromInch( static_cast< double >( nHmm ) / 1000.0 / CM_PER_INCH );
+}
+
+double XclTools::GetInchFromTwips( sal_Int32 nTwips )
+{
+ return static_cast< double >( nTwips ) / EXC_TWIPS_PER_INCH;
+}
+
+double XclTools::GetInchFromHmm( sal_Int32 nHmm )
+{
+ return GetInchFromTwips( GetTwipsFromHmm( nHmm ) );
+}
+
+sal_Int32 XclTools::GetHmmFromInch( double fInches )
+{
+ return static_cast< sal_Int32 >( fInches * CM_PER_INCH * 1000 );
+}
+
+sal_Int32 XclTools::GetHmmFromTwips( sal_Int32 nTwips )
+{
+ return GetHmmFromInch( GetInchFromTwips( nTwips ) );
+}
+
+sal_uInt16 XclTools::GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth )
+{
+ double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth + 0.5;
+ return limit_cast< sal_uInt16 >( fScWidth );
+}
+
+sal_uInt16 XclTools::GetXclColumnWidth( sal_uInt16 nScWidth, long nScCharWidth )
+{
+ double fXclWidth = static_cast< double >( nScWidth ) * 256.0 / nScCharWidth + 0.5;
+ return limit_cast< sal_uInt16 >( fXclWidth );
+}
+
+double XclTools::GetXclDefColWidthCorrection( long nXclDefFontHeight )
+{
+ return 40960.0 / ::std::max( nXclDefFontHeight - 15L, 60L ) + 50.0;
+}
+
+// formatting -----------------------------------------------------------------
+
+Color XclTools::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern )
+{
+ // 0x00 == 0% transparence (full rPattColor)
+ // 0x80 == 100% transparence (full rBackColor)
+ static const sal_uInt8 pnRatioTable[] =
+ {
+ 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
+ 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
+ 0x50, 0x70, 0x78 // 16 - 18
+ };
+ return (nXclPattern < SAL_N_ELEMENTS( pnRatioTable )) ?
+ ScfTools::GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
+}
+
+// text encoding --------------------------------------------------------------
+
+namespace {
+
+const struct XclCodePageEntry
+{
+ sal_uInt16 mnCodePage;
+ rtl_TextEncoding meTextEnc;
+}
+pCodePageTable[] =
+{
+ { 437, RTL_TEXTENCODING_IBM_437 }, // OEM US
+// { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
+ { 737, RTL_TEXTENCODING_IBM_737 }, // OEM Greek
+ { 775, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic
+ { 850, RTL_TEXTENCODING_IBM_850 }, // OEM Latin I
+ { 852, RTL_TEXTENCODING_IBM_852 }, // OEM Latin II (Central European)
+ { 855, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic
+ { 857, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish
+// { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
+ { 860, RTL_TEXTENCODING_IBM_860 }, // OEM Portugese
+ { 861, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic
+ { 862, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew
+ { 863, RTL_TEXTENCODING_IBM_863 }, // OEM Canadian (French)
+ { 864, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic
+ { 865, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic
+ { 866, RTL_TEXTENCODING_IBM_866 }, // OEM Cyrillic (Russian)
+ { 869, RTL_TEXTENCODING_IBM_869 }, // OEM Greek (Modern)
+ { 874, RTL_TEXTENCODING_MS_874 }, // MS Windows Thai
+ { 932, RTL_TEXTENCODING_MS_932 }, // MS Windows Japanese Shift-JIS
+ { 936, RTL_TEXTENCODING_MS_936 }, // MS Windows Chinese Simplified GBK
+ { 949, RTL_TEXTENCODING_MS_949 }, // MS Windows Korean (Wansung)
+ { 950, RTL_TEXTENCODING_MS_950 }, // MS Windows Chinese Traditional BIG5
+ { 1200, RTL_TEXTENCODING_DONTKNOW }, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
+ { 1250, RTL_TEXTENCODING_MS_1250 }, // MS Windows Latin II (Central European)
+ { 1251, RTL_TEXTENCODING_MS_1251 }, // MS Windows Cyrillic
+ { 1252, RTL_TEXTENCODING_MS_1252 }, // MS Windows Latin I (BIFF4-BIFF8)
+ { 1253, RTL_TEXTENCODING_MS_1253 }, // MS Windows Greek
+ { 1254, RTL_TEXTENCODING_MS_1254 }, // MS Windows Turkish
+ { 1255, RTL_TEXTENCODING_MS_1255 }, // MS Windows Hebrew
+ { 1256, RTL_TEXTENCODING_MS_1256 }, // MS Windows Arabic
+ { 1257, RTL_TEXTENCODING_MS_1257 }, // MS Windows Baltic
+ { 1258, RTL_TEXTENCODING_MS_1258 }, // MS Windows Vietnamese
+ { 1361, RTL_TEXTENCODING_MS_1361 }, // MS Windows Korean (Johab)
+ { 10000, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3)
+};
+const XclCodePageEntry* const pCodePageTableEnd = STATIC_TABLE_END( pCodePageTable );
+
+struct XclCodePageEntry_CPPred
+{
+ inline explicit XclCodePageEntry_CPPred( sal_uInt16 nCodePage ) : mnCodePage( nCodePage ) {}
+ inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.mnCodePage == mnCodePage; }
+ sal_uInt16 mnCodePage;
+};
+
+struct XclCodePageEntry_TEPred
+{
+ inline explicit XclCodePageEntry_TEPred( rtl_TextEncoding eTextEnc ) : meTextEnc( eTextEnc ) {}
+ inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.meTextEnc == meTextEnc; }
+ rtl_TextEncoding meTextEnc;
+};
+
+} // namespace
+
+rtl_TextEncoding XclTools::GetTextEncoding( sal_uInt16 nCodePage )
+{
+ const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_CPPred( nCodePage ) );
+ if( pEntry == pCodePageTableEnd )
+ {
+ OSL_TRACE( "XclTools::GetTextEncoding - unknown code page: 0x%04hX (%d)", nCodePage, nCodePage );
+ return RTL_TEXTENCODING_DONTKNOW;
+ }
+ return pEntry->meTextEnc;
+}
+
+sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc == RTL_TEXTENCODING_UNICODE )
+ return 1200; // for BIFF8
+
+ const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) );
+ if( pEntry == pCodePageTableEnd )
+ {
+ OSL_TRACE( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc );
+ return 1252;
+ }
+ return pEntry->mnCodePage;
+}
+
+// font names -----------------------------------------------------------------
+
+String XclTools::GetXclFontName( const String& rFontName )
+{
+ // substitute with MS fonts
+ String aNewName( GetSubsFontName( rFontName, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
+ if( aNewName.Len() )
+ return aNewName;
+ return rFontName;
+}
+
+// built-in defined names -----------------------------------------------------
+
+const String XclTools::maDefNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
+
+const String XclTools::maDefNamePrefixXml ( RTL_CONSTASCII_USTRINGPARAM( "_xlnm." ) );
+
+static const sal_Char* const ppcDefNames[] =
+{
+ "Consolidate_Area",
+ "Auto_Open",
+ "Auto_Close",
+ "Extract",
+ "Database",
+ "Criteria",
+ "Print_Area",
+ "Print_Titles",
+ "Recorder",
+ "Data_Form",
+ "Auto_Activate",
+ "Auto_Deactivate",
+ "Sheet_Title",
+ "_FilterDatabase"
+};
+
+String XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn )
+{
+ DBG_ASSERT( SAL_N_ELEMENTS( ppcDefNames ) == EXC_BUILTIN_UNKNOWN,
+ "XclTools::GetXclBuiltInDefName - built-in defined name list modified" );
+ String aDefName;
+ if( cBuiltIn < SAL_N_ELEMENTS( ppcDefNames ) )
+ aDefName.AssignAscii( ppcDefNames[ cBuiltIn ] );
+ else
+ aDefName = String::CreateFromInt32( cBuiltIn );
+ return aDefName;
+}
+
+String XclTools::GetBuiltInDefName( sal_Unicode cBuiltIn )
+{
+ return String( maDefNamePrefix ).Append( GetXclBuiltInDefName( cBuiltIn ) );
+}
+
+String XclTools::GetBuiltInDefNameXml( sal_Unicode cBuiltIn )
+{
+ return String( maDefNamePrefixXml ).Append( GetXclBuiltInDefName( cBuiltIn ) );
+}
+
+sal_Unicode XclTools::GetBuiltInDefNameIndex( const String& rDefName )
+{
+ xub_StrLen nPrefixLen = maDefNamePrefix.Len();
+ if( rDefName.EqualsIgnoreCaseAscii( maDefNamePrefix, 0, nPrefixLen ) )
+ {
+ for( sal_Unicode cBuiltIn = 0; cBuiltIn < EXC_BUILTIN_UNKNOWN; ++cBuiltIn )
+ {
+ String aBuiltInName( GetXclBuiltInDefName( cBuiltIn ) );
+ xub_StrLen nBuiltInLen = aBuiltInName.Len();
+ if( rDefName.EqualsIgnoreCaseAscii( aBuiltInName, nPrefixLen, nBuiltInLen ) )
+ {
+ // name can be followed by underline or space character
+ xub_StrLen nNextCharPos = nPrefixLen + nBuiltInLen;
+ sal_Unicode cNextChar = (rDefName.Len() > nNextCharPos) ? rDefName.GetChar( nNextCharPos ) : '\0';
+ if( (cNextChar == '\0') || (cNextChar == ' ') || (cNextChar == '_') )
+ return cBuiltIn;
+ }
+ }
+ }
+ return EXC_BUILTIN_UNKNOWN;
+}
+
+// built-in style names -------------------------------------------------------
+
+const String XclTools::maStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
+const String XclTools::maStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "Excel Built-in " ) );
+
+static const sal_Char* const ppcStyleNames[] =
+{
+ "", // "Normal" not used directly, but localized "Default"
+ "RowLevel_", // outline level will be appended
+ "ColumnLevel_", // outline level will be appended
+ "Comma",
+ "Currency",
+ "Percent",
+ "Comma_0",
+ "Currency_0",
+ "Hyperlink",
+ "Followed_Hyperlink"
+};
+
+String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel )
+{
+ String aStyleName;
+
+ if( nStyleId == EXC_STYLE_NORMAL ) // "Normal" becomes "Default" style
+ {
+ aStyleName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
+ }
+ else
+ {
+ aStyleName = maStyleNamePrefix1;
+ if( nStyleId < SAL_N_ELEMENTS( ppcStyleNames ) )
+ aStyleName.AppendAscii( ppcStyleNames[ nStyleId ] );
+ else if( rName.Len() > 0 )
+ aStyleName.Append( rName );
+ else
+ aStyleName.Append( String::CreateFromInt32( nStyleId ) );
+ if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
+ aStyleName.Append( String::CreateFromInt32( nLevel + 1 ) );
+ }
+
+ return aStyleName;
+}
+
+String XclTools::GetBuiltInStyleName( const String& rStyleName )
+{
+ return String( maStyleNamePrefix1 ).Append( rStyleName );
+}
+
+bool XclTools::IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleId, xub_StrLen* pnNextChar )
+{
+ // "Default" becomes "Normal"
+ if( rStyleName == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ) )
+ {
+ if( pnStyleId ) *pnStyleId = EXC_STYLE_NORMAL;
+ if( pnNextChar ) *pnNextChar = rStyleName.Len();
+ return true;
+ }
+
+ // try the other built-in styles
+ sal_uInt8 nFoundId = 0;
+ xub_StrLen nNextChar = 0;
+
+ xub_StrLen nPrefixLen = 0;
+ if( rStyleName.EqualsIgnoreCaseAscii( maStyleNamePrefix1, 0, maStyleNamePrefix1.Len() ) )
+ nPrefixLen = maStyleNamePrefix1.Len();
+ else if( rStyleName.EqualsIgnoreCaseAscii( maStyleNamePrefix2, 0, maStyleNamePrefix2.Len() ) )
+ nPrefixLen = maStyleNamePrefix2.Len();
+ if( nPrefixLen > 0 )
+ {
+ String aShortName;
+ for( sal_uInt8 nId = 0; nId < SAL_N_ELEMENTS( ppcStyleNames ); ++nId )
+ {
+ if( nId != EXC_STYLE_NORMAL )
+ {
+ aShortName.AssignAscii( ppcStyleNames[ nId ] );
+ if( rStyleName.EqualsIgnoreCaseAscii( aShortName, nPrefixLen, aShortName.Len() ) &&
+ (nNextChar < nPrefixLen + aShortName.Len()) )
+ {
+ nFoundId = nId;
+ nNextChar = nPrefixLen + aShortName.Len();
+ }
+ }
+ }
+ }
+
+ if( nNextChar > 0 )
+ {
+ if( pnStyleId ) *pnStyleId = nFoundId;
+ if( pnNextChar ) *pnNextChar = nNextChar;
+ return true;
+ }
+
+ if( pnStyleId ) *pnStyleId = EXC_STYLE_USERDEF;
+ if( pnNextChar ) *pnNextChar = 0;
+ return nPrefixLen > 0; // also return true for unknown built-in styles
+}
+
+bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, const String& rStyleName )
+{
+ sal_uInt8 nStyleId;
+ xub_StrLen nNextChar;
+ if( IsBuiltInStyleName( rStyleName, &nStyleId, &nNextChar ) && (nStyleId != EXC_STYLE_USERDEF) )
+ {
+ if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
+ {
+ String aLevel( rStyleName, nNextChar, STRING_LEN );
+ sal_Int32 nLevel = aLevel.ToInt32();
+ if( (String::CreateFromInt32( nLevel ) == aLevel) && (nLevel > 0) && (nLevel <= EXC_STYLE_LEVELCOUNT) )
+ {
+ rnStyleId = nStyleId;
+ rnLevel = static_cast< sal_uInt8 >( nLevel - 1 );
+ return true;
+ }
+ }
+ else if( rStyleName.Len() == nNextChar )
+ {
+ rnStyleId = nStyleId;
+ rnLevel = EXC_STYLE_NOLEVEL;
+ return true;
+ }
+ }
+ rnStyleId = EXC_STYLE_USERDEF;
+ rnLevel = EXC_STYLE_NOLEVEL;
+ return false;
+}
+
+// conditional formatting style names -----------------------------------------
+
+const String XclTools::maCFStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_CondFormat_" ) );
+const String XclTools::maCFStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "ConditionalStyle_" ) );
+
+String XclTools::GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition )
+{
+ return String( maCFStyleNamePrefix1 ).Append( String::CreateFromInt32( nScTab + 1 ) ).
+ Append( '_' ).Append( String::CreateFromInt32( nFormat + 1 ) ).
+ Append( '_' ).Append( String::CreateFromInt32( nCondition + 1 ) );
+}
+
+bool XclTools::IsCondFormatStyleName( const String& rStyleName, xub_StrLen* pnNextChar )
+{
+ xub_StrLen nPrefixLen = 0;
+ if( rStyleName.EqualsIgnoreCaseAscii( maCFStyleNamePrefix1, 0, maCFStyleNamePrefix1.Len() ) )
+ nPrefixLen = maCFStyleNamePrefix1.Len();
+ else if( rStyleName.EqualsIgnoreCaseAscii( maCFStyleNamePrefix2, 0, maCFStyleNamePrefix2.Len() ) )
+ nPrefixLen = maCFStyleNamePrefix2.Len();
+ if( pnNextChar ) *pnNextChar = nPrefixLen;
+ return nPrefixLen > 0;
+}
+
+// stream handling ------------------------------------------------------------
+
+void XclTools::SkipSubStream( XclImpStream& rStrm )
+{
+ bool bLoop = true;
+ while( bLoop && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.GetRecId();
+ bLoop = nRecId != EXC_ID_EOF;
+ if( (nRecId == EXC_ID2_BOF) || (nRecId == EXC_ID3_BOF) || (nRecId == EXC_ID4_BOF) || (nRecId == EXC_ID5_BOF) )
+ SkipSubStream( rStrm );
+ }
+}
+
+// Basic macro names ----------------------------------------------------------
+
+const OUString XclTools::maSbMacroPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) );
+const OUString XclTools::maSbMacroSuffix( RTL_CONSTASCII_USTRINGPARAM( "?language=Basic&location=document" ) );
+
+OUString XclTools::GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell )
+{
+ OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" );
+ ::ooo::vba::MacroResolvedInfo aMacroInfo = ::ooo::vba::resolveVBAMacro( pDocShell, rMacroName, false );
+ if( aMacroInfo.mbFound )
+ return ::ooo::vba::makeMacroURL( aMacroInfo.msResolvedMacro );
+ return OUString();
+}
+
+OUString XclTools::GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell )
+{
+ OSL_ENSURE( rModuleName.Len() > 0, "XclTools::GetSbMacroUrl - module name is empty" );
+ OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" );
+ return GetSbMacroUrl( rModuleName + OUString( sal_Unicode( '.' ) ) + rMacroName, pDocShell );
+}
+
+String XclTools::GetXclMacroName( const OUString& rSbMacroUrl )
+{
+ sal_Int32 nSbMacroUrlLen = rSbMacroUrl.getLength();
+ sal_Int32 nMacroNameLen = nSbMacroUrlLen - maSbMacroPrefix.getLength() - maSbMacroSuffix.getLength();
+ if( (nMacroNameLen > 0) && rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroPrefix, 0 ) &&
+ rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroSuffix, nSbMacroUrlLen - maSbMacroSuffix.getLength() ) )
+ {
+ sal_Int32 nPrjDot = rSbMacroUrl.indexOf( '.', maSbMacroPrefix.getLength() ) + 1;
+ return rSbMacroUrl.copy( nPrjDot, nSbMacroUrlLen - nPrjDot - maSbMacroSuffix.getLength() );
+ }
+ return String::EmptyString();
+}
+
+// read/write colors ----------------------------------------------------------
+
+XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor )
+{
+ sal_uInt8 nR, nG, nB, nD;
+ rStrm >> nR >> nG >> nB >> nD;
+ rColor.SetColor( RGB_COLORDATA( nR, nG, nB ) );
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor )
+{
+ return rStrm << rColor.GetRed() << rColor.GetGreen() << rColor.GetBlue() << sal_uInt8( 0 );
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xltracer.cxx b/sc/source/filter/excel/xltracer.cxx
new file mode 100644
index 000000000000..a5351a1da9bf
--- /dev/null
+++ b/sc/source/filter/excel/xltracer.cxx
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// ============================================================================
+#include "xltracer.hxx"
+#include <filter/msfilter/msfiltertracer.hxx>
+#include "address.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+
+// ============================================================================
+
+// Trace Table details are grouped by functionality using the context entry.
+// Each separate context starts at the next 1000 interval. New entries should
+// be added to their appropriate context. New contexts should be added onto
+// the end. Any gaps in the 1000 sequence or within the 1000 are the result
+// of trace events no longer present.
+static const XclTracerDetails pTracerDetails[] =
+{
+ { eUnKnown, 0, "UNKNOWN", "UNKNOWN", "Unknown trace property." },
+ { eRowLimitExceeded, 1000, "Limits", "Sheet", "Row limit exceeded." },
+ { eTabLimitExceeded, 1001, "Limits", "Sheet", "Sheet limit exceeded." },
+ { ePassword, 2000, "Protection", "Password", "Document is password protected." },
+ { ePrintRange, 3000, "Print", "Print Range", "Print Range present." },
+ { eShortDate, 4000, "CellFormatting", "Short Dates", "Possible Date format issue." },
+ { eBorderLineStyle, 4004, "CellFormatting", "Border", "Line style not supported.", },
+ { eFillPattern, 4005, "CellFormatting", "Pattern", "Fill Pattern not supported.", },
+ { eInvisibleGrid, 5000, "Properties", "Grid Invisible", "Grid invisible on first sheet." },
+ { eFormattedNote, 6000, "Notes", "Formatting", "Text may be formatted." },
+ { eFormulaExtName, 7000, "Formula", "External Name", "External names not supported." },
+ { eFormulaMissingArg, 7001, "Formula", "Missing Argument","Parameter missing." },
+ { ePivotDataSource, 8000, "Chart", "Pivot", "External data source not supported."},
+ { ePivotChartExists, 8001, "Chart", "Pivot", "Pivot Chart not supported."},
+ { eChartUnKnownType, 8002, "Chart", "Type", "Chart Type not supported."},
+ { eChartTrendLines, 8003, "Chart", "Type", "Chart trendlines not supported."},
+ { eChartOnlySheet, 8004, "Chart", "Type", "Chart only sheet not supported."},
+ { eChartRange, 8005, "Chart", "Source Data", "Chart source ranges too complex."},
+ { eChartDSName, 8006, "Chart", "Source Data", "Series titles not linked to cells."},
+ { eChartDataTable, 8007, "Chart", "Legend", "Data table not supported."},
+ { eChartLegendPosition, 8008, "Chart", "Legend", "Position not guaranteed."},
+ { eChartTextFormatting, 8009, "Chart", "Formatting", "Text formatting present."},
+ { eChartEmbeddedObj, 8010, "Chart", "Area", "Object inside chart."},
+ { eChartAxisAuto, 8012, "Chart", "Axis", "Axis interval is automatic."},
+ { eChartInvalidXY, 8013, "Chart", "Scatter", "Unsupported or invalid data range for XY chart."},
+ { eChartErrorBars, 8014, "Chart", "Type", "Chart error bars not supported."},
+ { eChartAxisManual, 8015, "Chart", "Axis", "Manual axis crossing point adjusted."},
+ { eUnsupportedObject, 9000, "Object", "Type", "Limited Object support."},
+ { eObjectNotPrintable, 9001, "Object", "Print", "Object not printable."},
+ { eDVType, 10000, "DataValidation", "Type", "Custom type present."}
+};
+
+XclTracer::XclTracer( const String& rDocUrl, const OUString& rConfigPath ) :
+ maFirstTimes(eTraceLength,true)
+{
+ Sequence< PropertyValue > aConfigData( 1 );
+ aConfigData[ 0 ].Name = CREATE_OUSTRING( "DocumentURL" );
+ aConfigData[ 0 ].Value <<= OUString( rDocUrl );
+ mpTracer.reset( new MSFilterTracer( rConfigPath, &aConfigData ) );
+ mpTracer->StartTracing();
+ mbEnabled = mpTracer->IsEnabled();
+}
+
+XclTracer::~XclTracer()
+{
+ mpTracer->EndTracing();
+}
+
+void XclTracer::AddAttribute( const OUString& rName, const OUString& rValue )
+{
+ if( mbEnabled )
+ mpTracer->AddAttribute( rName, rValue );
+}
+
+void XclTracer::Trace( const OUString& rElementID, const OUString& rMessage )
+{
+ if( mbEnabled )
+ {
+ mpTracer->Trace( rElementID, rMessage );
+ mpTracer->ClearAttributes();
+ }
+}
+
+void XclTracer::TraceLog( XclTracerId eProblem, sal_Int32 nValue )
+{
+ if( mbEnabled )
+ {
+ OUString sID( CREATE_STRING( "SC" ) );
+ sID += OUString::valueOf( static_cast< sal_Int32 >( pTracerDetails[ eProblem ].mnID ) );
+ OUString sProblem = OUString::createFromAscii( pTracerDetails[ eProblem ].mpProblem );
+
+ switch (eProblem)
+ {
+ case eRowLimitExceeded:
+ Context(eProblem,static_cast<SCTAB>(nValue));
+ break;
+ case eTabLimitExceeded:
+ Context(eProblem,static_cast<SCTAB>(nValue));
+ break;
+ default:
+ Context(eProblem);
+ break;
+ }
+ Trace(sID, sProblem);
+ }
+}
+
+void XclTracer::Context( XclTracerId eProblem, SCTAB nTab )
+{
+ OUString sContext = OUString::createFromAscii( pTracerDetails[ eProblem ].mpContext );
+ OUString sDetail = OUString::createFromAscii( pTracerDetails[ eProblem ].mpDetail );
+
+ switch (eProblem)
+ {
+ case eRowLimitExceeded:
+ case eTabLimitExceeded:
+ sDetail += OUString::valueOf( static_cast< sal_Int32 >( nTab + 1 ) );
+ break;
+ default:
+ break;
+ }
+ AddAttribute(sContext, sDetail);
+}
+
+void XclTracer::ProcessTraceOnce(XclTracerId eProblem, SCTAB nTab)
+{
+ if( mbEnabled && maFirstTimes[eProblem])
+ {
+ TraceLog(pTracerDetails[eProblem].meProblemId, nTab);
+ maFirstTimes[eProblem] = false;
+ }
+}
+
+void XclTracer::TraceInvalidAddress( const ScAddress& rPos, const ScAddress& rMaxPos )
+{
+ TraceInvalidRow(rPos.Tab(), rPos.Row(), rMaxPos.Row());
+ TraceInvalidTab(rPos.Tab(), rMaxPos.Tab());
+}
+
+void XclTracer::TraceInvalidRow( SCTAB nTab, sal_uInt32 nRow, sal_uInt32 nMaxRow )
+{
+ if(nRow > nMaxRow)
+ ProcessTraceOnce(eRowLimitExceeded, nTab);
+}
+
+void XclTracer::TraceInvalidTab( SCTAB nTab, SCTAB nMaxTab )
+{
+ if(nTab > nMaxTab)
+ ProcessTraceOnce(eTabLimitExceeded, nTab);
+}
+
+void XclTracer::TracePrintRange()
+{
+ ProcessTraceOnce( ePrintRange);
+}
+
+void XclTracer::TraceDates( sal_uInt16 nNumFmt)
+{
+ // Short Date = 14 and Short Date+Time = 22
+ if(nNumFmt == 14 || nNumFmt == 22)
+ ProcessTraceOnce(eShortDate);
+}
+
+void XclTracer::TraceBorderLineStyle( bool bBorderLineStyle)
+{
+ if(bBorderLineStyle)
+ ProcessTraceOnce(eBorderLineStyle);
+}
+
+void XclTracer::TraceFillPattern( bool bFillPattern)
+{
+ if(bFillPattern)
+ ProcessTraceOnce(eFillPattern);
+}
+
+void XclTracer::TraceFormulaMissingArg()
+{
+ // missing parameter in Formula record
+ ProcessTraceOnce(eFormulaMissingArg);
+}
+
+void XclTracer::TracePivotDataSource( bool bExternal)
+{
+ if(bExternal)
+ ProcessTraceOnce(ePivotDataSource);
+}
+
+void XclTracer::TracePivotChartExists()
+{
+ // Pivot Charts not currently displayed.
+ ProcessTraceOnce(ePivotChartExists);
+}
+
+void XclTracer::TraceChartUnKnownType()
+{
+ ProcessTraceOnce(eChartUnKnownType);
+}
+
+void XclTracer::TraceChartOnlySheet()
+{
+ ProcessTraceOnce(eChartOnlySheet);
+}
+
+void XclTracer::TraceChartDataTable()
+{
+ // Data table is not supported.
+ ProcessTraceOnce(eChartDataTable);
+}
+
+void XclTracer::TraceChartLegendPosition()
+{
+ // If position is set to "not docked or inside the plot area" then
+ // we cannot guarantee the legend position.
+ ProcessTraceOnce(eChartLegendPosition);
+}
+
+void XclTracer::TraceUnsupportedObjects()
+{
+ // Called from Excel 5.0 - limited Graphical object support.
+ ProcessTraceOnce(eUnsupportedObject);
+}
+
+void XclTracer::TraceObjectNotPrintable()
+{
+ ProcessTraceOnce(eObjectNotPrintable);
+}
+
+void XclTracer::TraceDVType( bool bType)
+{
+ // Custom types work if 'Data->validity dialog' is not OKed.
+ if(bType)
+ ProcessTraceOnce(eDVType);
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlview.cxx b/sc/source/filter/excel/xlview.cxx
new file mode 100644
index 000000000000..63512e4ec2d5
--- /dev/null
+++ b/sc/source/filter/excel/xlview.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "xlview.hxx"
+#include "ftools.hxx"
+
+// Structs ====================================================================
+
+XclDocViewData::XclDocViewData() :
+ mnWinX( 0 ),
+ mnWinY( 0 ),
+ mnWinWidth( 0 ),
+ mnWinHeight( 0 ),
+ mnFlags( EXC_WIN1_HOR_SCROLLBAR | EXC_WIN1_VER_SCROLLBAR | EXC_WIN1_TABBAR ),
+ mnDisplXclTab( 0 ),
+ mnFirstVisXclTab( 0 ),
+ mnXclSelectCnt( 1 ),
+ mnTabBarWidth( 600 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclTabViewData::XclTabViewData() :
+ maFirstXclPos( ScAddress::UNINITIALIZED ),
+ maSecondXclPos( ScAddress::UNINITIALIZED )
+{
+ SetDefaults();
+}
+
+XclTabViewData::~XclTabViewData()
+{
+}
+
+void XclTabViewData::SetDefaults()
+{
+ maSelMap.clear();
+ maGridColor.SetColor( COL_AUTO );
+ maFirstXclPos.Set( 0, 0 );
+ maSecondXclPos.Set( 0, 0 );
+ mnSplitX = mnSplitY = 0;
+ mnNormalZoom = EXC_WIN2_NORMALZOOM_DEF;
+ mnPageZoom = EXC_WIN2_PAGEZOOM_DEF;
+ mnCurrentZoom = 0; // default to mnNormalZoom or mnPageZoom
+ mnActivePane = EXC_PANE_TOPLEFT;
+ mbSelected = mbDisplayed = false;
+ mbMirrored = false;
+ mbFrozenPanes = false;
+ mbPageMode = false;
+ mbDefGridColor = true;
+ mbShowFormulas = false;
+ mbShowGrid = mbShowHeadings = mbShowZeros = mbShowOutline = true;
+ maTabBgColor.SetColor( COL_AUTO );
+}
+
+bool XclTabViewData::IsSplit() const
+{
+ return (mnSplitX > 0) || (mnSplitY > 0);
+}
+
+bool XclTabViewData::HasPane( sal_uInt8 nPaneId ) const
+{
+ switch( nPaneId )
+ {
+ case EXC_PANE_BOTTOMRIGHT: return (mnSplitX > 0) && (mnSplitY > 0);
+ case EXC_PANE_TOPRIGHT: return mnSplitX > 0;
+ case EXC_PANE_BOTTOMLEFT: return mnSplitY > 0;
+ case EXC_PANE_TOPLEFT: return true;
+ }
+ DBG_ERRORFILE( "XclExpPane::HasPane - wrong pane ID" );
+ return false;
+}
+
+const XclSelectionData* XclTabViewData::GetSelectionData( sal_uInt8 nPane ) const
+{
+ XclSelectionMap::const_iterator aIt = maSelMap.find( nPane );
+ return (aIt == maSelMap.end()) ? 0 : aIt->second.get();
+}
+
+XclSelectionData& XclTabViewData::CreateSelectionData( sal_uInt8 nPane )
+{
+ XclSelectionDataRef& rxSelData = maSelMap[ nPane ];
+ if( !rxSelData )
+ rxSelData.reset( new XclSelectionData );
+ return *rxSelData;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/ftools/fapihelper.cxx b/sc/source/filter/ftools/fapihelper.cxx
new file mode 100644
index 000000000000..3e96a92d6485
--- /dev/null
+++ b/sc/source/filter/ftools/fapihelper.cxx
@@ -0,0 +1,420 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "fapihelper.hxx"
+
+#include <algorithm>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <svl/itemset.hxx>
+#include "miscuno.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::TypeClass_BOOLEAN;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertyState;
+using ::com::sun::star::lang::XServiceName;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
+
+using namespace ::com::sun::star;
+
+// Static helper functions ====================================================
+
+OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt )
+{
+ OUString aService;
+ Reference< XServiceName > xServiceName( xInt, UNO_QUERY );
+ if( xServiceName.is() )
+ aService = xServiceName->getServiceName();
+ return aService;
+}
+
+Reference< XMultiServiceFactory > ScfApiHelper::GetServiceFactory( SfxObjectShell* pShell )
+{
+ Reference< XMultiServiceFactory > xFactory;
+ if( pShell )
+ xFactory.set( pShell->GetModel(), UNO_QUERY );
+ return xFactory;
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance(
+ Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName )
+{
+ Reference< XInterface > xInt;
+ if( xFactory.is() )
+ {
+ try
+ {
+ xInt = xFactory->createInstance( rServiceName );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfApiHelper::CreateInstance - cannot create instance" );
+ }
+ }
+ return xInt;
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance( SfxObjectShell* pShell, const OUString& rServiceName )
+{
+ return CreateInstance( GetServiceFactory( pShell ), rServiceName );
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstance( const OUString& rServiceName )
+{
+ return CreateInstance( ::comphelper::getProcessServiceFactory(), rServiceName );
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
+ Reference< XMultiServiceFactory > xFactory, const OUString& rServiceName, const Sequence< Any >& rArgs )
+{
+ Reference< XInterface > xInt;
+ if( xFactory.is() )
+ {
+ try
+ {
+ xInt = xFactory->createInstanceWithArguments( rServiceName, rArgs );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfApiHelper::CreateInstanceWithArgs - cannot create instance" );
+ }
+ }
+ return xInt;
+}
+
+Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs(
+ const OUString& rServiceName, const Sequence< Any >& rArgs )
+{
+ return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs );
+}
+
+uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium,
+ ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords )
+{
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false);
+ if ( pEncryptionDataItem )
+ pEncryptionDataItem->GetValue() >>= aEncryptionData;
+
+ ::rtl::OUString aPassword;
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false);
+ if ( pPasswordItem )
+ aPassword = pPasswordItem->GetValue();
+
+ OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
+
+ bool bIsDefaultPassword = false;
+ aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName,
+ ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword );
+
+ rMedium.GetItemSet()->ClearItem( SID_PASSWORD );
+ rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA );
+
+ if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) )
+ rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
+
+ return aEncryptionData;
+}
+
+// Property sets ==============================================================
+
+void ScfPropertySet::Set( Reference< XPropertySet > xPropSet )
+{
+ mxPropSet = xPropSet;
+ mxMultiPropSet.set( mxPropSet, UNO_QUERY );
+}
+
+OUString ScfPropertySet::GetServiceName() const
+{
+ return ScfApiHelper::GetServiceName( mxPropSet );
+}
+
+// Get properties -------------------------------------------------------------
+
+bool ScfPropertySet::HasProperty( const OUString& rPropName ) const
+{
+ bool bHasProp = false;
+ try
+ {
+ Reference< XPropertyState > xPropState( mxPropSet, UNO_QUERY_THROW );
+ bHasProp = xPropState->getPropertyState( rPropName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ }
+ catch( Exception& )
+ {
+ }
+ return bHasProp;
+}
+
+bool ScfPropertySet::GetAnyProperty( Any& rValue, const OUString& rPropName ) const
+{
+ bool bHasValue = false;
+ try
+ {
+ if( mxPropSet.is() )
+ {
+ rValue = mxPropSet->getPropertyValue( rPropName );
+ bHasValue = true;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return bHasValue;
+}
+
+bool ScfPropertySet::GetBoolProperty( const ::rtl::OUString& rPropName ) const
+{
+ Any aAny;
+ return GetAnyProperty( aAny, rPropName ) && ScUnoHelpFunctions::GetBoolFromAny( aAny );
+}
+
+bool ScfPropertySet::GetStringProperty( String& rValue, const OUString& rPropName ) const
+{
+ OUString aOUString;
+ bool bRet = GetProperty( aOUString, rPropName );
+ rValue = aOUString;
+ return bRet;
+}
+
+bool ScfPropertySet::GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const
+{
+ sal_Int32 nApiColor = 0;
+ bool bRet = GetProperty( nApiColor, rPropName );
+ rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
+ return bRet;
+}
+
+void ScfPropertySet::GetProperties( Sequence< Any >& rValues, const Sequence< OUString >& rPropNames ) const
+{
+ try
+ {
+ DBG_ASSERT( mxMultiPropSet.is(), "ScfPropertySet::GetProperties - multi property set not available" );
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ rValues = mxMultiPropSet->getPropertyValues( rPropNames );
+ }
+ else if( mxPropSet.is() )
+ {
+ sal_Int32 nLen = rPropNames.getLength();
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + nLen;
+ rValues.realloc( nLen );
+ Any* pValue = rValues.getArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ *pValue = mxPropSet->getPropertyValue( *pPropName );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// Set properties -------------------------------------------------------------
+
+void ScfPropertySet::SetAnyProperty( const OUString& rPropName, const Any& rValue )
+{
+ try
+ {
+ if( mxPropSet.is() )
+ mxPropSet->setPropertyValue( rPropName, rValue );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE(
+ ByteString( "ScfPropertySet::SetAnyProperty - cannot set property \"" ).
+ Append( ByteString( String( rPropName ), RTL_TEXTENCODING_ASCII_US ) ).
+ Append( '"' ).
+ GetBuffer() );
+ }
+}
+
+void ScfPropertySet::SetProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
+{
+ DBG_ASSERT( rPropNames.getLength() == rValues.getLength(), "ScfPropertySet::SetProperties - length of sequences different" );
+ try
+ {
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ mxMultiPropSet->setPropertyValues( rPropNames, rValues );
+ }
+ else if( mxPropSet.is() )
+ {
+ DBG_ERRORFILE( "ScfPropertySet::SetProperties - multi property set not available" );
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
+ const Any* pValue = rValues.getConstArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ mxPropSet->setPropertyValue( *pPropName, *pValue );
+ }
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "ScfPropertySet::SetAnyProperty - cannot set multiple properties" );
+ }
+}
+
+// ============================================================================
+
+ScfPropSetHelper::ScfPropSetHelper( const sal_Char* const* ppcPropNames ) :
+ mnNextIdx( 0 )
+{
+ DBG_ASSERT( ppcPropNames, "ScfPropSetHelper::ScfPropSetHelper - no strings found" );
+
+ // create OUStrings from ASCII property names
+ typedef ::std::pair< OUString, size_t > IndexedOUString;
+ typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
+ IndexedOUStringVec aPropNameVec;
+ for( size_t nVecIdx = 0; *ppcPropNames; ++ppcPropNames, ++nVecIdx )
+ {
+ OUString aPropName = OUString::createFromAscii( *ppcPropNames );
+ aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx ) );
+ }
+
+ // sorts the pairs, which will be sorted by first component (the property name)
+ ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
+
+ // resize member sequences
+ size_t nSize = aPropNameVec.size();
+ maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maNameOrder.resize( nSize );
+
+ // fill the property name sequence and store original sort order
+ sal_Int32 nSeqIdx = 0;
+ for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
+ aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
+ {
+ maNameSeq[ nSeqIdx ] = aIt->first;
+ maNameOrder[ aIt->second ] = nSeqIdx;
+ }
+}
+
+// read properties ------------------------------------------------------------
+
+void ScfPropSetHelper::ReadFromPropertySet( const ScfPropertySet& rPropSet )
+{
+ rPropSet.GetProperties( maValueSeq, maNameSeq );
+ mnNextIdx = 0;
+}
+
+bool ScfPropSetHelper::ReadValue( UnoAny& rAny )
+{
+ UnoAny* pAny = GetNextAny();
+ if( pAny )
+ rAny = *pAny;
+ return pAny != 0;
+}
+
+bool ScfPropSetHelper::ReadValue( String& rString )
+{
+ OUString aOUString;
+ bool bRet = ReadValue( aOUString );
+ rString = aOUString;
+ return bRet;
+}
+
+bool ScfPropSetHelper::ReadValue( Color& rColor )
+{
+ sal_Int32 nApiColor(0);
+ bool bRet = ReadValue( nApiColor );
+ rColor = ScfApiHelper::ConvertFromApiColor( nApiColor );
+ return bRet;
+}
+
+bool ScfPropSetHelper::ReadValue( bool& rbValue )
+{
+ Any aAny;
+ bool bRet = ReadValue( aAny );
+ rbValue = ScUnoHelpFunctions::GetBoolFromAny( aAny );
+ return bRet;
+}
+
+// write properties -----------------------------------------------------------
+
+void ScfPropSetHelper::InitializeWrite( bool bClearAllAnys )
+{
+ mnNextIdx = 0;
+ if( bClearAllAnys )
+ for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
+ maValueSeq[ nIdx ].clear();
+}
+
+void ScfPropSetHelper::WriteValue( const Any& rAny )
+{
+ if( UnoAny* pAny = GetNextAny() )
+ *pAny = rAny;
+}
+
+void ScfPropSetHelper::WriteValue( const bool& rbValue )
+{
+ if( Any* pAny = GetNextAny() )
+ ScUnoHelpFunctions::SetBoolInAny( *pAny, rbValue );
+}
+
+void ScfPropSetHelper::WriteToPropertySet( ScfPropertySet& rPropSet ) const
+{
+ rPropSet.SetProperties( maNameSeq, maValueSeq );
+}
+
+// private --------------------------------------------------------------------
+
+Any* ScfPropSetHelper::GetNextAny()
+{
+ DBG_ASSERT( mnNextIdx < maNameOrder.size(), "ScfPropSetHelper::GetNextAny - sequence overflow" );
+ Any* pAny = 0;
+ if( mnNextIdx < maNameOrder.size() )
+ pAny = &maValueSeq[ maNameOrder[ mnNextIdx++ ] ];
+ return pAny;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/ftools/fprogressbar.cxx b/sc/source/filter/ftools/fprogressbar.cxx
new file mode 100644
index 000000000000..20e227f69f46
--- /dev/null
+++ b/sc/source/filter/ftools/fprogressbar.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "fprogressbar.hxx"
+#include "global.hxx"
+#include "progress.hxx"
+
+// ============================================================================
+
+ScfProgressBar::ScfProgressSegment::ScfProgressSegment( sal_Size nSize ) :
+ mxProgress( 0 ),
+ mnSize( nSize ),
+ mnPos( 0 )
+{
+}
+
+ScfProgressBar::ScfProgressSegment::~ScfProgressSegment()
+{
+}
+
+// ============================================================================
+
+ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, const String& rText ) :
+ maText( rText )
+{
+ Init( pDocShell );
+}
+
+ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
+ maText( ScGlobal::GetRscString( nResId ) )
+{
+ Init( pDocShell );
+}
+
+ScfProgressBar::ScfProgressBar( ScfProgressBar& rParProgress, ScfProgressSegment* pParSegment )
+{
+ Init( rParProgress.mpDocShell );
+ mpParentProgress = &rParProgress;
+ mpParentSegment = pParSegment;
+}
+
+ScfProgressBar::~ScfProgressBar()
+{
+}
+
+void ScfProgressBar::Init( SfxObjectShell* pDocShell )
+{
+ mpDocShell = pDocShell;
+ mpParentProgress = 0;
+ mpParentSegment = mpCurrSegment = 0;
+ mnTotalSize = mnTotalPos = mnUnitSize = mnNextUnitPos = 0;
+ mnSysProgressScale = 1; // used to workaround the ULONG_MAX/100 limit
+ mbInProgress = false;
+}
+
+ScfProgressBar::ScfProgressSegment* ScfProgressBar::GetSegment( sal_Int32 nSegment )
+{
+ if( nSegment < 0 )
+ return 0;
+ return &(maSegments.at( nSegment ));
+}
+
+void ScfProgressBar::SetCurrSegment( ScfProgressSegment* pSegment )
+{
+ if( mpCurrSegment != pSegment )
+ {
+ mpCurrSegment = pSegment;
+
+ if( mpParentProgress && mpParentSegment )
+ {
+ mpParentProgress->SetCurrSegment( mpParentSegment );
+ }
+ else if( !mxSysProgress.get() && (mnTotalSize > 0) )
+ {
+ // System progress has an internal limit of ULONG_MAX/100.
+ mnSysProgressScale = 1;
+ sal_uLong nSysTotalSize = static_cast< sal_uLong >( mnTotalSize );
+ while( nSysTotalSize >= ULONG_MAX / 100 )
+ {
+ nSysTotalSize /= 2;
+ mnSysProgressScale *= 2;
+ }
+ mxSysProgress.reset( new ScProgress( mpDocShell, maText, nSysTotalSize ) );
+ }
+
+ if( !mbInProgress && mpCurrSegment && (mnTotalSize > 0) )
+ {
+ mnUnitSize = mnTotalSize / 256 + 1; // at most 256 calls of system progress
+ mnNextUnitPos = 0;
+ mbInProgress = true;
+ }
+ }
+}
+
+void ScfProgressBar::IncreaseProgressBar( sal_Size nDelta )
+{
+ sal_Size nNewPos = mnTotalPos + nDelta;
+
+ // call back to parent progress bar
+ if( mpParentProgress && mpParentSegment )
+ {
+ // calculate new position of parent progress bar
+ sal_Size nParentPos = static_cast< sal_Size >(
+ static_cast< double >( nNewPos ) * mpParentSegment->mnSize / mnTotalSize );
+ mpParentProgress->ProgressAbs( nParentPos );
+ }
+ // modify system progress bar
+ else if( mxSysProgress.get() )
+ {
+ if( nNewPos >= mnNextUnitPos )
+ {
+ mnNextUnitPos = nNewPos + mnUnitSize;
+ mxSysProgress->SetState( static_cast< sal_uLong >( nNewPos / mnSysProgressScale ) );
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScfProgressBar::IncreaseProgressBar - no progress bar found" );
+ }
+
+ mnTotalPos = nNewPos;
+}
+
+sal_Int32 ScfProgressBar::AddSegment( sal_Size nSize )
+{
+ DBG_ASSERT( !mbInProgress, "ScfProgressBar::AddSegment - already in progress mode" );
+ if( nSize == 0 )
+ return SCF_INV_SEGMENT;
+
+ maSegments.push_back( new ScfProgressSegment( nSize ) );
+ mnTotalSize += nSize;
+ return static_cast< sal_Int32 >( maSegments.size() - 1 );
+}
+
+ScfProgressBar& ScfProgressBar::GetSegmentProgressBar( sal_Int32 nSegment )
+{
+ ScfProgressSegment* pSegment = GetSegment( nSegment );
+ DBG_ASSERT( !pSegment || (pSegment->mnPos == 0), "ScfProgressBar::GetSegmentProgressBar - segment already started" );
+ if( pSegment && (pSegment->mnPos == 0) )
+ {
+ if( !pSegment->mxProgress.get() )
+ pSegment->mxProgress.reset( new ScfProgressBar( *this, pSegment ) );
+ return *pSegment->mxProgress;
+ }
+ return *this;
+}
+
+bool ScfProgressBar::IsFull() const
+{
+ DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::IsFull - no segment started" );
+ return mpCurrSegment && (mpCurrSegment->mnPos >= mpCurrSegment->mnSize);
+}
+
+void ScfProgressBar::ActivateSegment( sal_Int32 nSegment )
+{
+ DBG_ASSERT( mnTotalSize > 0, "ScfProgressBar::ActivateSegment - progress range is zero" );
+ if( mnTotalSize > 0 )
+ SetCurrSegment( GetSegment( nSegment ) );
+}
+
+void ScfProgressBar::ProgressAbs( sal_Size nPos )
+{
+ DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::ProgressAbs - no segment started" );
+ if( mpCurrSegment )
+ {
+ DBG_ASSERT( mpCurrSegment->mnPos <= nPos, "ScfProgressBar::ProgressAbs - delta pos < 0" );
+ DBG_ASSERT( nPos <= mpCurrSegment->mnSize, "ScfProgressBar::ProgressAbs - segment overflow" );
+ if( (mpCurrSegment->mnPos < nPos) && (nPos <= mpCurrSegment->mnSize) )
+ {
+ IncreaseProgressBar( nPos - mpCurrSegment->mnPos );
+ mpCurrSegment->mnPos = nPos;
+ }
+ }
+}
+
+void ScfProgressBar::Progress( sal_Size nDelta )
+{
+ ProgressAbs( mpCurrSegment ? (mpCurrSegment->mnPos + nDelta) : 0 );
+}
+
+// ============================================================================
+
+ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText ) :
+ maProgress( pDocShell, rText )
+{
+ Init( nSize );
+}
+
+ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
+ maProgress( pDocShell, nResId )
+{
+ Init( nSize );
+}
+
+void ScfSimpleProgressBar::Init( sal_Size nSize )
+{
+ sal_Int32 nSegment = maProgress.AddSegment( nSize );
+ if( nSegment >= 0 )
+ maProgress.ActivateSegment( nSegment );
+}
+
+ScfStreamProgressBar::ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
+ mrStrm( rStrm )
+{
+ Init( pDocShell, ScGlobal::GetRscString( nResId ) );
+}
+
+void ScfStreamProgressBar::Progress()
+{
+ mxProgress->ProgressAbs( mrStrm.Tell() );
+}
+
+void ScfStreamProgressBar::Init( SfxObjectShell* pDocShell, const String& rText )
+{
+ sal_Size nPos = mrStrm.Tell();
+ mrStrm.Seek( STREAM_SEEK_TO_END );
+ sal_Size nSize = mrStrm.Tell();
+ mrStrm.Seek( nPos );
+
+ mxProgress.reset( new ScfSimpleProgressBar( nSize, pDocShell, rText ) );
+ Progress();
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/ftools/ftools.cxx b/sc/source/filter/ftools/ftools.cxx
new file mode 100644
index 000000000000..1846794667d3
--- /dev/null
+++ b/sc/source/filter/ftools/ftools.cxx
@@ -0,0 +1,410 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "ftools.hxx"
+#include <tools/color.hxx>
+#include <unotools/charclass.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/poolitem.hxx>
+#include <sot/storage.hxx>
+
+#include <math.h>
+#include "global.hxx"
+#include "document.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "compiler.hxx"
+
+#include <stdio.h>
+
+// ============================================================================
+// ScFilterTools::ReadLongDouble()
+
+#ifdef _MSC_VER
+#if _MSC_VER <= 800
+#undef __SIMPLE_FUNC
+#define __SIMPLE_FUNC
+#endif
+#endif
+
+double ScfTools::ReadLongDouble( SvStream& rStrm )
+
+#ifdef __SIMPLE_FUNC // for <=VC 1.5
+{
+ long double fRet;
+ rStrm.Read( &fRet, 10 );
+ return static_cast< double >( fRet );
+}
+#undef __SIMPLE_FUNC
+
+#else // detailed for all others
+{
+
+/*
+" M a p p i n g - G u i d e " 10-Byte Intel
+
+77777777 77666666 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
+98765432 10987654 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit-# total
+9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 Byte-#
+76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 76543210 Bit-# in Byte
+SEEEEEEE EEEEEEEE IMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM Group
+01111110 00000000 06665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 x10
+14321098 76543210 02109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 Bit in Group
+*/
+
+ register long double lfDouble = 0.0;
+ register long double lfFakt = 256.0;
+ sal_uInt8 pDouble10[ 10 ];
+
+ rStrm.Read( pDouble10, 10 ); // Intel-10 in pDouble10
+
+ lfDouble = static_cast< long double >( pDouble10[ 7 ] ); // Byte 7
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 6 ] ); // Byte 6
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 5 ] ); // Byte 5
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 4 ] ); // Byte 4
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 3 ] ); // Byte 3
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 2 ] ); // Byte 2
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 1 ] ); // Byte 1
+ lfDouble *= lfFakt;
+ lfDouble += static_cast< long double >( pDouble10[ 0 ] ); // Byte 0
+
+ // For value 0.0 all bits are zero; pow(2.0,-16446) does not work with CSet compilers
+ if( lfDouble != 0.0 )
+ {
+ // exponent
+ register sal_Int32 nExp;
+ nExp = pDouble10[ 9 ] & 0x7F;
+ nExp <<= 8;
+ nExp += pDouble10[ 8 ];
+ nExp -= 16446;
+
+ lfDouble *= pow( 2.0, static_cast< double >( nExp ) );
+ }
+
+ // sign
+ if( pDouble10[ 9 ] & 0x80 )
+ lfDouble *= static_cast< long double >( -1.0 );
+
+ return static_cast< double >( lfDouble );
+}
+#endif
+
+// *** common methods *** -----------------------------------------------------
+
+rtl_TextEncoding ScfTools::GetSystemTextEncoding()
+{
+ return gsl_getSystemTextEncoding();
+}
+
+String ScfTools::GetHexStr( sal_uInt16 nValue )
+{
+ const sal_Char pHex[] = "0123456789ABCDEF";
+ String aStr;
+
+ aStr += pHex[ nValue >> 12 ];
+ aStr += pHex[ (nValue >> 8) & 0x000F ];
+ aStr += pHex[ (nValue >> 4) & 0x000F ];
+ aStr += pHex[ nValue & 0x000F ];
+ return aStr;
+}
+
+sal_uInt8 ScfTools::GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans )
+{
+ sal_Int32 nTemp = ((static_cast< sal_Int32 >( nBack ) - nFore) * nTrans) / 0x80 + nFore;
+ return static_cast< sal_uInt8 >( nTemp );
+}
+
+Color ScfTools::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans )
+{
+ return Color(
+ GetMixedColorComp( rFore.GetRed(), rBack.GetRed(), nTrans ),
+ GetMixedColorComp( rFore.GetGreen(), rBack.GetGreen(), nTrans ),
+ GetMixedColorComp( rFore.GetBlue(), rBack.GetBlue(), nTrans ) );
+}
+
+// *** conversion of names *** ------------------------------------------------
+
+/* XXX As in sc/source/core/tool/rangenam.cxx ScRangeData::IsValidName() */
+
+void ScfTools::ConvertToScDefinedName( String& rName )
+{
+ sal_Char a('.');
+ rName.SearchAndReplaceAllAscii(&a,'_'); //fdo#37872: we don't allow points in range names any more
+ xub_StrLen nLen = rName.Len();
+ if( nLen && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
+ rName.SetChar( 0, '_' );
+ for( xub_StrLen nPos = 1; nPos < nLen; ++nPos )
+ if( !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME ) )
+ rName.SetChar( nPos, '_' );
+}
+
+// *** streams and storages *** -----------------------------------------------
+
+SotStorageRef ScfTools::OpenStorageRead( SotStorageRef xStrg, const String& rStrgName )
+{
+ SotStorageRef xSubStrg;
+ if( xStrg.Is() && xStrg->IsContained( rStrgName ) )
+ xSubStrg = xStrg->OpenSotStorage( rStrgName, STREAM_STD_READ );
+ return xSubStrg;
+}
+
+SotStorageRef ScfTools::OpenStorageWrite( SotStorageRef xStrg, const String& rStrgName )
+{
+ SotStorageRef xSubStrg;
+ if( xStrg.Is() )
+ xSubStrg = xStrg->OpenSotStorage( rStrgName, STREAM_STD_WRITE );
+ return xSubStrg;
+}
+
+SotStorageStreamRef ScfTools::OpenStorageStreamRead( SotStorageRef xStrg, const String& rStrmName )
+{
+ SotStorageStreamRef xStrm;
+ if( xStrg.Is() && xStrg->IsContained( rStrmName ) && xStrg->IsStream( rStrmName ) )
+ xStrm = xStrg->OpenSotStream( rStrmName, STREAM_STD_READ );
+ return xStrm;
+}
+
+SotStorageStreamRef ScfTools::OpenStorageStreamWrite( SotStorageRef xStrg, const String& rStrmName )
+{
+ DBG_ASSERT( !xStrg || !xStrg->IsContained( rStrmName ), "ScfTools::OpenStorageStreamWrite - stream exists already" );
+ SotStorageStreamRef xStrm;
+ if( xStrg.Is() )
+ xStrm = xStrg->OpenSotStream( rStrmName, STREAM_STD_WRITE | STREAM_TRUNC );
+ return xStrm;
+}
+
+// *** item handling *** ------------------------------------------------------
+
+bool ScfTools::CheckItem( const SfxItemSet& rItemSet, sal_uInt16 nWhichId, bool bDeep )
+{
+ return rItemSet.GetItemState( nWhichId, bDeep ) == SFX_ITEM_SET;
+}
+
+bool ScfTools::CheckItems( const SfxItemSet& rItemSet, const sal_uInt16* pnWhichIds, bool bDeep )
+{
+ DBG_ASSERT( pnWhichIds, "ScfTools::CheckItems - no which id list" );
+ for( const sal_uInt16* pnWhichId = pnWhichIds; *pnWhichId != 0; ++pnWhichId )
+ if( CheckItem( rItemSet, *pnWhichId, bDeep ) )
+ return true;
+ return false;
+}
+
+void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, sal_uInt16 nWhichId, bool bSkipPoolDef )
+{
+ if( !bSkipPoolDef || (rItem != rItemSet.GetPool()->GetDefaultItem( nWhichId )) )
+ rItemSet.Put( rItem, nWhichId );
+}
+
+void ScfTools::PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, bool bSkipPoolDef )
+{
+ PutItem( rItemSet, rItem, rItem.Which(), bSkipPoolDef );
+}
+
+// *** style sheet handling *** -----------------------------------------------
+
+namespace {
+
+ScStyleSheet& lclMakeStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, SfxStyleFamily eFamily, bool bForceName )
+{
+ // find an unused name
+ String aNewName( rStyleName );
+ sal_Int32 nIndex = 0;
+ SfxStyleSheetBase* pOldStyleSheet = 0;
+ while( SfxStyleSheetBase* pStyleSheet = rPool.Find( aNewName, eFamily ) )
+ {
+ if( !pOldStyleSheet )
+ pOldStyleSheet = pStyleSheet;
+ aNewName.Assign( rStyleName ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) );
+ }
+
+ // rename existing style
+ if( pOldStyleSheet && bForceName )
+ {
+ pOldStyleSheet->SetName( aNewName );
+ aNewName = rStyleName;
+ }
+
+ // create new style sheet
+ return static_cast< ScStyleSheet& >( rPool.Make( aNewName, eFamily, SFXSTYLEBIT_USERDEF ) );
+}
+
+} // namespace
+
+ScStyleSheet& ScfTools::MakeCellStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, bool bForceName )
+{
+ return lclMakeStyleSheet( rPool, rStyleName, SFX_STYLE_FAMILY_PARA, bForceName );
+}
+
+ScStyleSheet& ScfTools::MakePageStyleSheet( ScStyleSheetPool& rPool, const String& rStyleName, bool bForceName )
+{
+ return lclMakeStyleSheet( rPool, rStyleName, SFX_STYLE_FAMILY_PAGE, bForceName );
+}
+
+// *** byte string import operations *** --------------------------------------
+
+ByteString ScfTools::ReadCString( SvStream& rStrm )
+{
+ ByteString aRet;
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ while( cChar )
+ {
+ aRet += cChar;
+ rStrm >> cChar;
+ }
+ return aRet;
+}
+
+ByteString ScfTools::ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft )
+{
+ ByteString aRet;
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ rnBytesLeft--;
+ while( cChar )
+ {
+ aRet += cChar;
+ rStrm >> cChar;
+ rnBytesLeft--;
+ }
+
+ return aRet;
+}
+
+void ScfTools::AppendCString( SvStream& rStrm, ByteString& rString )
+{
+ sal_Char cChar;
+
+ rStrm >> cChar;
+ while( cChar )
+ {
+ rString += cChar;
+ rStrm >> cChar;
+ }
+}
+
+void ScfTools::AppendCString( SvStream& rStrm, String& rString, rtl_TextEncoding eTextEnc )
+{
+ ByteString aByteString;
+ AppendCString( rStrm, aByteString );
+ rString += String( aByteString, eTextEnc );
+}
+
+// *** HTML table names <-> named range names *** -----------------------------
+
+const String& ScfTools::GetHTMLDocName()
+{
+ static const String saHTMLDoc( RTL_CONSTASCII_USTRINGPARAM( "HTML_all" ) );
+ return saHTMLDoc;
+}
+
+const String& ScfTools::GetHTMLTablesName()
+{
+ static const String saHTMLTables( RTL_CONSTASCII_USTRINGPARAM( "HTML_tables" ) );
+ return saHTMLTables;
+}
+
+const String& ScfTools::GetHTMLIndexPrefix()
+{
+ static const String saHTMLIndexPrefix( RTL_CONSTASCII_USTRINGPARAM( "HTML_" ) );
+ return saHTMLIndexPrefix;
+
+}
+
+const String& ScfTools::GetHTMLNamePrefix()
+{
+ static const String saHTMLNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "HTML__" ) );
+ return saHTMLNamePrefix;
+}
+
+String ScfTools::GetNameFromHTMLIndex( sal_uInt32 nIndex )
+{
+ String aName( GetHTMLIndexPrefix() );
+ aName += String::CreateFromInt32( static_cast< sal_Int32 >( nIndex ) );
+ return aName;
+}
+
+String ScfTools::GetNameFromHTMLName( const String& rTabName )
+{
+ String aName( GetHTMLNamePrefix() );
+ aName += rTabName;
+ return aName;
+}
+
+bool ScfTools::IsHTMLDocName( const String& rSource )
+{
+ return rSource.EqualsIgnoreCaseAscii( GetHTMLDocName() );
+}
+
+bool ScfTools::IsHTMLTablesName( const String& rSource )
+{
+ return rSource.EqualsIgnoreCaseAscii( GetHTMLTablesName() );
+}
+
+bool ScfTools::GetHTMLNameFromName( const String& rSource, String& rName )
+{
+ rName.Erase();
+ if( rSource.EqualsIgnoreCaseAscii( GetHTMLNamePrefix(), 0, GetHTMLNamePrefix().Len() ) )
+ {
+ rName = rSource.Copy( GetHTMLNamePrefix().Len() );
+ ScGlobal::AddQuotes( rName, '"', false );
+ }
+ else if( rSource.EqualsIgnoreCaseAscii( GetHTMLIndexPrefix(), 0, GetHTMLIndexPrefix().Len() ) )
+ {
+ String aIndex( rSource.Copy( GetHTMLIndexPrefix().Len() ) );
+ if( CharClass::isAsciiNumeric( aIndex ) && (aIndex.ToInt32() > 0) )
+ rName = aIndex;
+ }
+ return rName.Len() > 0;
+}
+
+// ============================================================================
+
+ScFormatFilterPluginImpl::ScFormatFilterPluginImpl()
+{
+}
+
+SAL_DLLPUBLIC_EXPORT ScFormatFilterPlugin * SAL_CALL ScFilterCreate(void)
+{
+ return new ScFormatFilterPluginImpl();
+}
+
+// implementation class inside the filters
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx
new file mode 100644
index 000000000000..1c97b00152e6
--- /dev/null
+++ b/sc/source/filter/html/htmlexp.cxx
@@ -0,0 +1,1338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#define _SVSTDARR_STRINGSSORTDTOR
+#include <rtl/tencinfo.h>
+
+#include <vcl/svapp.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/editeng.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/frmhtmlw.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/urihelper.hxx>
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#endif
+#include <svl/svstdarr.hxx>
+#include <svl/zforlist.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/parhtml.hxx>
+#include <vcl/outdev.hxx>
+#include <stdio.h>
+
+#include "htmlexp.hxx"
+#include "filter.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "stlpool.hxx"
+#include "scresid.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "docoptio.hxx"
+#include "editutil.hxx"
+#include "ftools.hxx"
+
+
+#include <editeng/flditem.hxx>
+#include <editeng/borderline.hxx>
+#include <unotools/syslocale.hxx>
+
+
+// ohne sc.hrc: error C2679: binary '=' : no operator defined which takes a
+// right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
+// bei
+// const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
+// ?!???
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+using ::editeng::SvxBorderLine;
+
+//========================================================================
+
+const static sal_Char sMyBegComment[] = "<!-- ";
+const static sal_Char sMyEndComment[] = " -->";
+const static sal_Char sFontFamily[] = "font-family:";
+const static sal_Char sFontSize[] = "font-size:";
+
+const sal_uInt16 ScHTMLExport::nDefaultFontSize[SC_HTML_FONTSIZES] =
+{
+ HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
+ HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
+};
+
+sal_uInt16 ScHTMLExport::nFontSize[SC_HTML_FONTSIZES] = { 0 };
+
+const char* ScHTMLExport::pFontSizeCss[SC_HTML_FONTSIZES] =
+{
+ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
+};
+
+const sal_uInt16 ScHTMLExport::nCellSpacing = 0;
+const sal_Char ScHTMLExport::sIndentSource[nIndentMax+1] =
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+
+//========================================================================
+// Makros fuer HTML-Export
+//========================================================================
+#define OUT_PROLOGUE() (rStrm << sHTML30_Prologue << ScExportBase::sNewLine \
+ << ScExportBase::sNewLine)
+#define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
+#define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, false )
+#define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
+#define OUT_STR_NO_CONV( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc )
+#define OUT_LF() rStrm << ScExportBase::sNewLine << GetIndentStr()
+#define lcl_OUT_LF() rStrm << ScExportBase::sNewLine
+#define TAG_ON_LF( tag ) (TAG_ON( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define TAG_OFF_LF( tag ) (TAG_OFF( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
+#define OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine \
+ << GetIndentStr())
+#define lcl_OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR_NO_CONV( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine)
+
+#define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '='
+#define APPEND_SPACE( s ) s.AppendAscii(" ")
+
+#define GLOBSTR(id) ScGlobal::GetRscString( id )
+
+
+
+//========================================================================
+
+FltError ScFormatFilterPluginImpl::ScExportHTML( SvStream& rStrm, const String& rBaseURL, ScDocument* pDoc,
+ const ScRange& rRange, const CharSet /*eNach*/, sal_Bool bAll,
+ const String& rStreamPath, String& rNonConvertibleChars )
+{
+ ScHTMLExport aEx( rStrm, rBaseURL, pDoc, rRange, bAll, rStreamPath );
+ FltError nErr = aEx.Write();
+ rNonConvertibleChars = aEx.GetNonConvertibleChars();
+ return nErr;
+}
+
+
+void lcl_AddStamp( String& rStr, const String& rName,
+ const ::com::sun::star::util::DateTime& rDateTime,
+ const LocaleDataWrapper& rLoc )
+{
+ Date aD(rDateTime.Day, rDateTime.Month, rDateTime.Year);
+ Time aT(rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds,
+ rDateTime.HundredthSeconds);
+ DateTime aDateTime(aD,aT);
+
+ String aStrDate = rLoc.getDate( aDateTime );
+ String aStrTime = rLoc.getTime( aDateTime );
+
+ rStr += GLOBSTR( STR_BY );
+ APPEND_SPACE( rStr );
+ if (rName.Len())
+ rStr += rName;
+ else
+ rStr.AppendAscii( "???" );
+ APPEND_SPACE( rStr );
+ rStr += GLOBSTR( STR_ON );
+ APPEND_SPACE( rStr );
+ if (aStrDate.Len())
+ rStr += aStrDate;
+ else
+ rStr.AppendAscii( "???" );
+ rStr.AppendAscii( ", " );
+ if (aStrTime.Len())
+ rStr += aStrTime;
+ else
+ rStr.AppendAscii( "???" );
+}
+
+
+void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor )
+{
+ // <font COLOR="#00FF40">hallo</font>
+ sal_Char buf[64];
+ sal_Char* p = buf;
+
+ rStr += "\"#";
+ p += sprintf( p, "%02X", rColor.GetRed() );
+ p += sprintf( p, "%02X", rColor.GetGreen() );
+ p += sprintf( p, "%02X", rColor.GetBlue() );
+ rStr += buf;
+ rStr += '\"';
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP,
+ const ScRange& rRangeP,
+ sal_Bool bAllP, const String& rStreamPathP ) :
+ ScExportBase( rStrmP, pDocP, rRangeP ),
+ aBaseURL( rBaseURL ),
+ aStreamPath( rStreamPathP ),
+ pAppWin( Application::GetDefaultDevice() ),
+ pSrcArr( NULL ),
+ pDestArr( NULL ),
+ nUsedTables( 0 ),
+ nIndent( 0 ),
+ bAll( bAllP ),
+ bTabHasGraphics( false ),
+ bCalcAsShown( pDocP->GetDocOptions().IsCalcAsShown() ),
+ bTableDataWidth( sal_True ),
+ bTableDataHeight( sal_True )
+{
+ strcpy( sIndent, sIndentSource );
+ sIndent[0] = 0;
+
+ // set HTML configuration
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ eDestEnc = (pDoc->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8 : pHtmlOptions->GetTextEncoding());
+ bCopyLocalFileToINet = pHtmlOptions->IsSaveGraphicsLocal();
+ for ( sal_uInt16 j=0; j < SC_HTML_FONTSIZES; j++ )
+ {
+ sal_uInt16 nSize = pHtmlOptions->GetFontSize( j );
+ // remember in Twips, like our SvxFontHeightItem
+ if ( nSize )
+ nFontSize[j] = nSize * 20;
+ else
+ nFontSize[j] = nDefaultFontSize[j] * 20;
+ }
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ nUsedTables++;
+ }
+
+ // Content-Id fuer Mail-Export?
+ SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ORIGURL );
+ if( pItem )
+ {
+ aCId = ((const SfxStringItem *)pItem)->GetValue();
+ DBG_ASSERT( aCId.Len(), "CID ohne Laenge!" );
+ }
+ }
+}
+
+
+ScHTMLExport::~ScHTMLExport()
+{
+ aGraphList.clear();
+ delete pSrcArr;
+ delete pDestArr;
+}
+
+
+sal_uInt16 ScHTMLExport::GetFontSizeNumber( sal_uInt16 nHeight )
+{
+ sal_uInt16 nSize = 1;
+ for ( sal_uInt16 j=SC_HTML_FONTSIZES-1; j>0; j-- )
+ {
+ if( nHeight > (nFontSize[j] + nFontSize[j-1]) / 2 )
+ { // der naechstgelegene
+ nSize = j+1;
+ break;
+ }
+ }
+ return nSize;
+}
+
+const char* ScHTMLExport::GetFontSizeCss( sal_uInt16 nHeight )
+{
+ sal_uInt16 nSize = GetFontSizeNumber( nHeight );
+ return pFontSizeCss[ nSize-1 ];
+}
+
+
+sal_uInt16 ScHTMLExport::ToPixel( sal_uInt16 nVal )
+{
+ if( nVal )
+ {
+ nVal = (sal_uInt16)pAppWin->LogicToPixel(
+ Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
+ if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
+ nVal = 1;
+ }
+ return nVal;
+}
+
+
+Size ScHTMLExport::MMToPixel( const Size& rSize )
+{
+ Size aSize( rSize );
+ aSize = pAppWin->LogicToPixel( rSize, MapMode( MAP_100TH_MM ) );
+ // wo etwas ist sollte auch ein Pixel sein
+ if ( !aSize.Width() && rSize.Width() )
+ aSize.Width() = 1;
+ if ( !aSize.Height() && rSize.Height() )
+ aSize.Height() = 1;
+ return aSize;
+}
+
+
+sal_uLong ScHTMLExport::Write()
+{
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_doctype << ' ' << OOO_STRING_SVTOOLS_HTML_doctype32 << '>'
+ << sNewLine << sNewLine;
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
+ WriteHeader();
+ OUT_LF();
+ WriteBody();
+ OUT_LF();
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
+
+ return rStrm.GetError();
+}
+
+
+void ScHTMLExport::WriteHeader()
+{
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
+
+ if ( pDoc->IsClipOrUndo() )
+ { // no real DocInfo available, but some META information like charset needed
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, NULL, sIndent, eDestEnc, &aNonConvertibleChars );
+ }
+ else
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, xDocProps,
+ sIndent, eDestEnc, &aNonConvertibleChars );
+ OUT_LF();
+
+ //----------------------------------------------------------
+ if (xDocProps->getPrintedBy().getLength())
+ {
+ OUT_COMMENT( GLOBSTR( STR_DOC_INFO ) );
+ String aStrOut( GLOBSTR( STR_DOC_PRINTED ) );
+ aStrOut.AppendAscii( ": " );
+ lcl_AddStamp( aStrOut, xDocProps->getPrintedBy(),
+ xDocProps->getPrintDate(), *ScGlobal::pLocaleData );
+ OUT_COMMENT( aStrOut );
+ }
+ //----------------------------------------------------------
+ }
+ OUT_LF();
+
+ // CSS1 StyleSheet
+ PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_style );
+ rStrm << sMyBegComment; OUT_LF();
+ rStrm << OOO_STRING_SVTOOLS_HTML_body << "," << OOO_STRING_SVTOOLS_HTML_division << "," << OOO_STRING_SVTOOLS_HTML_table << ","
+ << OOO_STRING_SVTOOLS_HTML_thead << "," << OOO_STRING_SVTOOLS_HTML_tbody << "," << OOO_STRING_SVTOOLS_HTML_tfoot << ","
+ << OOO_STRING_SVTOOLS_HTML_tablerow << "," << OOO_STRING_SVTOOLS_HTML_tableheader << ","
+ << OOO_STRING_SVTOOLS_HTML_tabledata << "," << OOO_STRING_SVTOOLS_HTML_parabreak << " { " << sFontFamily;
+ xub_StrLen nFonts = aHTMLStyle.aFontFamilyName.GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ rStrm << '\"';
+ OUT_STR( aHTMLStyle.aFontFamilyName );
+ rStrm << '\"';
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator,
+ // CSS1: Komma als Separator und jeder einzelne Fontname quoted
+ const String& rList = aHTMLStyle.aFontFamilyName;
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ rStrm << '\"';
+ OUT_STR( rList.GetToken( 0, ';', nPos ) );
+ rStrm << '\"';
+ if ( j < nFonts-1 )
+ rStrm << ", ";
+ }
+ }
+ rStrm << "; " << sFontSize
+ << GetFontSizeCss( ( sal_uInt16 ) aHTMLStyle.nFontHeight ) << " }";
+ OUT_LF();
+ rStrm << sMyEndComment;
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
+
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
+}
+
+
+void ScHTMLExport::WriteOverview()
+{
+ if ( nUsedTables > 1 )
+ {
+ IncIndent(1);
+ OUT_HR();
+ IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( ScGlobal::GetRscString( STR_OVERVIEW ) );
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1 );
+
+ String aStr;
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ {
+ pDoc->GetName( nTab, aStr );
+ rStrm << "<A HREF=\"#table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ OUT_STR( aStr );
+ rStrm << "</A>";
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak );
+ }
+ }
+
+ IncIndent(-1); OUT_LF();
+ IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak );
+ }
+}
+
+
+const SfxItemSet& ScHTMLExport::PageDefaults( SCTAB nTab )
+{
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+ DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
+
+ // remember defaults for compare in WriteCell
+ if ( !aHTMLStyle.bInitialized )
+ {
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find(
+ ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
+ SFX_STYLE_FAMILY_PARA );
+ DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
+
+ aHTMLStyle.nDefaultScriptType = ScGlobal::GetDefaultScriptType();
+ aHTMLStyle.aFontFamilyName = ((const SvxFontItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT
+ )))).GetFamilyName();
+ aHTMLStyle.nFontHeight = ((const SvxFontHeightItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT_HEIGHT
+ )))).GetHeight();
+ aHTMLStyle.nFontSizeNumber = GetFontSizeNumber( static_cast< sal_uInt16 >( aHTMLStyle.nFontHeight ) );
+ }
+
+ // Page style sheet printer settings, e.g. for background graphics.
+ // There's only one background graphic in HTML!
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if ( !aHTMLStyle.bInitialized )
+ {
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+ aHTMLStyle.aBackgroundColor = pBrushItem->GetColor();
+ aHTMLStyle.bInitialized = sal_True;
+ }
+ return rSet;
+}
+
+
+void ScHTMLExport::BorderToStyle( ByteString& rOut, const char* pBorderName,
+ const SvxBorderLine* pLine, bool& bInsertSemicolon )
+{
+ if ( pLine )
+ {
+ if ( bInsertSemicolon )
+ rOut += "; ";
+
+ // which border
+ ((rOut += "border-") += pBorderName) += ": ";
+
+ // thickness
+ int nWidth = pLine->GetWidth();
+ int nPxWidth = ( nWidth > 0 )? std::max( int( nWidth / TWIPS_PER_PIXEL ), 1 ): 0;
+ (rOut += ByteString::CreateFromInt32( nPxWidth )) += "px ";
+ switch ( pLine->GetStyle() )
+ {
+ case ::editeng::SOLID: rOut += "solid"; break;
+ case ::editeng::DOTTED: rOut += "dotted"; break;
+ case ::editeng::DASHED: rOut += "dashed"; break;
+ case ::editeng::DOUBLE:
+ case ::editeng::THINTHICK_SMALLGAP:
+ case ::editeng::THINTHICK_MEDIUMGAP:
+ case ::editeng::THINTHICK_LARGEGAP:
+ case ::editeng::THICKTHIN_SMALLGAP:
+ case ::editeng::THICKTHIN_MEDIUMGAP:
+ case ::editeng::THICKTHIN_LARGEGAP:
+ rOut += "double";
+ break;
+ case ::editeng::EMBOSSED: rOut += "ridge"; break;
+ case ::editeng::ENGRAVED: rOut += "groove"; break;
+ case ::editeng::OUTSET: rOut += "outset"; break;
+ case ::editeng::INSET: rOut += "inset"; break;
+ default: rOut += "hidden";
+ }
+ rOut += " #";
+
+ // color
+ char hex[7];
+ snprintf( hex, 7, "%06x", static_cast< unsigned int >( pLine->GetColor().GetRGBColor() ) );
+ hex[6] = 0;
+
+ rOut += hex;
+
+ bInsertSemicolon = true;
+ }
+}
+
+void ScHTMLExport::WriteBody()
+{
+ const SfxItemSet& rSet = PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+
+ // default Textfarbe schwarz
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_body << ' ' << OOO_STRING_SVTOOLS_HTML_O_text << "=\"#000000\"";
+
+ if ( bAll && GPOS_NONE != pBrushItem->GetGraphicPos() )
+ {
+ const String* pLink = pBrushItem->GetGraphicLink();
+ String aGrfNm;
+
+ // embeddete Grafik -> via WriteGraphic schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ aGrfNm = aStreamPath;
+ sal_uInt16 nErr = XOutBitmap::WriteGraphic( *pGrf, aGrfNm,
+ CREATE_STRING( "JPG" ), XOUTBMP_USE_NATIVE_IF_POSSIBLE );
+ if( !nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ pLink = &aGrfNm;
+ }
+ }
+ }
+ else
+ {
+ aGrfNm = *pLink;
+ if( bCopyLocalFileToINet || HasCId() )
+ {
+ CopyLocalFileToINet( aGrfNm, aStreamPath );
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ }
+ else
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ pLink = &aGrfNm;
+ }
+ if( pLink )
+ {
+ rStrm << ' ' << OOO_STRING_SVTOOLS_HTML_O_background << "=\"";
+ OUT_STR( URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL,
+ *pLink ) ) << '\"';
+ }
+ }
+ if ( !aHTMLStyle.aBackgroundColor.GetTransparency() )
+ { // A transparent background color should always result in default
+ // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
+ // black #000000 for COL_AUTO which is the same as white #ffffff with
+ // transparency set to 0xff, our default background.
+ OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor );
+ HTMLOutFuncs::Out_Color( rStrm, aHTMLStyle.aBackgroundColor );
+ }
+
+ rStrm << '>'; OUT_LF();
+
+ if ( bAll )
+ WriteOverview();
+
+ WriteTables();
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
+}
+
+
+void ScHTMLExport::WriteTables()
+{
+ const SCTAB nTabCount = pDoc->GetTableCount();
+ const String aStrTable( ScResId( SCSTR_TABLE ) );
+ String aStr;
+ String aStrOut;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ SCCOL nStartColFix = 0;
+ SCROW nStartRowFix = 0;
+ SCCOL nEndColFix = 0;
+ SCROW nEndRowFix = 0;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( bAll )
+ {
+ nStartTab = 0;
+ nEndTab = nTabCount - 1;
+ }
+ else
+ {
+ nStartCol = nStartColFix = aRange.aStart.Col();
+ nStartRow = nStartRowFix = aRange.aStart.Row();
+ nStartTab = aRange.aStart.Tab();
+ nEndCol = nEndColFix = aRange.aEnd.Col();
+ nEndRow = nEndRowFix = aRange.aEnd.Row();
+ nEndTab = aRange.aEnd.Tab();
+ }
+ SCTAB nTableStrNum = 1;
+ for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
+ {
+ if ( !pDoc->IsVisible( nTab ) )
+ continue; // for
+
+ if ( bAll )
+ {
+ if ( !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+
+ if ( nUsedTables > 1 )
+ {
+ aStrOut = aStrTable;
+ aStrOut.AppendAscii( " " );
+ aStrOut += String::CreateFromInt32( nTableStrNum++ );
+ aStrOut.AppendAscii( ": " );
+
+ OUT_HR();
+
+ // Anker festlegen:
+ rStrm << "<A NAME=\"table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( aStrOut );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis );
+
+ pDoc->GetName( nTab, aStr );
+ OUT_STR( aStr );
+
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis );
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1 );
+ rStrm << "</A>"; OUT_LF();
+ }
+ }
+ else
+ {
+ nStartCol = nStartColFix;
+ nStartRow = nStartRowFix;
+ nEndCol = nEndColFix;
+ nEndRow = nEndRowFix;
+ if ( !TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+ }
+
+ // <TABLE ...>
+ ByteString aByteStrOut = OOO_STRING_SVTOOLS_HTML_table;
+
+ // FRAME=VOID, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_frame) += '=') += OOO_STRING_SVTOOLS_HTML_TF_void;
+
+ bTabHasGraphics = bTabAlignedLeft = false;
+ if ( bAll && pDrawLayer )
+ PrepareGraphics( pDrawLayer, nTab, nStartCol, nStartRow,
+ nEndCol, nEndRow );
+
+ // more <TABLE ...>
+ if ( bTabAlignedLeft )
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ // ALIGN=LEFT allow text and graphics to flow around
+ // CELLSPACING
+ (((aByteStrOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=') +=
+ ByteString::CreateFromInt32( nCellSpacing );
+ // COLS=n
+ SCCOL nColCnt = 0;
+ SCCOL nCol;
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( !pDoc->ColHidden(nCol, nTab) )
+ ++nColCnt;
+ }
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt );
+
+ // RULES=NONE, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_rules) += '=') += OOO_STRING_SVTOOLS_HTML_TR_none;
+
+ // BORDER=0, we do the styling of the cells in <TD>
+ ((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += "=0";
+ IncIndent(1); TAG_ON_LF( aByteStrOut.GetBuffer() );
+
+ // <COLGROUP>
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_colgroup );
+ // <COL WIDTH=x> as pre-info for long tables
+ ByteString aByteStr = OOO_STRING_SVTOOLS_HTML_col;
+ aByteStr += ' ';
+ aByteStr += OOO_STRING_SVTOOLS_HTML_O_width;
+ aByteStr += '=';
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( pDoc->ColHidden(nCol, nTab) )
+ continue; // for
+
+ aByteStrOut = aByteStr;
+ aByteStrOut += ByteString::CreateFromInt32(
+ ToPixel( pDoc->GetColWidth( nCol, nTab ) ) );
+ TAG_ON( aByteStrOut.GetBuffer() );
+ }
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup );
+
+ // <TBODY>
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+ // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
+ // <COL WIDTH=x> specified, but needs a width at every column.
+ bTableDataWidth = sal_True; // widths in first row
+ bool bHasHiddenRows = pDoc->HasHiddenRows(nStartRow, nEndRow, nTab);
+ for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ )
+ {
+ if ( bHasHiddenRows && pDoc->RowHidden(nRow, nTab) )
+ {
+ nRow = pDoc->FirstVisibleRow(nRow+1, nEndRow, nTab);
+ --nRow;
+ continue; // for
+ }
+
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ bTableDataHeight = sal_True; // height at every first cell of each row
+ for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ )
+ {
+ if ( pDoc->ColHidden(nCol2, nTab) )
+ continue; // for
+
+ if ( nCol2 == nEndCol )
+ IncIndent(-1);
+ WriteCell( nCol2, nRow, nTab );
+ bTableDataHeight = false;
+ }
+ bTableDataWidth = false; // widths only in first row
+
+ if ( nRow == nEndRow )
+ IncIndent(-1);
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ }
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
+
+ if ( bTabHasGraphics )
+ {
+ // the rest that is not in a cell
+ size_t ListSize = aGraphList.size();
+ for ( size_t i = 0; i < ListSize; ++i )
+ {
+ ScHTMLGraphEntry* pE = &aGraphList[ i ];
+ if ( !pE->bWritten )
+ WriteGraphEntry( pE );
+ }
+ aGraphList.clear();
+ if ( bTabAlignedLeft )
+ { // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
+ aByteStrOut = OOO_STRING_SVTOOLS_HTML_linebreak;
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ TAG_ON_LF( aByteStrOut.GetBuffer() );
+ }
+ }
+
+ if ( bAll )
+ OUT_COMMENT( CREATE_STRING( "**************************************************************************" ) );
+ }
+}
+
+
+void ScHTMLExport::WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondItemSet = pDoc->GetCondResult( nCol, nRow, nTab );
+
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG, pCondItemSet );
+ if ( rMergeFlagAttr.IsOverlapped() )
+ return ;
+
+ ScAddress aPos( nCol, nRow, nTab );
+ ScHTMLGraphEntry* pGraphEntry = NULL;
+ if ( bTabHasGraphics )
+ {
+ size_t ListSize = aGraphList.size();
+ for ( size_t i = 0; i < ListSize; ++i )
+ {
+ pGraphEntry = &aGraphList[ i ];
+ if ( pGraphEntry->bInCell && pGraphEntry->aRange.In( aPos ) )
+ {
+ if ( pGraphEntry->aRange.aStart == aPos )
+ break; // for
+ else
+ return ; // ist ein Col/RowSpan, Overlapped
+ }
+ }
+ }
+
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ sal_uLong nFormat = pAttr->GetNumberFormat( pFormatter );
+ sal_Bool bValueData;
+ sal_uInt8 nScriptType;
+ if ( pCell )
+ {
+ bValueData = pCell->HasValueData();
+ nScriptType = pDoc->GetScriptType( nCol, nRow, nTab, pCell );
+ }
+ else
+ {
+ bValueData = false;
+ nScriptType = 0;
+ }
+ if ( nScriptType == 0 )
+ nScriptType = aHTMLStyle.nDefaultScriptType;
+
+
+ ByteString aStrTD = OOO_STRING_SVTOOLS_HTML_tabledata;
+
+ // border of the cells
+ SvxBoxItem* pBorder = (SvxBoxItem*) pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER );
+ if ( pBorder && (pBorder->GetTop() || pBorder->GetBottom() || pBorder->GetLeft() || pBorder->GetRight()) )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_style) += "=\"";
+
+ bool bInsertSemicolon = false;
+ BorderToStyle( aStrTD, "top", pBorder->GetTop(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "bottom", pBorder->GetBottom(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "left", pBorder->GetLeft(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "right", pBorder->GetRight(), bInsertSemicolon );
+
+ aStrTD += '"';
+ }
+
+ const sal_Char* pChar;
+ sal_uInt16 nWidthPixel;
+ sal_uInt16 nHeightPixel;
+
+ const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE, pCondItemSet );
+ if ( pGraphEntry || rMergeAttr.IsMerged() )
+ {
+ SCCOL nC, jC;
+ SCROW nR;
+ sal_uLong v;
+ if ( pGraphEntry )
+ nC = Max( SCCOL(pGraphEntry->aRange.aEnd.Col() - nCol + 1),
+ SCCOL(rMergeAttr.GetColMerge()) );
+ else
+ nC = rMergeAttr.GetColMerge();
+ if ( nC > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_colspan) += '=') += ByteString::CreateFromInt32( nC );
+ nC = nC + nCol;
+ for ( jC=nCol, v=0; jC<nC; jC++ )
+ v += pDoc->GetColWidth( jC, nTab );
+ nWidthPixel = ToPixel( static_cast< sal_uInt16 >( v ) );
+ }
+ else
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+
+ if ( pGraphEntry )
+ nR = Max( SCROW(pGraphEntry->aRange.aEnd.Row() - nRow + 1),
+ SCROW(rMergeAttr.GetRowMerge()) );
+ else
+ nR = rMergeAttr.GetRowMerge();
+ if ( nR > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_rowspan) += '=') += ByteString::CreateFromInt32( nR );
+ nR += nRow;
+ v = pDoc->GetRowHeight( nRow, nR-1, nTab );
+ nHeightPixel = ToPixel( static_cast< sal_uInt16 >( v ) );
+ }
+ else
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+ else
+ {
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+
+ if ( bTableDataWidth )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') += ByteString::CreateFromInt32( nWidthPixel );
+ if ( bTableDataHeight )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') += ByteString::CreateFromInt32( nHeightPixel );
+
+ const SvxFontItem& rFontItem = (const SvxFontItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT),
+ pCondItemSet);
+
+ const SvxFontHeightItem& rFontHeightItem = (const SvxFontHeightItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_HEIGHT), pCondItemSet);
+
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT_WEIGHT),
+ pCondItemSet);
+
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_POSTURE), pCondItemSet);
+
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&)
+ pAttr->GetItem( ATTR_FONT_UNDERLINE, pCondItemSet );
+
+ const SvxColorItem& rColorItem = (const SvxColorItem&) pAttr->GetItem(
+ ATTR_FONT_COLOR, pCondItemSet );
+
+ const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)
+ pAttr->GetItem( ATTR_HOR_JUSTIFY, pCondItemSet );
+
+ const SvxVerJustifyItem& rVerJustifyItem = (const SvxVerJustifyItem&)
+ pAttr->GetItem( ATTR_VER_JUSTIFY, pCondItemSet );
+
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&) pAttr->GetItem(
+ ATTR_BACKGROUND, pCondItemSet );
+
+ Color aBgColor;
+ if ( rBrushItem.GetColor().GetTransparency() == 255 )
+ aBgColor = aHTMLStyle.aBackgroundColor; // keine ungewollte Hintergrundfarbe
+ else
+ aBgColor = rBrushItem.GetColor();
+
+ sal_Bool bBold = ( WEIGHT_BOLD <= rWeightItem.GetWeight() );
+ sal_Bool bItalic = ( ITALIC_NONE != rPostureItem.GetPosture() );
+ sal_Bool bUnderline = ( UNDERLINE_NONE != rUnderlineItem.GetLineStyle() );
+ sal_Bool bSetFontColor = ( COL_AUTO != rColorItem.GetValue().GetColor() ); // default is AUTO now
+ sal_Bool bSetFontName = ( aHTMLStyle.aFontFamilyName != rFontItem.GetFamilyName() );
+ sal_uInt16 nSetFontSizeNumber = 0;
+ sal_uInt32 nFontHeight = rFontHeightItem.GetHeight();
+ if ( nFontHeight != aHTMLStyle.nFontHeight )
+ {
+ nSetFontSizeNumber = GetFontSizeNumber( (sal_uInt16) nFontHeight );
+ if ( nSetFontSizeNumber == aHTMLStyle.nFontSizeNumber )
+ nSetFontSizeNumber = 0; // no difference, don't set
+ }
+
+ sal_Bool bSetFont = (bSetFontColor || bSetFontName || nSetFontSizeNumber);
+
+ //! TODO: we could entirely use CSS1 here instead, but that would exclude
+ //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
+ //! Do we want that?
+
+ switch( rHorJustifyItem.GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ pChar = (bValueData ? OOO_STRING_SVTOOLS_HTML_AL_right : OOO_STRING_SVTOOLS_HTML_AL_left);
+ break;
+ case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_AL_center; break;
+ case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
+ case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_HTML_AL_right; break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default: pChar = OOO_STRING_SVTOOLS_HTML_AL_left; break;
+ }
+
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pChar;
+
+ switch( rVerJustifyItem.GetValue() )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case SVX_VER_JUSTIFY_STANDARD:
+ default: pChar = NULL;
+ }
+ if ( pChar )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=') += pChar;
+
+ if ( aHTMLStyle.aBackgroundColor != aBgColor )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
+ lcl_AppendHTMLColorTripel( aStrTD, aBgColor );
+ }
+
+ double fVal = 0.0;
+ if ( bValueData )
+ {
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ fVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && fVal != 0.0 )
+ fVal = pDoc->RoundValueAsShown( fVal, nFormat );
+ break;
+ case CELLTYPE_FORMULA:
+ fVal = ((ScFormulaCell*)pCell)->GetValue();
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = ScGlobal::GetStandardFormat( fVal, *pFormatter,
+ nFormat, ((ScFormulaCell*)pCell)->GetFormatType() );
+ break;
+ default:
+ DBG_ERRORFILE( "value data with unsupported cell type" );
+ }
+ }
+ }
+ HTMLOutFuncs::CreateTableDataOptionsValNum( aStrTD, bValueData, fVal,
+ nFormat, *pFormatter, eDestEnc, &aNonConvertibleChars );
+
+ TAG_ON( aStrTD.GetBuffer() );
+
+ if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
+ if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
+
+
+ if ( bSetFont )
+ {
+ ByteString aStr = OOO_STRING_SVTOOLS_HTML_font;
+ if ( bSetFontName )
+ {
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
+ xub_StrLen nFonts = rFontItem.GetFamilyName().GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML( rFontItem.GetFamilyName(),
+ aTmpStr, eDestEnc, &aNonConvertibleChars );
+ aStr += aTmpStr;
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
+ const String& rList = rFontItem.GetFamilyName();
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML(
+ rList.GetToken( 0, ';', nPos ), aTmpStr, eDestEnc,
+ &aNonConvertibleChars );
+ aStr += aTmpStr;
+ if ( j < nFonts-1 )
+ aStr += ',';
+ }
+ }
+ aStr += '\"';
+ }
+ if ( nSetFontSizeNumber )
+ {
+ (((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
+ += ByteString::CreateFromInt32( nSetFontSizeNumber );
+ }
+ if ( bSetFontColor )
+ {
+ Color aColor = rColorItem.GetValue();
+
+ // always export automatic text color as black
+ if ( aColor.GetColor() == COL_AUTO )
+ aColor.SetColor( COL_BLACK );
+
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ lcl_AppendHTMLColorTripel( aStr, aColor );
+ }
+ TAG_ON( aStr.GetBuffer() );
+ }
+
+ String aStrOut;
+ sal_Bool bFieldText = false;
+ if ( pCell )
+ { // cell content
+ Color* pColor;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_NOTE :
+ // nothing
+ break;
+ case CELLTYPE_EDIT :
+ bFieldText = WriteFieldText( (const ScEditCell*) pCell );
+ if ( bFieldText )
+ break;
+ //! else: fallthru
+ default:
+ ScCellFormat::GetString( pCell, nFormat, aStrOut, &pColor, *pFormatter );
+ }
+ }
+ if ( !bFieldText )
+ {
+ if ( !aStrOut.Len() )
+ {
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // keine komplett leere Zelle
+ }
+ else
+ {
+ xub_StrLen nPos = aStrOut.Search( _LF );
+ if ( nPos == STRING_NOTFOUND )
+ {
+ OUT_STR( aStrOut );
+ }
+ else
+ {
+ xub_StrLen nStartPos = 0;
+ do
+ {
+ String aSingleLine( aStrOut, nStartPos, nPos - nStartPos );
+ OUT_STR( aSingleLine );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ nStartPos = nPos + 1;
+ }
+ while( ( nPos = aStrOut.Search( _LF, nStartPos ) ) != STRING_NOTFOUND );
+ String aSingleLine( aStrOut, nStartPos, aStrOut.Len() - nStartPos );
+ OUT_STR( aSingleLine );
+ }
+ }
+ }
+ if ( pGraphEntry )
+ WriteGraphEntry( pGraphEntry );
+
+ if ( bSetFont ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
+ if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
+ if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata );
+}
+
+
+sal_Bool ScHTMLExport::WriteFieldText( const ScEditCell* pCell )
+{
+ sal_Bool bFields = false;
+ const EditTextObject* pData;
+ pCell->GetData( pData );
+ // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ sal_uInt16 nParas = rEngine.GetParagraphCount();
+ if ( nParas )
+ {
+ ESelection aSel( 0, 0, nParas-1, rEngine.GetTextLen( nParas-1 ) );
+ SfxItemSet aSet( rEngine.GetAttribs( aSel ) );
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, false );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bFields = sal_True;
+ }
+ if ( bFields )
+ {
+ sal_Bool bOldUpdateMode = rEngine.GetUpdateMode();
+ rEngine.SetUpdateMode( sal_True ); // no portions if not formatted
+ for ( sal_uInt16 nPar=0; nPar < nParas; nPar++ )
+ {
+ if ( nPar > 0 )
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ SvUShorts aPortions;
+ rEngine.GetPortions( nPar, aPortions );
+ sal_uInt16 nCnt = aPortions.Count();
+ sal_uInt16 nStart = 0;
+ for ( sal_uInt16 nPos = 0; nPos < nCnt; nPos++ )
+ {
+ sal_uInt16 nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ sal_Bool bUrl = false;
+ // fields are single characters
+ if ( nEnd == nStart+1 )
+ {
+ const SfxPoolItem* pItem;
+ SfxItemSet aSet = rEngine.GetAttribs( aSel );
+ if ( aSet.GetItemState( EE_FEATURE_FIELD, false, &pItem ) == SFX_ITEM_ON )
+ {
+ const SvxFieldData* pField = ((const SvxFieldItem*)pItem)->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ bUrl = sal_True;
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+// String aFieldText = rEngine.GetText( aSel );
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_anchor << ' ' << OOO_STRING_SVTOOLS_HTML_O_href << "=\"";
+ OUT_STR( pURLField->GetURL() );
+ rStrm << "\">";
+ OUT_STR( pURLField->GetRepresentation() );
+ rStrm << "</" << OOO_STRING_SVTOOLS_HTML_anchor << '>';
+ }
+ }
+ }
+ if ( !bUrl )
+ OUT_STR( rEngine.GetText( aSel ) );
+ nStart = nEnd;
+ }
+ }
+ rEngine.SetUpdateMode( bOldUpdateMode );
+ }
+ return bFields;
+}
+
+
+sal_Bool ScHTMLExport::CopyLocalFileToINet( String& rFileNm,
+ const String& rTargetNm, sal_Bool bFileToFile )
+{
+ sal_Bool bRet = false;
+ INetURLObject aFileUrl, aTargetUrl;
+ aFileUrl.SetSmartURL( rFileNm );
+ aTargetUrl.SetSmartURL( rTargetNm );
+ if( INET_PROT_FILE == aFileUrl.GetProtocol() &&
+ ( (bFileToFile && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
+ (!bFileToFile && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
+ INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
+ INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
+ {
+ if( pSrcArr )
+ {
+ // wurde die Datei schon verschoben
+ sal_uInt16 nPos;
+ if( pSrcArr->Seek_Entry( &rFileNm, &nPos ))
+ {
+ rFileNm = *(*pDestArr)[ nPos ];
+ return sal_True;
+ }
+ }
+ else
+ {
+ pSrcArr = new SvStringsSortDtor( 4, 4 );
+ pDestArr = new SvStringsSortDtor( 4, 4 );
+ }
+
+ String* pSrc = new String( rFileNm );
+ SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
+
+ String* pDest = new String( aTargetUrl.GetPartBeforeLastName() );
+ *pDest += String(aFileUrl.GetName());
+
+ if( bFileToFile )
+ {
+ INetURLObject aCpyURL( *pDest );
+ SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
+ aCpy << aTmp;
+
+ aCpy.Close();
+ bRet = SVSTREAM_OK == aCpy.GetError();
+ }
+ else
+ {
+ SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
+ false );
+
+ {
+ SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
+ aCpy << aTmp;
+ }
+
+ // uebertragen
+ aMedium.Close();
+ aMedium.Commit();
+
+ bRet = 0 == aMedium.GetError();
+ }
+
+ if( bRet )
+ {
+ pSrcArr->Insert( pSrc );
+ pDestArr->Insert( pDest );
+ rFileNm = *pDest;
+ }
+ else
+ {
+ delete pSrc;
+ delete pDest;
+ }
+ }
+
+ return bRet;
+}
+
+
+void ScHTMLExport::MakeCIdURL( String& rURL )
+{
+ if( !aCId.Len() )
+ return;
+
+ INetURLObject aURLObj( rURL );
+ if( INET_PROT_FILE != aURLObj.GetProtocol() )
+ return;
+
+ String aLastName( aURLObj.GetLastName() );
+ DBG_ASSERT( aLastName.Len(), "Dateiname ohne Laenge!" );
+ aLastName.ToLowerAscii();
+
+ rURL.AssignAscii( "cid:" );
+ rURL += aLastName;
+ rURL.AppendAscii( "." );
+ rURL += aCId;
+}
+
+
+void ScHTMLExport::IncIndent( short nVal )
+{
+ sIndent[nIndent] = '\t';
+ nIndent = nIndent + nVal;
+ if ( nIndent < 0 )
+ nIndent = 0;
+ else if ( nIndent > nIndentMax )
+ nIndent = nIndentMax;
+ sIndent[nIndent] = 0;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/html/htmlexp2.cxx b/sc/source/filter/html/htmlexp2.cxx
new file mode 100644
index 000000000000..0100c1d9d258
--- /dev/null
+++ b/sc/source/filter/html/htmlexp2.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/xoutbmp.hxx>
+#include <svx/svdxcgv.hxx>
+#include <sot/exchange.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/transfer.hxx>
+#include <svtools/embedtransfer.hxx>
+#include <svl/urihelper.hxx>
+#include <tools/urlobj.hxx>
+
+#include "htmlexp.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "ftools.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+void ScHTMLExport::PrepareGraphics( ScDrawLayer* pDrawLayer, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if ( pDrawLayer->HasObjectsInRows( nTab, nStartRow, nEndRow ) )
+ {
+ SdrPage* pDrawPage = pDrawLayer->GetPage( static_cast<sal_uInt16>(nTab) );
+ if ( pDrawPage )
+ {
+ bTabHasGraphics = true;
+ FillGraphList( pDrawPage, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ size_t ListSize = aGraphList.size();
+ for ( size_t i = 0; i < ListSize; ++i )
+ {
+ ScHTMLGraphEntry* pE = &aGraphList[ i ];
+ if ( !pE->bInCell )
+ { // nicht alle in Zellen: einige neben Tabelle
+ bTabAlignedLeft = sal_True;
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void ScHTMLExport::FillGraphList( const SdrPage* pPage, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ sal_uLong nObjCount = pPage->GetObjCount();
+ if ( nObjCount )
+ {
+ Rectangle aRect;
+ if ( !bAll )
+ aRect = pDoc->GetMMRect( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+ SdrObjListIter aIter( *pPage, IM_FLAT );
+ SdrObject* pObject = aIter.Next();
+ while ( pObject )
+ {
+ Rectangle aObjRect = pObject->GetCurrentBoundRect();
+ if ( bAll || aRect.IsInside( aObjRect ) )
+ {
+ Size aSpace;
+ ScRange aR = pDoc->GetRange( nTab, aObjRect );
+ // Rectangle in mm/100
+ Size aSize( MMToPixel( aObjRect.GetSize() ) );
+ // If the image is somewhere in a merged range we must
+ // move the anchor to the upper left (THE span cell).
+ pDoc->ExtendOverlapped( aR );
+ SCCOL nCol1 = aR.aStart.Col();
+ SCROW nRow1 = aR.aStart.Row();
+ SCCOL nCol2 = aR.aEnd.Col();
+ SCROW nRow2 = aR.aEnd.Row();
+ // All cells empty under object?
+ sal_Bool bInCell = (pDoc->GetEmptyLinesInBlock(
+ nCol1, nRow1, nTab, nCol2, nRow2, nTab, DIR_TOP )
+ == static_cast< SCSIZE >( nRow2 - nRow1 )); // rows-1 !
+ if ( bInCell )
+ { // Spacing in spanning cell
+ Rectangle aCellRect = pDoc->GetMMRect(
+ nCol1, nRow1, nCol2, nRow2, nTab );
+ aSpace = MMToPixel( Size(
+ aCellRect.GetWidth() - aObjRect.GetWidth(),
+ aCellRect.GetHeight() - aObjRect.GetHeight() ));
+ aSpace.Width() += (nCol2-nCol1) * (nCellSpacing+1);
+ aSpace.Height() += (nRow2-nRow1) * (nCellSpacing+1);
+ aSpace.Width() /= 2;
+ aSpace.Height() /= 2;
+ }
+ ScHTMLGraphEntry* pE = new ScHTMLGraphEntry( pObject,
+ aR, aSize, bInCell, aSpace );
+ aGraphList.push_back( pE );
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+
+
+void ScHTMLExport::WriteGraphEntry( ScHTMLGraphEntry* pE )
+{
+ SdrObject* pObject = pE->pObject;
+ ByteString aOpt;
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') +=
+ ByteString::CreateFromInt32( pE->aSize.Width() );
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') +=
+ ByteString::CreateFromInt32( pE->aSize.Height() );
+ if ( pE->bInCell )
+ {
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=') +=
+ ByteString::CreateFromInt32( pE->aSpace.Width() );
+ (((aOpt += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=') +=
+ ByteString::CreateFromInt32( pE->aSpace.Height() );
+ }
+ switch ( pObject->GetObjIdentifier() )
+ {
+ case OBJ_GRAF:
+ {
+ const SdrGrafObj* pSGO = (SdrGrafObj*)pObject;
+ const SdrGrafObjGeoData* pGeo = (SdrGrafObjGeoData*)pSGO->GetGeoData();
+ sal_uInt16 nMirrorCase = (pGeo->aGeo.nDrehWink == 18000 ?
+ ( pGeo->bMirrored ? 3 : 4 ) : ( pGeo->bMirrored ? 2 : 1 ));
+ sal_Bool bHMirr = ( ( nMirrorCase == 2 ) || ( nMirrorCase == 4 ) );
+ sal_Bool bVMirr = ( ( nMirrorCase == 3 ) || ( nMirrorCase == 4 ) );
+ sal_uLong nXOutFlags = 0;
+ if ( bHMirr )
+ nXOutFlags |= XOUTBMP_MIRROR_HORZ;
+ if ( bVMirr )
+ nXOutFlags |= XOUTBMP_MIRROR_VERT;
+ String aLinkName;
+ if ( pSGO->IsLinkedGraphic() )
+ aLinkName = pSGO->GetFileName();
+ WriteImage( aLinkName, pSGO->GetGraphic(), aOpt, nXOutFlags );
+ pE->bWritten = sal_True;
+ }
+ break;
+ case OBJ_OLE2:
+ {
+ Graphic* pGraphic = ((SdrOle2Obj*)pObject)->GetGraphic();
+ if ( pGraphic )
+ {
+ String aLinkName;
+ WriteImage( aLinkName, *pGraphic, aOpt );
+ pE->bWritten = sal_True;
+ }
+ }
+ break;
+ default:
+ {
+ Graphic aGraph( SdrExchangeView::GetObjGraphic(
+ pDoc->GetDrawLayer(), pObject ) );
+ String aLinkName;
+ WriteImage( aLinkName, aGraph, aOpt );
+ pE->bWritten = sal_True;
+ }
+ }
+}
+
+
+void ScHTMLExport::WriteImage( String& rLinkName, const Graphic& rGrf,
+ const ByteString& rImgOptions, sal_uLong nXOutFlags )
+{
+ // embeddete Grafik -> via WriteGraphic schreiben
+ if( !rLinkName.Len() )
+ {
+ if( aStreamPath.Len() > 0 )
+ {
+ // Grafik als (JPG-)File speichern
+ String aGrfNm( aStreamPath );
+ nXOutFlags |= XOUTBMP_USE_NATIVE_IF_POSSIBLE;
+ sal_uInt16 nErr = XOutBitmap::WriteGraphic( rGrf, aGrfNm,
+ CREATE_STRING( "JPG" ), nXOutFlags );
+ if( !nErr ) // sonst fehlerhaft, da ist nichts auszugeben
+ {
+ rLinkName = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm,
+ URIHelper::GetMaybeFileHdl());
+ if ( HasCId() )
+ MakeCIdURL( rLinkName );
+ }
+ }
+ }
+ else
+ {
+ if( bCopyLocalFileToINet || HasCId() )
+ {
+ CopyLocalFileToINet( rLinkName, aStreamPath );
+ if ( HasCId() )
+ MakeCIdURL( rLinkName );
+ }
+ else
+ rLinkName = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ rLinkName,
+ URIHelper::GetMaybeFileHdl());
+ }
+ if( rLinkName.Len() )
+ { // <IMG SRC="..."[ rImgOptions]>
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_image << ' ' << OOO_STRING_SVTOOLS_HTML_O_src << "=\"";
+ HTMLOutFuncs::Out_String( rStrm, URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL,
+ rLinkName ), eDestEnc ) << '\"';
+ if ( rImgOptions.Len() )
+ rStrm << rImgOptions.GetBuffer();
+ rStrm << '>' << sNewLine << GetIndentStr();
+ }
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx
new file mode 100644
index 000000000000..5bae367a3f65
--- /dev/null
+++ b/sc/source/filter/html/htmlimp.cxx
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/lrspitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <vcl/svapp.hxx>
+
+#include "htmlimp.hxx"
+#include "htmlpars.hxx"
+#include "filter.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "compiler.hxx"
+#include "rangenam.hxx"
+#include "attrib.hxx"
+#include "ftools.hxx"
+#include "tokenarray.hxx"
+
+
+//------------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc,
+ ScRange& rRange, double nOutputFactor, sal_Bool bCalcWidthHeight, SvNumberFormatter* pFormatter,
+ bool bConvertDate )
+{
+ ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight );
+ FltError nErr = (FltError) aImp.Read( rStream, rBaseURL );
+ ScRange aR = aImp.GetRange();
+ rRange.aEnd = aR.aEnd;
+ aImp.WriteToDocument( sal_True, nOutputFactor, pFormatter, bConvertDate );
+ return nErr;
+}
+
+ScEEAbsImport *ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight )
+{
+ return new ScHTMLImport( pDocP, rBaseURL, rRange, bCalcWidthHeight );
+}
+
+ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight ) :
+ ScEEImport( pDocP, rRange )
+{
+ Size aPageSize;
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ const String& aPageStyle = mpDoc->GetPageStyle( rRange.aStart.Tab() );
+ ScStyleSheet* pStyleSheet = (ScStyleSheet*)mpDoc->
+ GetStyleSheetPool()->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &rSet.Get( ATTR_LRSPACE );
+ long nLeftMargin = pLRItem->GetLeft();
+ long nRightMargin = pLRItem->GetRight();
+ const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &rSet.Get( ATTR_ULSPACE );
+ long nTopMargin = pULItem->GetUpper();
+ long nBottomMargin = pULItem->GetLower();
+ aPageSize = ((const SvxSizeItem&) rSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ if ( !aPageSize.Width() || !aPageSize.Height() )
+ {
+ DBG_ERRORFILE("PageSize Null ?!?!?");
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
+ }
+ aPageSize.Width() -= nLeftMargin + nRightMargin;
+ aPageSize.Height() -= nTopMargin + nBottomMargin;
+ aPageSize = pDefaultDev->LogicToPixel( aPageSize, MapMode( MAP_TWIP ) );
+ }
+ else
+ {
+ DBG_ERRORFILE("kein StyleSheet?!?");
+ aPageSize = pDefaultDev->LogicToPixel(
+ SvxPaperInfo::GetPaperSize( PAPER_A4 ), MapMode( MAP_TWIP ) );
+ }
+ if( bCalcWidthHeight )
+ mpParser = new ScHTMLLayoutParser( mpEngine, rBaseURL, aPageSize, pDocP );
+ else
+ mpParser = new ScHTMLQueryParser( mpEngine, pDocP );
+}
+
+
+ScHTMLImport::~ScHTMLImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete (ScHTMLParser*) mpParser; // vor EditEngine!
+}
+
+
+void ScHTMLImport::InsertRangeName( ScDocument* pDoc, const String& rName, const ScRange& rRange )
+{
+ ScComplexRefData aRefData;
+ aRefData.InitRange( rRange );
+ ScTokenArray aTokArray;
+ aTokArray.AddDoubleReference( aRefData );
+ ScRangeData* pRangeData = new ScRangeData( pDoc, rName, aTokArray );
+ if( !pDoc->GetRangeName()->insert( pRangeData ) )
+ delete pRangeData;
+}
+
+void ScHTMLImport::WriteToDocument(
+ sal_Bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
+{
+ ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate );
+
+ const ScHTMLParser* pParser = GetParser();
+ const ScHTMLTable* pGlobTable = pParser->GetGlobalTable();
+ if( !pGlobTable )
+ return;
+
+ // set cell borders for HTML table cells
+ pGlobTable->ApplyCellBorders( mpDoc, maRange.aStart );
+
+ // correct cell borders for merged cells
+ size_t ListSize = pParser->ListSize();
+ for ( size_t i = 0; i < ListSize; ++i )
+ {
+ const ScEEParseEntry* pEntry = pParser->ListEntry( i );
+ if( (pEntry->nColOverlap > 1) || (pEntry->nRowOverlap > 1) )
+ {
+ SCTAB nTab = maRange.aStart.Tab();
+ const ScMergeAttr* pItem = (ScMergeAttr*) mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_MERGE );
+ if( pItem->IsMerged() )
+ {
+ SCCOL nColMerge = pItem->GetColMerge();
+ SCROW nRowMerge = pItem->GetRowMerge();
+
+ const SvxBoxItem* pToItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_BORDER );
+ SvxBoxItem aNewItem( *pToItem );
+ if( nColMerge > 1 )
+ {
+ const SvxBoxItem* pFromItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol + nColMerge - 1, pEntry->nRow, nTab, ATTR_BORDER );
+ aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_RIGHT ), BOX_LINE_RIGHT );
+ }
+ if( nRowMerge > 1 )
+ {
+ const SvxBoxItem* pFromItem = (const SvxBoxItem*)
+ mpDoc->GetAttr( pEntry->nCol, pEntry->nRow + nRowMerge - 1, nTab, ATTR_BORDER );
+ aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_BOTTOM ), BOX_LINE_BOTTOM );
+ }
+ mpDoc->ApplyAttr( pEntry->nCol, pEntry->nRow, nTab, aNewItem );
+ }
+ }
+ }
+
+ // create ranges for HTML tables
+ // 1 - entire document
+ ScRange aNewRange( maRange.aStart );
+ aNewRange.aEnd.IncCol( static_cast<SCsCOL>(pGlobTable->GetDocSize( tdCol )) - 1 );
+ aNewRange.aEnd.IncRow( pGlobTable->GetDocSize( tdRow ) - 1 );
+ InsertRangeName( mpDoc, ScfTools::GetHTMLDocName(), aNewRange );
+
+ // 2 - all tables
+ InsertRangeName( mpDoc, ScfTools::GetHTMLTablesName(), ScRange( maRange.aStart ) );
+
+ // 3 - single tables
+ SCsCOL nColDiff = (SCsCOL)maRange.aStart.Col();
+ SCsROW nRowDiff = (SCsROW)maRange.aStart.Row();
+ SCsTAB nTabDiff = (SCsTAB)maRange.aStart.Tab();
+
+ ScHTMLTable* pTable = NULL;
+ ScHTMLTableId nTableId = SC_HTML_GLOBAL_TABLE;
+ while( (pTable = pGlobTable->FindNestedTable( ++nTableId )) != 0 )
+ {
+ pTable->GetDocRange( aNewRange );
+ aNewRange.Move( nColDiff, nRowDiff, nTabDiff );
+ // insert table number as name
+ InsertRangeName( mpDoc, ScfTools::GetNameFromHTMLIndex( nTableId ), aNewRange );
+ // insert table id as name
+ if( pTable->GetTableName().Len() )
+ {
+ String aName( ScfTools::GetNameFromHTMLName( pTable->GetTableName() ) );
+ if (!mpDoc->GetRangeName()->findByName(aName))
+ InsertRangeName( mpDoc, aName, aNewRange );
+ }
+ }
+}
+
+String ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
+{
+ return ScHTMLImport::GetHTMLRangeNameList( pDoc, rOrigName );
+}
+
+String ScHTMLImport::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
+{
+ DBG_ASSERT( pDoc, "ScHTMLImport::GetHTMLRangeNameList - missing document" );
+
+ String aNewName;
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ ScRangeList aRangeList;
+ xub_StrLen nTokenCnt = rOrigName.GetTokenCount( ';' );
+ xub_StrLen nStringIx = 0;
+ for( xub_StrLen nToken = 0; nToken < nTokenCnt; nToken++ )
+ {
+ String aToken( rOrigName.GetToken( 0, ';', nStringIx ) );
+ if( pRangeNames && ScfTools::IsHTMLTablesName( aToken ) )
+ { // build list with all HTML tables
+ sal_uLong nIndex = 1;
+ bool bLoop = true;
+ while( bLoop )
+ {
+ aToken = ScfTools::GetNameFromHTMLIndex( nIndex++ );
+ const ScRangeData* pRangeData = pRangeNames->findByName(aToken);
+ if (pRangeData)
+ {
+ ScRange aRange;
+ if( pRangeData->IsReference( aRange ) && !aRangeList.In( aRange ) )
+ {
+ ScGlobal::AddToken( aNewName, aToken, ';' );
+ aRangeList.Append( aRange );
+ }
+ }
+ else
+ bLoop = false;
+ }
+ }
+ else
+ ScGlobal::AddToken( aNewName, aToken, ';' );
+ }
+ return aNewName;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
new file mode 100644
index 000000000000..10c4a5b83684
--- /dev/null
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -0,0 +1,3002 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+#define SC_HTMLPARS_CXX
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svtools/htmlcfg.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/eitem.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/parhtml.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <sfx2/docfile.hxx>
+
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/tenccvt.hxx>
+
+#include "htmlpars.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "rangelst.hxx"
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+using ::editeng::SvxBorderLine;
+using namespace ::com::sun::star;
+
+
+SV_IMPL_VARARR_SORT( ScHTMLColOffset, sal_uLong );
+
+
+// ============================================================================
+// BASE class for HTML parser classes
+// ============================================================================
+
+ScHTMLParser::ScHTMLParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
+ ScEEParser( pEditEngine ),
+ mpDoc( pDoc )
+{
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ for( sal_uInt16 nIndex = 0; nIndex < SC_HTML_FONTSIZES; ++nIndex )
+ maFontHeights[ nIndex ] = pHtmlOptions->GetFontSize( nIndex ) * 20;
+}
+
+ScHTMLParser::~ScHTMLParser()
+{
+}
+
+
+// ============================================================================
+
+ScHTMLLayoutParser::ScHTMLLayoutParser( EditEngine* pEditP, const String& rBaseURL, const Size& aPageSizeP, ScDocument* pDocP ) :
+ ScHTMLParser( pEditP, pDocP ),
+ aPageSize( aPageSizeP ),
+ aBaseURL( rBaseURL ),
+ xLockedList( new ScRangeList ),
+ pTables( NULL ),
+ pColOffset( new ScHTMLColOffset ),
+ pLocalColOffset( new ScHTMLColOffset ),
+ nFirstTableCell(0),
+ nTableLevel(0),
+ nTable(0),
+ nMaxTable(0),
+ nColCntStart(0),
+ nMaxCol(0),
+ nTableWidth(0),
+ nColOffset(0),
+ nColOffsetStart(0),
+ nMetaCnt(0),
+ nOffsetTolerance( SC_HTML_OFFSET_TOLERANCE_SMALL ),
+ bTabInTabCell( false ),
+ bFirstRow( sal_True ),
+ bInCell( false ),
+ bInTitle( false )
+{
+ MakeColNoRef( pLocalColOffset, 0, 0, 0, 0 );
+ MakeColNoRef( pColOffset, 0, 0, 0, 0 );
+}
+
+
+ScHTMLLayoutParser::~ScHTMLLayoutParser()
+{
+ ScHTMLTableStackEntry* pS;
+ while ( (pS = aTableStack.Pop()) != 0 )
+ {
+ bool found = false;
+ for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ if ( pS->pCellEntry == maList[ i ] )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ delete pS->pCellEntry;
+ if ( pS->pLocalColOffset != pLocalColOffset )
+ delete pS->pLocalColOffset;
+ delete pS;
+ }
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ if ( pColOffset )
+ delete pColOffset;
+ if ( pTables )
+ {
+ for ( Table* pT = (Table*) pTables->First(); pT; pT = (Table*) pTables->Next() )
+ delete pT;
+ delete pTables;
+ }
+}
+
+
+sal_uLong ScHTMLLayoutParser::Read( SvStream& rStream, const String& rBaseURL )
+{
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScHTMLLayoutParser, HTMLImportHdl ) );
+
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ sal_Bool bLoading = pObjSh && pObjSh->IsLoading();
+
+ SvKeyValueIteratorRef xValues;
+ SvKeyValueIterator* pAttributes = NULL;
+ if ( bLoading )
+ pAttributes = pObjSh->GetHeaderAttributes();
+ else
+ {
+ // When not loading, set up fake http headers to force the SfxHTMLParser to use UTF8
+ // (used when pasting from clipboard)
+
+ const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
+ if( pCharSet )
+ {
+ String aContentType = String::CreateFromAscii( "text/html; charset=" );
+ aContentType.AppendAscii( pCharSet );
+
+ xValues = new SvKeyValueIterator;
+ xValues->Append( SvKeyValue( String::CreateFromAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
+ pAttributes = xValues;
+ }
+ }
+
+ sal_uLong nErr = pEdit->Read( rStream, rBaseURL, EE_FORMAT_HTML, pAttributes );
+
+ pEdit->SetImportHdl( aOldLink );
+ // Spaltenbreiten erzeugen
+ Adjust();
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ sal_uInt16 nCount = pColOffset->Count();
+ const sal_uLong* pOff = (const sal_uLong*) pColOffset->GetData();
+ sal_uLong nOff = *pOff++;
+ Size aSize;
+ for ( sal_uInt16 j = 1; j < nCount; j++, pOff++ )
+ {
+ aSize.Width() = *pOff - nOff;
+ aSize = pDefaultDev->PixelToLogic( aSize, MapMode( MAP_TWIP ) );
+ pColWidths->Insert( j-1, (void*)aSize.Width() );
+ nOff = *pOff;
+ }
+ return nErr;
+}
+
+
+const ScHTMLTable* ScHTMLLayoutParser::GetGlobalTable() const
+{
+ return 0;
+}
+
+
+void ScHTMLLayoutParser::NewActEntry( ScEEParseEntry* pE )
+{
+ ScEEParser::NewActEntry( pE );
+ if ( pE )
+ {
+ if ( !pE->aSel.HasRange() )
+ { // komplett leer, nachfolgender Text landet im gleichen Absatz!
+ pActEntry->aSel.nStartPara = pE->aSel.nEndPara;
+ pActEntry->aSel.nStartPos = pE->aSel.nEndPos;
+ }
+ }
+ pActEntry->aSel.nEndPara = pActEntry->aSel.nStartPara;
+ pActEntry->aSel.nEndPos = pActEntry->aSel.nStartPos;
+}
+
+
+void ScHTMLLayoutParser::EntryEnd( ScEEParseEntry* pE, const ESelection& rSel )
+{
+ if ( rSel.nEndPara >= pE->aSel.nStartPara )
+ {
+ pE->aSel.nEndPara = rSel.nEndPara;
+ pE->aSel.nEndPos = rSel.nEndPos;
+ }
+ else if ( rSel.nStartPara == pE->aSel.nStartPara - 1 && !pE->aSel.HasRange() )
+ { // kein Absatz angehaengt aber leer, nichts tun
+ }
+ else
+ {
+ DBG_ERRORFILE( "EntryEnd: EditEngine ESelection End < Start" );
+ }
+}
+
+
+void ScHTMLLayoutParser::NextRow( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( nRowMax < ++nRowCnt )
+ nRowMax = nRowCnt;
+ nColCnt = nColCntStart;
+ nColOffset = nColOffsetStart;
+ bFirstRow = false;
+}
+
+
+sal_Bool ScHTMLLayoutParser::SeekOffset( ScHTMLColOffset* pOffset, sal_uInt16 nOffset,
+ SCCOL* pCol, sal_uInt16 nOffsetTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::SeekOffset - illegal call" );
+ sal_uInt16 nPos;
+ sal_Bool bFound = pOffset->Seek_Entry( nOffset, &nPos );
+ *pCol = static_cast<SCCOL>(nPos);
+ if ( bFound )
+ return sal_True;
+ sal_uInt16 nCount = pOffset->Count();
+ if ( !nCount )
+ return false;
+ // nPos ist Einfuegeposition, da liegt der Naechsthoehere (oder auch nicht)
+ if ( nPos < nCount && (((*pOffset)[nPos] - nOffsetTol) <= nOffset) )
+ return sal_True;
+ // nicht kleiner als alles andere? dann mit Naechstniedrigerem vergleichen
+ else if ( nPos && (((*pOffset)[nPos-1] + nOffsetTol) >= nOffset) )
+ {
+ (*pCol)--;
+ return sal_True;
+ }
+ return false;
+}
+
+
+void ScHTMLLayoutParser::MakeCol( ScHTMLColOffset* pOffset, sal_uInt16& nOffset,
+ sal_uInt16& nWidth, sal_uInt16 nOffsetTol, sal_uInt16 nWidthTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::MakeCol - illegal call" );
+ SCCOL nPos;
+ if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
+ nOffset = (sal_uInt16)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nOffset );
+ if ( nWidth )
+ {
+ if ( SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
+ nWidth = (sal_uInt16)(*pOffset)[nPos] - nOffset;
+ else
+ pOffset->Insert( nOffset + nWidth );
+ }
+}
+
+
+void ScHTMLLayoutParser::MakeColNoRef( ScHTMLColOffset* pOffset, sal_uInt16 nOffset,
+ sal_uInt16 nWidth, sal_uInt16 nOffsetTol, sal_uInt16 nWidthTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::MakeColNoRef - illegal call" );
+ SCCOL nPos;
+ if ( SeekOffset( pOffset, nOffset, &nPos, nOffsetTol ) )
+ nOffset = (sal_uInt16)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nOffset );
+ if ( nWidth )
+ {
+ if ( !SeekOffset( pOffset, nOffset + nWidth, &nPos, nWidthTol ) )
+ pOffset->Insert( nOffset + nWidth );
+ }
+}
+
+
+void ScHTMLLayoutParser::ModifyOffset( ScHTMLColOffset* pOffset, sal_uInt16& nOldOffset,
+ sal_uInt16& nNewOffset, sal_uInt16 nOffsetTol )
+{
+ DBG_ASSERT( pOffset, "ScHTMLLayoutParser::ModifyOffset - illegal call" );
+ SCCOL nPos;
+ if ( !SeekOffset( pOffset, nOldOffset, &nPos, nOffsetTol ) )
+ {
+ if ( SeekOffset( pOffset, nNewOffset, &nPos, nOffsetTol ) )
+ nNewOffset = (sal_uInt16)(*pOffset)[nPos];
+ else
+ pOffset->Insert( nNewOffset );
+ return ;
+ }
+ nOldOffset = (sal_uInt16)(*pOffset)[nPos];
+ SCCOL nPos2;
+ if ( SeekOffset( pOffset, nNewOffset, &nPos2, nOffsetTol ) )
+ {
+ nNewOffset = (sal_uInt16)(*pOffset)[nPos2];
+ return ;
+ }
+ sal_uLong* pData = ((sal_uLong*) pOffset->GetData()) + nPos; //! QAD
+ long nDiff = nNewOffset - nOldOffset;
+ if ( nDiff < 0 )
+ {
+ const sal_uLong* pStop = pOffset->GetData();
+ do
+ {
+ *pData += nDiff;
+ } while ( pStop < pData-- );
+ }
+ else
+ {
+ const sal_uLong* pStop = pOffset->GetData() + pOffset->Count();
+ do
+ {
+ *pData += nDiff;
+ } while ( ++pData < pStop );
+ }
+}
+
+
+void ScHTMLLayoutParser::SkipLocked( ScEEParseEntry* pE, sal_Bool bJoin )
+{
+ if ( ValidCol(pE->nCol) )
+ { // wuerde sonst bei ScAddress falschen Wert erzeugen, evtl. Endlosschleife!
+ sal_Bool bBadCol = false;
+ sal_Bool bAgain;
+ ScRange aRange( pE->nCol, pE->nRow, 0,
+ pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 );
+ do
+ {
+ bAgain = false;
+ for ( size_t i = 0, nRanges = xLockedList->size(); i < nRanges; ++i )
+ {
+ ScRange* pR = (*xLockedList)[i];
+ if ( pR->Intersects( aRange ) )
+ {
+ pE->nCol = pR->aEnd.Col() + 1;
+ SCCOL nTmp = pE->nCol + pE->nColOverlap - 1;
+ if ( pE->nCol > MAXCOL || nTmp > MAXCOL )
+ bBadCol = sal_True;
+ else
+ {
+ bAgain = sal_True;
+ aRange.aStart.SetCol( pE->nCol );
+ aRange.aEnd.SetCol( nTmp );
+ }
+ break;
+ }
+ }
+ } while ( bAgain );
+ if ( bJoin && !bBadCol )
+ xLockedList->Join( aRange );
+ }
+}
+
+
+void ScHTMLLayoutParser::Adjust()
+{
+ xLockedList->RemoveAll();
+
+ ScHTMLAdjustStack aStack;
+ ScHTMLAdjustStackEntry* pS;
+ sal_uInt16 nTab = 0;
+ SCCOL nLastCol = SCCOL_MAX;
+ SCROW nNextRow = 0;
+ SCROW nCurRow = 0;
+ sal_uInt16 nPageWidth = (sal_uInt16) aPageSize.Width();
+ Table* pTab = NULL;
+ for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ ScEEParseEntry* pE = maList[ i ];
+ if ( pE->nTab < nTab )
+ { // Table beendet
+ if ( (pS = aStack.Pop()) != 0 )
+ {
+ nLastCol = pS->nLastCol;
+ nNextRow = pS->nNextRow;
+ nCurRow = pS->nCurRow;
+ }
+ delete pS;
+ nTab = pE->nTab;
+ pTab = (pTables ? (Table*) pTables->Get( nTab ) : NULL);
+
+ }
+ SCROW nRow = pE->nRow;
+ if ( pE->nCol <= nLastCol )
+ { // naechste Zeile
+ if ( pE->nRow < nNextRow )
+ pE->nRow = nCurRow = nNextRow;
+ else
+ nCurRow = nNextRow = pE->nRow;
+ SCROW nR;
+ if ( pTab && ((nR = (SCROW)(sal_uLong)pTab->Get( nCurRow )) != 0) )
+ nNextRow += nR;
+ else
+ nNextRow++;
+ }
+ else
+ pE->nRow = nCurRow;
+ nLastCol = pE->nCol; // eingelesene Col
+ if ( pE->nTab > nTab )
+ { // neue Table
+ aStack.Push( new ScHTMLAdjustStackEntry(
+ nLastCol, nNextRow, nCurRow ) );
+ nTab = pE->nTab;
+ pTab = (pTables ? (Table*) pTables->Get( nTab ) : NULL);
+ // neuer Zeilenabstand
+ SCROW nR;
+ if ( pTab && ((nR = (SCROW)(sal_uLong)pTab->Get( nCurRow )) != 0) )
+ nNextRow = nCurRow + nR;
+ else
+ nNextRow = nCurRow + 1;
+ }
+ if ( nTab == 0 )
+ pE->nWidth = nPageWidth;
+ else
+ { // echte Table, keine Absaetze auf der Wiese
+ if ( pTab )
+ {
+ SCROW nRowSpan = pE->nRowOverlap;
+ for ( SCROW j=0; j < nRowSpan; j++ )
+ { // aus merged Zeilen resultierendes RowSpan
+ SCROW nRows = (SCROW)(sal_uLong)pTab->Get( nRow+j );
+ if ( nRows > 1 )
+ {
+ pE->nRowOverlap += nRows - 1;
+ if ( j == 0 )
+ { // merged Zeilen verschieben die naechste Zeile
+ SCROW nTmp = nCurRow + nRows;
+ if ( nNextRow < nTmp )
+ nNextRow = nTmp;
+ }
+ }
+ }
+ }
+ }
+ // echte Col
+ SeekOffset( pColOffset, pE->nOffset, &pE->nCol, nOffsetTolerance );
+ SCCOL nColBeforeSkip = pE->nCol;
+ SkipLocked( pE, false );
+ if ( pE->nCol != nColBeforeSkip )
+ {
+ SCCOL nCount = (SCCOL)pColOffset->Count();
+ if ( nCount <= pE->nCol )
+ {
+ pE->nOffset = (sal_uInt16) (*pColOffset)[nCount-1];
+ MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
+ }
+ else
+ {
+ pE->nOffset = (sal_uInt16) (*pColOffset)[pE->nCol];
+ }
+ }
+ SCCOL nPos;
+ if ( pE->nWidth && SeekOffset( pColOffset, pE->nOffset + pE->nWidth, &nPos, nOffsetTolerance ) )
+ pE->nColOverlap = (nPos > pE->nCol ? nPos - pE->nCol : 1);
+ else
+ {
+//2do: das muss nicht korrekt sein, ist aber..
+ pE->nColOverlap = 1;
+ }
+ xLockedList->Join( ScRange( pE->nCol, pE->nRow, 0,
+ pE->nCol + pE->nColOverlap - 1, pE->nRow + pE->nRowOverlap - 1, 0 ) );
+ // MaxDimensions mitfuehren
+ SCCOL nColTmp = pE->nCol + pE->nColOverlap;
+ if ( nColMax < nColTmp )
+ nColMax = nColTmp;
+ SCROW nRowTmp = pE->nRow + pE->nRowOverlap;
+ if ( nRowMax < nRowTmp )
+ nRowMax = nRowTmp;
+ }
+ while ( (pS = aStack.Pop()) != 0 )
+ delete pS;
+}
+
+
+sal_uInt16 ScHTMLLayoutParser::GetWidth( ScEEParseEntry* pE )
+{
+ if ( pE->nWidth )
+ return pE->nWidth;
+ sal_Int32 nTmp = ::std::min( static_cast<sal_Int32>( pE->nCol -
+ nColCntStart + pE->nColOverlap),
+ static_cast<sal_Int32>( pLocalColOffset->Count() - 1));
+ SCCOL nPos = (nTmp < 0 ? 0 : static_cast<SCCOL>(nTmp));
+ sal_uInt16 nOff2 = (sal_uInt16) (*pLocalColOffset)[nPos];
+ if ( pE->nOffset < nOff2 )
+ return nOff2 - pE->nOffset;
+ return 0;
+}
+
+
+void ScHTMLLayoutParser::SetWidths()
+{
+ ScEEParseEntry* pE;
+ SCCOL nCol;
+ if ( !nTableWidth )
+ nTableWidth = (sal_uInt16) aPageSize.Width();
+ SCCOL nColsPerRow = nMaxCol - nColCntStart;
+ if ( nColsPerRow <= 0 )
+ nColsPerRow = 1;
+ if ( pLocalColOffset->Count() <= 2 )
+ { // nur PageSize, es gab keine Width-Angabe
+ sal_uInt16 nWidth = nTableWidth / static_cast<sal_uInt16>(nColsPerRow);
+ sal_uInt16 nOff = nColOffsetStart;
+ pLocalColOffset->Remove( (sal_uInt16)0, pLocalColOffset->Count() );
+ for ( nCol = 0; nCol <= nColsPerRow; ++nCol, nOff = nOff + nWidth )
+ {
+ MakeColNoRef( pLocalColOffset, nOff, 0, 0, 0 );
+ }
+ nTableWidth = (sal_uInt16)((*pLocalColOffset)[pLocalColOffset->Count() -1 ] - (*pLocalColOffset)[0]);
+ for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ pE = maList[ i ];
+ if ( pE->nTab == nTable )
+ {
+ pE->nOffset = (sal_uInt16) (*pLocalColOffset)[pE->nCol - nColCntStart];
+ pE->nWidth = 0; // to be recalculated later
+ }
+ }
+ }
+ else
+ { // einige mit einige ohne Width
+ // wieso eigentlich kein pE ?!?
+ if ( nFirstTableCell < maList.size() )
+ {
+ sal_uInt16* pOffsets = new sal_uInt16[ nColsPerRow+1 ];
+ memset( pOffsets, 0, (nColsPerRow+1) * sizeof(sal_uInt16) );
+ sal_uInt16* pWidths = new sal_uInt16[ nColsPerRow ];
+ memset( pWidths, 0, nColsPerRow * sizeof(sal_uInt16) );
+ pOffsets[0] = nColOffsetStart;
+ for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ pE = maList[ i ];
+ if ( pE->nTab == nTable && pE->nWidth )
+ {
+ nCol = pE->nCol - nColCntStart;
+ if ( nCol < nColsPerRow )
+ {
+ if ( pE->nColOverlap == 1 )
+ {
+ if ( pWidths[nCol] < pE->nWidth )
+ pWidths[nCol] = pE->nWidth;
+ }
+ else
+ { // try to find a single undefined width
+ sal_uInt16 nTotal = 0;
+ sal_Bool bFound = false;
+ SCCOL nHere = 0;
+ SCCOL nStop = Min( static_cast<SCCOL>(nCol + pE->nColOverlap), nColsPerRow );
+ for ( ; nCol < nStop; nCol++ )
+ {
+ if ( pWidths[nCol] )
+ nTotal = nTotal + pWidths[nCol];
+ else
+ {
+ if ( bFound )
+ {
+ bFound = false;
+ break; // for
+ }
+ bFound = sal_True;
+ nHere = nCol;
+ }
+ }
+ if ( bFound && pE->nWidth > nTotal )
+ pWidths[nHere] = pE->nWidth - nTotal;
+ }
+ }
+ }
+ }
+ sal_uInt16 nWidths = 0;
+ sal_uInt16 nUnknown = 0;
+ for ( nCol = 0; nCol < nColsPerRow; nCol++ )
+ {
+ if ( pWidths[nCol] )
+ nWidths = nWidths + pWidths[nCol];
+ else
+ nUnknown++;
+ }
+ if ( nUnknown )
+ {
+ sal_uInt16 nW = ((nWidths < nTableWidth) ?
+ ((nTableWidth - nWidths) / nUnknown) :
+ (nTableWidth / nUnknown));
+ for ( nCol = 0; nCol < nColsPerRow; nCol++ )
+ {
+ if ( !pWidths[nCol] )
+ pWidths[nCol] = nW;
+ }
+ }
+ for ( nCol = 1; nCol <= nColsPerRow; nCol++ )
+ {
+ pOffsets[nCol] = pOffsets[nCol-1] + pWidths[nCol-1];
+ }
+ pLocalColOffset->Remove( (sal_uInt16)0, pLocalColOffset->Count() );
+ for ( nCol = 0; nCol <= nColsPerRow; nCol++ )
+ {
+ MakeColNoRef( pLocalColOffset, pOffsets[nCol], 0, 0, 0 );
+ }
+ nTableWidth = pOffsets[nColsPerRow] - pOffsets[0];
+
+ for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ pE = maList[ i ];
+ if ( pE->nTab == nTable )
+ {
+ nCol = pE->nCol - nColCntStart;
+ DBG_ASSERT( nCol < nColsPerRow, "ScHTMLLayoutParser::SetWidths: column overflow" );
+ if ( nCol < nColsPerRow )
+ {
+ pE->nOffset = pOffsets[nCol];
+ nCol = nCol + pE->nColOverlap;
+ if ( nCol > nColsPerRow )
+ nCol = nColsPerRow;
+ pE->nWidth = pOffsets[nCol] - pE->nOffset;
+ }
+ }
+ }
+
+ delete [] pWidths;
+ delete [] pOffsets;
+ }
+ }
+ if ( pLocalColOffset->Count() )
+ {
+ sal_uInt16 nMax = (sal_uInt16) (*pLocalColOffset)[pLocalColOffset->Count() - 1];
+ if ( aPageSize.Width() < nMax )
+ aPageSize.Width() = nMax;
+ }
+ for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ pE = maList[ i ];
+ if ( pE->nTab == nTable )
+ {
+ if ( !pE->nWidth )
+ {
+ pE->nWidth = GetWidth( pE );
+ DBG_ASSERT( pE->nWidth, "SetWidths: pE->nWidth == 0" );
+ }
+ MakeCol( pColOffset, pE->nOffset, pE->nWidth, nOffsetTolerance, nOffsetTolerance );
+ }
+ }
+}
+
+
+void ScHTMLLayoutParser::Colonize( ScEEParseEntry* pE )
+{
+ if ( pE->nCol == SCCOL_MAX )
+ pE->nCol = nColCnt;
+ if ( pE->nRow == SCROW_MAX )
+ pE->nRow = nRowCnt;
+ SCCOL nCol = pE->nCol;
+ SkipLocked( pE ); // Spaltenverdraengung nach rechts
+
+ if ( nCol < pE->nCol )
+ { // verdraengt
+ nCol = pE->nCol - nColCntStart;
+ SCCOL nCount = static_cast<SCCOL>(pLocalColOffset->Count());
+ if ( nCol < nCount )
+ nColOffset = (sal_uInt16) (*pLocalColOffset)[nCol];
+ else
+ nColOffset = (sal_uInt16) (*pLocalColOffset)[nCount - 1];
+ }
+ pE->nOffset = nColOffset;
+ sal_uInt16 nWidth = GetWidth( pE );
+ MakeCol( pLocalColOffset, pE->nOffset, nWidth, nOffsetTolerance, nOffsetTolerance );
+ if ( pE->nWidth )
+ pE->nWidth = nWidth;
+ nColOffset = pE->nOffset + nWidth;
+ if ( nTableWidth < nColOffset - nColOffsetStart )
+ nTableWidth = nColOffset - nColOffsetStart;
+}
+
+
+void ScHTMLLayoutParser::CloseEntry( ImportInfo* pInfo )
+{
+ bInCell = false;
+ if ( bTabInTabCell )
+ { // in TableOff vom Stack geholt
+ bTabInTabCell = false;
+ bool found = false;
+ for ( size_t i = 0, nListSize = maList.size(); i < nListSize; ++i )
+ {
+ if ( pActEntry == maList[ i ] )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ delete pActEntry;
+ NewActEntry( maList.back() ); // neuer freifliegender pActEntry
+ return ;
+ }
+ if ( pActEntry->nTab == 0 )
+ pActEntry->nWidth = (sal_uInt16) aPageSize.Width();
+ Colonize( pActEntry );
+ nColCnt = pActEntry->nCol + pActEntry->nColOverlap;
+ if ( nMaxCol < nColCnt )
+ nMaxCol = nColCnt; // TableStack MaxCol
+ if ( nColMax < nColCnt )
+ nColMax = nColCnt; // globales MaxCol fuer ScEEParser GetDimensions!
+ EntryEnd( pActEntry, pInfo->aSelection );
+ ESelection& rSel = pActEntry->aSel;
+ while ( rSel.nStartPara < rSel.nEndPara
+ && pEdit->GetTextLen( rSel.nStartPara ) == 0 )
+ { // vorgehaengte Leerabsaetze strippen
+ rSel.nStartPara++;
+ }
+ while ( rSel.nEndPos == 0 && rSel.nEndPara > rSel.nStartPara )
+ { // angehaengte Leerabsaetze strippen
+ rSel.nEndPara--;
+ rSel.nEndPos = pEdit->GetTextLen( rSel.nEndPara );
+ }
+ if ( rSel.nStartPara > rSel.nEndPara )
+ { // gibt GPF in CreateTextObject
+ DBG_ERRORFILE( "CloseEntry: EditEngine ESelection Start > End" );
+ rSel.nEndPara = rSel.nStartPara;
+ }
+ if ( rSel.HasRange() )
+ pActEntry->aItemSet.Put( SfxBoolItem( ATTR_LINEBREAK, true ) );
+ maList.push_back( pActEntry );
+ NewActEntry( pActEntry ); // neuer freifliegender pActEntry
+}
+
+
+IMPL_LINK( ScHTMLLayoutParser, HTMLImportHdl, ImportInfo*, pInfo )
+{
+ switch ( pInfo->eState )
+ {
+ case HTMLIMP_NEXTTOKEN:
+ ProcToken( pInfo );
+ break;
+ case HTMLIMP_UNKNOWNATTR:
+ ProcToken( pInfo );
+ break;
+ case HTMLIMP_START:
+ break;
+ case HTMLIMP_END:
+ if ( pInfo->aSelection.nEndPos )
+ {
+ // If text remains: create paragraph, without calling CloseEntry().
+ if( bInCell ) // ...but only in opened table cells.
+ {
+ bInCell = false;
+ NextRow( pInfo );
+ bInCell = sal_True;
+ }
+ CloseEntry( pInfo );
+ }
+ while ( nTableLevel > 0 )
+ TableOff( pInfo ); // close tables, if </TABLE> missing
+ break;
+ case HTMLIMP_SETATTR:
+ break;
+ case HTMLIMP_INSERTTEXT:
+ break;
+ case HTMLIMP_INSERTPARA:
+ if ( nTableLevel < 1 )
+ {
+ CloseEntry( pInfo );
+ NextRow( pInfo );
+ }
+ break;
+ case HTMLIMP_INSERTFIELD:
+ break;
+ default:
+ DBG_ERRORFILE("HTMLImportHdl: unknown ImportInfo.eState");
+ }
+ return 0;
+}
+
+
+// Groesster Gemeinsamer Teiler nach Euklid (Kettendivision)
+// Sonderfall: 0 und irgendwas geben 1
+SCROW lcl_GGT( SCROW a, SCROW b )
+{
+ if ( !a || !b )
+ return 1;
+ do
+ {
+ if ( a > b )
+ a -= SCROW(a / b) * b;
+ else
+ b -= SCROW(b / a) * a;
+ } while ( a && b );
+ return ((a != 0) ? a : b);
+}
+
+
+// Kleinstes Gemeinsames Vielfaches: a * b / GGT(a,b)
+SCROW lcl_KGV( SCROW a, SCROW b )
+{
+ if ( a > b ) // Ueberlauf unwahrscheinlicher machen
+ return (a / lcl_GGT(a,b)) * b;
+ else
+ return (b / lcl_GGT(a,b)) * a;
+}
+
+
+void ScHTMLLayoutParser::TableDataOn( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( !nTableLevel )
+ {
+ OSL_FAIL( "Dummbatz-Dok! <TH> oder <TD> ohne vorheriges <TABLE>" );
+ TableOn( pInfo );
+ }
+ bInCell = sal_True;
+ sal_Bool bHorJustifyCenterTH = (pInfo->nToken == HTML_TABLEHEADER_ON);
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_COLSPAN:
+ {
+ pActEntry->nColOverlap = ( SCCOL ) pOption->GetString().ToInt32();
+ }
+ break;
+ case HTML_O_ROWSPAN:
+ {
+ pActEntry->nRowOverlap = ( SCROW ) pOption->GetString().ToInt32();
+ }
+ break;
+ case HTML_O_ALIGN:
+ {
+ bHorJustifyCenterTH = false;
+ SvxCellHorJustify eVal;
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_CENTER;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) == COMPARE_EQUAL )
+ eVal = SVX_HOR_JUSTIFY_LEFT;
+ else
+ eVal = SVX_HOR_JUSTIFY_STANDARD;
+ if ( eVal != SVX_HOR_JUSTIFY_STANDARD )
+ pActEntry->aItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
+ }
+ break;
+ case HTML_O_VALIGN:
+ {
+ SvxCellVerJustify eVal;
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_TOP;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_CENTER;
+ else if ( rOptVal.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) == COMPARE_EQUAL )
+ eVal = SVX_VER_JUSTIFY_BOTTOM;
+ else
+ eVal = SVX_VER_JUSTIFY_STANDARD;
+ pActEntry->aItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY) );
+ }
+ break;
+ case HTML_O_WIDTH:
+ {
+ pActEntry->nWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BGCOLOR:
+ {
+ Color aColor;
+ pOption->GetColor( aColor );
+ pActEntry->aItemSet.Put(
+ SvxBrushItem( aColor, ATTR_BACKGROUND ) );
+ }
+ break;
+ case HTML_O_SDVAL:
+ {
+ pActEntry->pValStr = new String( pOption->GetString() );
+ }
+ break;
+ case HTML_O_SDNUM:
+ {
+ pActEntry->pNumStr = new String( pOption->GetString() );
+ }
+ break;
+ }
+ }
+ pActEntry->nCol = nColCnt;
+ pActEntry->nRow = nRowCnt;
+ pActEntry->nTab = nTable;
+
+ if ( bHorJustifyCenterTH )
+ pActEntry->aItemSet.Put(
+ SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
+}
+
+
+void ScHTMLLayoutParser::TableRowOn( ImportInfo* pInfo )
+{
+ if ( nColCnt > nColCntStart )
+ NextRow( pInfo ); // das optionale TableRowOff war nicht
+ nColOffset = nColOffsetStart;
+}
+
+
+void ScHTMLLayoutParser::TableRowOff( ImportInfo* pInfo )
+{
+ NextRow( pInfo );
+}
+
+
+void ScHTMLLayoutParser::TableDataOff( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo ); // aber nur wenn's auch eine war
+}
+
+
+void ScHTMLLayoutParser::TableOn( ImportInfo* pInfo )
+{
+ String aTabName;
+
+ if ( ++nTableLevel > 1 )
+ { // Table in Table
+ sal_uInt16 nTmpColOffset = nColOffset; // wird in Colonize noch angepasst
+ Colonize( pActEntry );
+ aTableStack.Push( new ScHTMLTableStackEntry(
+ pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
+ nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
+ nTableWidth, nColOffset, nColOffsetStart,
+ bFirstRow ) );
+ sal_uInt16 nLastWidth = nTableWidth;
+ nTableWidth = GetWidth( pActEntry );
+ if ( nTableWidth == nLastWidth && nMaxCol - nColCntStart > 1 )
+ { // es muss mehr als einen geben, also kann dieser nicht alles sein
+ nTableWidth = nLastWidth / static_cast<sal_uInt16>((nMaxCol - nColCntStart));
+ }
+ nLastWidth = nTableWidth;
+ if ( pInfo->nToken == HTML_TABLE_ON )
+ { // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ { // Prozent: von Dokumentbreite bzw. aeusserer Zelle
+ nTableWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BORDER:
+ // Border is: ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ aTabName.Assign( pOption->GetString() );
+ break;
+ }
+ }
+ }
+ bInCell = false;
+ if ( bTabInTabCell && !(nTableWidth < nLastWidth) )
+ { // mehrere Tabellen in einer Zelle, untereinander
+ bTabInTabCell = false;
+ NextRow( pInfo );
+ }
+ else
+ { // in dieser Zelle geht's los, oder nebeneinander
+ bTabInTabCell = false;
+ nColCntStart = nColCnt;
+ nColOffset = nTmpColOffset;
+ nColOffsetStart = nColOffset;
+ }
+
+ ScEEParseEntry* pE = NULL;
+ if (maList.size())
+ pE = maList.back();
+ NewActEntry( pE ); // neuer freifliegender pActEntry
+ xLockedList = new ScRangeList;
+ }
+ else
+ { // einfache Table auf Dokumentebene
+ EntryEnd( pActEntry, pInfo->aSelection );
+ if ( pActEntry->aSel.HasRange() )
+ { // noch fliegender Text
+ CloseEntry( pInfo );
+ NextRow( pInfo );
+ }
+ aTableStack.Push( new ScHTMLTableStackEntry(
+ pActEntry, xLockedList, pLocalColOffset, nFirstTableCell,
+ nColCnt, nRowCnt, nColCntStart, nMaxCol, nTable,
+ nTableWidth, nColOffset, nColOffsetStart,
+ bFirstRow ) );
+ // As soon as we have multiple tables we need to be tolerant with the offsets.
+ if (nMaxTable > 0)
+ nOffsetTolerance = SC_HTML_OFFSET_TOLERANCE_LARGE;
+ nTableWidth = 0;
+ if ( pInfo->nToken == HTML_TABLE_ON )
+ { // es kann auch TD oder TH sein, wenn es vorher kein TABLE gab
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ { // Prozent: von Dokumentbreite bzw. aeusserer Zelle
+ nTableWidth = GetWidthPixel( pOption );
+ }
+ break;
+ case HTML_O_BORDER:
+ //BorderOn is: ((pOption->GetString().Len() == 0) || (pOption->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ aTabName.Assign( pOption->GetString() );
+ break;
+ }
+ }
+ }
+ }
+ nTable = ++nMaxTable;
+ bFirstRow = true;
+ nFirstTableCell = maList.size();
+
+ pLocalColOffset = new ScHTMLColOffset;
+ MakeColNoRef( pLocalColOffset, nColOffsetStart, 0, 0, 0 );
+}
+
+
+void ScHTMLLayoutParser::TableOff( ImportInfo* pInfo )
+{
+ if ( bInCell )
+ CloseEntry( pInfo );
+ if ( nColCnt > nColCntStart )
+ TableRowOff( pInfo ); // das optionale TableRowOff war nicht
+ if ( !nTableLevel )
+ {
+ OSL_FAIL( "Dummbatz-Dok! </TABLE> ohne oeffnendes <TABLE>" );
+ return ;
+ }
+ if ( --nTableLevel > 0 )
+ { // Table in Table beendet
+ ScHTMLTableStackEntry* pS = aTableStack.Pop();
+ if ( pS )
+ {
+ ScEEParseEntry* pE = pS->pCellEntry;
+ SCROW nRows = nRowCnt - pS->nRowCnt;
+ if ( nRows > 1 )
+ { // Groesse der Tabelle an dieser Position eintragen
+ SCROW nRow = pS->nRowCnt;
+ sal_uInt16 nTab = pS->nTable;
+ if ( !pTables )
+ pTables = new Table;
+ // Hoehen der aeusseren Table
+ Table* pTab1 = (Table*) pTables->Get( nTab );
+ if ( !pTab1 )
+ {
+ pTab1 = new Table;
+ pTables->Insert( nTab, pTab1 );
+ }
+ SCROW nRowSpan = pE->nRowOverlap;
+ SCROW nRowKGV;
+ SCROW nRowsPerRow1; // aeussere Table
+ SCROW nRowsPerRow2; // innere Table
+ if ( nRowSpan > 1 )
+ { // KGV auf das sich aussere und innere Zeilen
+ // abbilden lassen
+ nRowKGV = lcl_KGV( nRowSpan, nRows );
+ nRowsPerRow1 = nRowKGV / nRowSpan;
+ nRowsPerRow2 = nRowKGV / nRows;
+ }
+ else
+ {
+ nRowKGV = nRowsPerRow1 = nRows;
+ nRowsPerRow2 = 1;
+ }
+ Table* pTab2 = NULL;
+ if ( nRowsPerRow2 > 1 )
+ { // Hoehen der inneren Table
+ pTab2 = new Table;
+ pTables->Insert( nTable, pTab2 );
+ }
+ // void* Data-Entry der Table-Class fuer das
+ // Hoehen-Mapping missbrauchen
+ if ( nRowKGV > 1 )
+ {
+ if ( nRowsPerRow1 > 1 )
+ { // aussen
+ for ( SCROW j=0; j < nRowSpan; j++ )
+ {
+ sal_uLong nRowKey = nRow + j;
+ SCROW nR = (SCROW)(sal_uLong)pTab1->Get( nRowKey );
+ if ( !nR )
+ pTab1->Insert( nRowKey, (void*)(sal_IntPtr)nRowsPerRow1 );
+ else if ( nRowsPerRow1 > nR )
+ pTab1->Replace( nRowKey, (void*)(sal_IntPtr)nRowsPerRow1 );
+ //2do: wie geht das noch besser?
+ else if ( nRowsPerRow1 < nR && nRowSpan == 1
+ && nTable == nMaxTable )
+ { // Platz uebrig, evtl. besser mergen
+ SCROW nAdd = nRowsPerRow1 - (nR % nRowsPerRow1);
+ nR += nAdd;
+ if ( (nR % nRows) == 0 )
+ { // nur wenn abbildbar
+ SCROW nR2 = (SCROW)(sal_uLong)pTab1->Get( nRowKey+1 );
+ if ( nR2 > nAdd )
+ { // nur wenn wirklich Platz
+ pTab1->Replace( nRowKey, (void*)(sal_IntPtr)nR );
+ pTab1->Replace( nRowKey+1, (void*)(sal_IntPtr)(nR2 - nAdd) );
+ nRowsPerRow2 = nR / nRows;
+ }
+ }
+ }
+ }
+ }
+ if ( nRowsPerRow2 > 1 )
+ { // innen
+ if ( !pTab2 )
+ { // nRowsPerRow2 kann erhoeht worden sein
+ pTab2 = new Table;
+ pTables->Insert( nTable, pTab2 );
+ }
+ for ( SCROW j=0; j < nRows; j++ )
+ {
+ sal_uLong nRowKey = nRow + j;
+ SCROW nR = (SCROW)(sal_uLong)pTab2->Get( nRowKey );
+ if ( !nR )
+ pTab2->Insert( nRowKey, (void*)(sal_IntPtr)nRowsPerRow2 );
+ else if ( nRowsPerRow2 > nR )
+ pTab2->Replace( nRowKey, (void*)(sal_IntPtr)nRowsPerRow2 );
+ }
+ }
+ }
+ }
+
+ SetWidths();
+
+ if ( !pE->nWidth )
+ pE->nWidth = nTableWidth;
+ else if ( pE->nWidth < nTableWidth )
+ {
+ sal_uInt16 nOldOffset = pE->nOffset + pE->nWidth;
+ sal_uInt16 nNewOffset = pE->nOffset + nTableWidth;
+ ModifyOffset( pS->pLocalColOffset, nOldOffset, nNewOffset, nOffsetTolerance );
+ sal_uInt16 nTmp = nNewOffset - pE->nOffset - pE->nWidth;
+ pE->nWidth = nNewOffset - pE->nOffset;
+ pS->nTableWidth = pS->nTableWidth + nTmp;
+ if ( pS->nColOffset >= nOldOffset )
+ pS->nColOffset = pS->nColOffset + nTmp;
+ }
+
+ nColCnt = pE->nCol + pE->nColOverlap;
+ nRowCnt = pS->nRowCnt;
+ nColCntStart = pS->nColCntStart;
+ nMaxCol = pS->nMaxCol;
+ nTable = pS->nTable;
+ nTableWidth = pS->nTableWidth;
+ nFirstTableCell = pS->nFirstTableCell;
+ nColOffset = pS->nColOffset;
+ nColOffsetStart = pS->nColOffsetStart;
+ bFirstRow = pS->bFirstRow;
+ xLockedList = pS->xLockedList;
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ pLocalColOffset = pS->pLocalColOffset;
+ delete pActEntry;
+ // pActEntry bleibt erstmal erhalten falls da noch 'ne Table in
+ // der gleichen Zelle aufgemacht werden sollte (in HTML ist ja
+ // alles moeglich..) und wird in CloseEntry deleted
+ pActEntry = pE;
+ delete pS;
+ }
+ bTabInTabCell = sal_True;
+ bInCell = sal_True;
+ }
+ else
+ { // einfache Table beendet
+ SetWidths();
+ ScHTMLTableStackEntry* pS = aTableStack.Pop();
+ nMaxCol = 0;
+ nTable = 0;
+ if ( pS )
+ {
+ if ( pLocalColOffset )
+ delete pLocalColOffset;
+ pLocalColOffset = pS->pLocalColOffset;
+ delete pS;
+ }
+ }
+}
+
+
+void ScHTMLLayoutParser::Image( ImportInfo* pInfo )
+{
+ ScHTMLImage* pImage = new ScHTMLImage;
+ pActEntry->maImageList.push_back( pImage );
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_SRC:
+ {
+ pImage->aURL = INetURLObject::GetAbsURL( aBaseURL, pOption->GetString() );
+ }
+ break;
+ case HTML_O_ALT:
+ {
+ if ( !pActEntry->bHasGraphic )
+ { // ALT text only if not any image loaded
+ if ( pActEntry->aAltText.Len() )
+ pActEntry->aAltText.AppendAscii( "; " );
+ pActEntry->aAltText += pOption->GetString();
+ }
+ }
+ break;
+ case HTML_O_WIDTH:
+ {
+ pImage->aSize.Width() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HEIGHT:
+ {
+ pImage->aSize.Height() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HSPACE:
+ {
+ pImage->aSpace.X() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_VSPACE:
+ {
+ pImage->aSpace.Y() = (long)pOption->GetNumber();
+ }
+ break;
+ }
+ }
+ if ( !pImage->aURL.Len() )
+ {
+ DBG_ERRORFILE( "Image: Grafik ohne URL ?!?" );
+ return ;
+ }
+
+ sal_uInt16 nFormat;
+ Graphic* pGraphic = new Graphic;
+ GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter();
+ if ( GRFILTER_OK != GraphicFilter::LoadGraphic( pImage->aURL, pImage->aFilterName,
+ *pGraphic, pFilter, &nFormat ) )
+ {
+ delete pGraphic;
+ return ; // dumm gelaufen
+ }
+ if ( !pActEntry->bHasGraphic )
+ { // discard any ALT text in this cell if we have any image
+ pActEntry->bHasGraphic = sal_True;
+ pActEntry->aAltText.Erase();
+ }
+ pImage->aFilterName = pFilter->GetImportFormatName( nFormat );
+ pImage->pGraphic = pGraphic;
+ if ( !(pImage->aSize.Width() && pImage->aSize.Height()) )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ pImage->aSize = pDefaultDev->LogicToPixel( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode() );
+ }
+ if ( pActEntry->maImageList.size() > 0 )
+ {
+ long nWidth = 0;
+ for ( sal_uInt32 i=0; i < pActEntry->maImageList.size(); ++i )
+ {
+ ScHTMLImage* pI = &pActEntry->maImageList[ i ];
+ if ( pI->nDir & nHorizontal )
+ nWidth += pI->aSize.Width() + 2 * pI->aSpace.X();
+ else
+ nWidth = 0;
+ }
+ if ( pActEntry->nWidth
+ && (nWidth + pImage->aSize.Width() + 2 * pImage->aSpace.X()
+ >= pActEntry->nWidth) )
+ pActEntry->maImageList.back().nDir = nVertical;
+ }
+}
+
+
+void ScHTMLLayoutParser::ColOn( ImportInfo* pInfo )
+{
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_WIDTH:
+ {
+ sal_uInt16 nVal = GetWidthPixel( pOption );
+ MakeCol( pLocalColOffset, nColOffset, nVal, 0, 0 );
+ nColOffset = nColOffset + nVal;
+ }
+ break;
+ }
+ }
+}
+
+
+sal_uInt16 ScHTMLLayoutParser::GetWidthPixel( const HTMLOption* pOption )
+{
+ const String& rOptVal = pOption->GetString();
+ if ( rOptVal.Search('%') != STRING_NOTFOUND )
+ { // Prozent
+ sal_uInt16 nW = (nTableWidth ? nTableWidth : (sal_uInt16) aPageSize.Width());
+ return (sal_uInt16)((pOption->GetNumber() * nW) / 100);
+ }
+ else
+ {
+ if ( rOptVal.Search('*') != STRING_NOTFOUND )
+ { // relativ zu was?!?
+ //todo: ColArray aller relativen Werte sammeln und dann MakeCol
+ return 0;
+ }
+ else
+ return (sal_uInt16)pOption->GetNumber(); // Pixel
+ }
+}
+
+
+void ScHTMLLayoutParser::AnchorOn( ImportInfo* pInfo )
+{
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ {
+ pActEntry->pName = new String( pOption->GetString() );
+ }
+ break;
+ }
+ }
+}
+
+
+sal_Bool ScHTMLLayoutParser::IsAtBeginningOfText( ImportInfo* pInfo )
+{
+ ESelection& rSel = pActEntry->aSel;
+ return rSel.nStartPara == rSel.nEndPara &&
+ rSel.nStartPara <= pInfo->aSelection.nEndPara &&
+ pEdit->GetTextLen( rSel.nStartPara ) == 0;
+}
+
+
+void ScHTMLLayoutParser::FontOn( ImportInfo* pInfo )
+{
+ if ( IsAtBeginningOfText( pInfo ) )
+ { // nur am Anfang des Textes, gilt dann fuer gesamte Zelle
+ const HTMLOptions* pOptions = ((HTMLParser*)pInfo->pParser)->GetOptions();
+ sal_uInt16 nArrLen = pOptions->Count();
+ for ( sal_uInt16 i = 0; i < nArrLen; i++ )
+ {
+ const HTMLOption* pOption = (*pOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_FACE :
+ {
+ const String& rFace = pOption->GetString();
+ String aFontName;
+ xub_StrLen nPos = 0;
+ while( nPos != STRING_NOTFOUND )
+ { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
+ String aFName = rFace.GetToken( 0, ',', nPos );
+ aFName.EraseTrailingChars().EraseLeadingChars();
+ if( aFontName.Len() )
+ aFontName += ';';
+ aFontName += aFName;
+ }
+ if ( aFontName.Len() )
+ pActEntry->aItemSet.Put( SvxFontItem( FAMILY_DONTKNOW,
+ aFontName, EMPTY_STRING, PITCH_DONTKNOW,
+ RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ }
+ break;
+ case HTML_O_SIZE :
+ {
+ sal_uInt16 nSize = (sal_uInt16) pOption->GetNumber();
+ if ( nSize == 0 )
+ nSize = 1;
+ else if ( nSize > SC_HTML_FONTSIZES )
+ nSize = SC_HTML_FONTSIZES;
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[nSize-1], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_O_COLOR :
+ {
+ Color aColor;
+ pOption->GetColor( aColor );
+ pActEntry->aItemSet.Put( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
+{
+ sal_Bool bSetLastToken = sal_True;
+ switch ( pInfo->nToken )
+ {
+ case HTML_META:
+ {
+ HTMLParser* pParser = (HTMLParser*) pInfo->pParser;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ pParser->ParseMetaOptions(
+ xDPS->getDocumentProperties(),
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
+ }
+ break;
+ case HTML_TITLE_ON:
+ {
+ bInTitle = sal_True;
+ aString.Erase();
+ }
+ break;
+ case HTML_TITLE_OFF:
+ {
+ if ( bInTitle && aString.Len() )
+ {
+ // Leerzeichen von Zeilenumbruechen raus
+ aString.EraseLeadingChars();
+ aString.EraseTrailingChars();
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(),
+ uno::UNO_QUERY_THROW);
+ xDPS->getDocumentProperties()->setTitle(aString);
+ }
+ bInTitle = false;
+ }
+ break;
+ case HTML_TABLE_ON:
+ {
+ TableOn( pInfo );
+ }
+ break;
+ case HTML_COL_ON:
+ {
+ ColOn( pInfo );
+ }
+ break;
+ case HTML_TABLEHEADER_ON: // oeffnet Zelle
+ {
+ if ( bInCell )
+ CloseEntry( pInfo );
+ // bInCell nicht sal_True setzen, das macht TableDataOn
+ pActEntry->aItemSet.Put(
+ SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT) );
+ } // fall thru
+ case HTML_TABLEDATA_ON: // oeffnet Zelle
+ {
+ TableDataOn( pInfo );
+ }
+ break;
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF: // schliesst Zelle
+ {
+ TableDataOff( pInfo );
+ }
+ break;
+ case HTML_TABLEROW_ON: // vor erster Zelle in Row
+ {
+ TableRowOn( pInfo );
+ }
+ break;
+ case HTML_TABLEROW_OFF: // nach letzter Zelle in Row
+ {
+ TableRowOff( pInfo );
+ }
+ break;
+ case HTML_TABLE_OFF:
+ {
+ TableOff( pInfo );
+ }
+ break;
+ case HTML_IMAGE:
+ {
+ Image( pInfo );
+ }
+ break;
+ case HTML_PARABREAK_OFF:
+ { // nach einem Image geht es vertikal weiter
+ if ( pActEntry->maImageList.size() > 0 )
+ pActEntry->maImageList.back().nDir = nVertical;
+ }
+ break;
+ case HTML_ANCHOR_ON:
+ {
+ AnchorOn( pInfo );
+ }
+ break;
+ case HTML_FONT_ON :
+ {
+ FontOn( pInfo );
+ }
+ break;
+ case HTML_BIGPRINT_ON :
+ {
+ //tpdo: aktuelle Fontgroesse merken und einen groesser
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[3], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_SMALLPRINT_ON :
+ {
+ //todo: aktuelle Fontgroesse merken und einen kleiner
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxFontHeightItem(
+ maFontHeights[0], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_BOLD_ON :
+ case HTML_STRONG_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
+ ATTR_FONT_WEIGHT ) );
+ }
+ break;
+ case HTML_ITALIC_ON :
+ case HTML_EMPHASIS_ON :
+ case HTML_ADDRESS_ON :
+ case HTML_BLOCKQUOTE_ON :
+ case HTML_BLOCKQUOTE30_ON :
+ case HTML_CITIATION_ON :
+ case HTML_VARIABLE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
+ ATTR_FONT_POSTURE ) );
+ }
+ break;
+ case HTML_DEFINSTANCE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ {
+ pActEntry->aItemSet.Put( SvxWeightItem( WEIGHT_BOLD,
+ ATTR_FONT_WEIGHT ) );
+ pActEntry->aItemSet.Put( SvxPostureItem( ITALIC_NORMAL,
+ ATTR_FONT_POSTURE ) );
+ }
+ }
+ break;
+ case HTML_UNDERLINE_ON :
+ {
+ if ( IsAtBeginningOfText( pInfo ) )
+ pActEntry->aItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE,
+ ATTR_FONT_UNDERLINE ) );
+ }
+ break;
+ case HTML_TEXTTOKEN:
+ {
+ if ( bInTitle )
+ aString += pInfo->aText;
+ }
+ break;
+ default:
+ { // nLastToken nicht setzen!
+ bSetLastToken = false;
+ }
+ }
+ if ( bSetLastToken )
+ nLastToken = pInfo->nToken;
+}
+
+
+
+// ============================================================================
+// HTML DATA QUERY PARSER
+// ============================================================================
+
+template< typename Type >
+inline Type getLimitedValue( const Type& rValue, const Type& rMin, const Type& rMax )
+{ return ::std::max( ::std::min( rValue, rMax ), rMin ); }
+
+// ============================================================================
+
+/** Iterates through all HTML tag options of the passed ImportInfo struct. */
+class ScHTMLOptionIterator
+{
+private:
+ const HTMLOptions* mpOptions; /// The options array.
+ const HTMLOption* mpCurrOption; /// Current option.
+ sal_uInt16 mnCount; /// Size of the options array.
+ sal_uInt16 mnIndex; /// Next option to return.
+
+public:
+ explicit ScHTMLOptionIterator( const ImportInfo& rInfo );
+
+ inline bool is() const { return mnIndex < mnCount; }
+ inline const HTMLOption* operator->() const { return mpCurrOption; }
+ inline const HTMLOption& operator*() const { return *mpCurrOption; }
+ ScHTMLOptionIterator& operator++();
+};
+
+// ----------------------------------------------------------------------------
+
+ScHTMLOptionIterator::ScHTMLOptionIterator( const ImportInfo& rInfo ) :
+ mpOptions( 0 ),
+ mpCurrOption( 0 ),
+ mnCount( 0 ),
+ mnIndex( 0 )
+{
+ const HTMLParser* pParser = static_cast< const HTMLParser* >( rInfo.pParser );
+ if( pParser )
+ mpOptions = pParser->GetOptions();
+ if( mpOptions )
+ mnCount = mpOptions->Count();
+ if( mnCount )
+ mpCurrOption = mpOptions->GetObject( 0 );
+}
+
+ScHTMLOptionIterator& ScHTMLOptionIterator::operator++()
+{
+ if( mnIndex < mnCount ) ++mnIndex;
+ mpCurrOption = (mnIndex < mnCount) ? mpOptions->GetObject( mnIndex ) : 0;
+ return *this;
+}
+
+// ============================================================================
+
+ScHTMLEntry::ScHTMLEntry( const SfxItemSet& rItemSet, ScHTMLTableId nTableId ) :
+ ScEEParseEntry( rItemSet ),
+ mbImportAlways( false )
+{
+ nTab = nTableId;
+ bEntirePara = false;
+}
+
+bool ScHTMLEntry::HasContents() const
+{
+ return mbImportAlways || aSel.HasRange() || aAltText.Len() || IsTable();
+}
+
+void ScHTMLEntry::AdjustStart( const ImportInfo& rInfo )
+{
+ // set start position
+ aSel.nStartPara = rInfo.aSelection.nStartPara;
+ aSel.nStartPos = rInfo.aSelection.nStartPos;
+ // adjust end position
+ if( (aSel.nEndPara < aSel.nStartPara) || ((aSel.nEndPara == aSel.nStartPara) && (aSel.nEndPos < aSel.nStartPos)) )
+ {
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos;
+ }
+}
+
+void ScHTMLEntry::AdjustEnd( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( (aSel.nEndPara < rInfo.aSelection.nEndPara) ||
+ ((aSel.nEndPara == rInfo.aSelection.nEndPara) && (aSel.nEndPos <= rInfo.aSelection.nEndPos)),
+ "ScHTMLQueryParser::AdjustEntryEnd - invalid end position" );
+ // set end position
+ aSel.nEndPara = rInfo.aSelection.nEndPara;
+ aSel.nEndPos = rInfo.aSelection.nEndPos;
+}
+
+void ScHTMLEntry::Strip( const EditEngine& rEditEngine )
+{
+ // strip leading empty paragraphs
+ while( (aSel.nStartPara < aSel.nEndPara) && (rEditEngine.GetTextLen( aSel.nStartPara ) <= aSel.nStartPos) )
+ {
+ ++aSel.nStartPara;
+ aSel.nStartPos = 0;
+ }
+ // strip trailing empty paragraphs
+ while( (aSel.nStartPara < aSel.nEndPara) && (aSel.nEndPos == 0) )
+ {
+ --aSel.nEndPara;
+ aSel.nEndPos = rEditEngine.GetTextLen( aSel.nEndPara );
+ }
+}
+
+// ============================================================================
+
+/** A map of ScHTMLTable objects.
+
+ Organizes the tables with a unique table key. Stores nested tables inside
+ the parent table and forms in this way a tree structure of tables. An
+ instance of this class ownes the contained table objects and deletes them
+ on destruction.
+ */
+class ScHTMLTableMap
+{
+private:
+ typedef ::boost::shared_ptr< ScHTMLTable > ScHTMLTablePtr;
+ typedef ::std::map< ScHTMLTableId, ScHTMLTablePtr > ScHTMLTableStdMap;
+
+public:
+ typedef ScHTMLTableStdMap::iterator iterator;
+ typedef ScHTMLTableStdMap::const_iterator const_iterator;
+
+private:
+ ScHTMLTable& mrParentTable; /// Reference to parent table.
+ ScHTMLTableStdMap maTables; /// Container for all table objects.
+ mutable ScHTMLTable* mpCurrTable; /// Current table, used for fast search.
+
+public:
+ explicit ScHTMLTableMap( ScHTMLTable& rParentTable );
+ virtual ~ScHTMLTableMap();
+
+ inline iterator begin() { return maTables.begin(); }
+ inline const_iterator begin() const { return maTables.begin(); }
+ inline iterator end() { return maTables.end(); }
+ inline const_iterator end() const { return maTables.end(); }
+ inline bool empty() const { return maTables.empty(); }
+
+ /** Returns the specified table.
+ @param nTableId Unique identifier of the table.
+ @param bDeep true = searches deep in all nested table; false = only in this container. */
+ ScHTMLTable* FindTable( ScHTMLTableId nTableId, bool bDeep = true ) const;
+
+ /** Inserts a new table into the container. This container owns the created table.
+ @param bPreFormText true = New table is based on preformatted text (<pre> tag). */
+ ScHTMLTable* CreateTable( const ImportInfo& rInfo, bool bPreFormText );
+
+private:
+ /** Sets a working table with its index for search optimization. */
+ inline void SetCurrTable( ScHTMLTable* pTable ) const
+ { if( pTable ) mpCurrTable = pTable; }
+};
+
+// ----------------------------------------------------------------------------
+
+ScHTMLTableMap::ScHTMLTableMap( ScHTMLTable& rParentTable ) :
+ mrParentTable(rParentTable),
+ mpCurrTable(NULL)
+{
+}
+
+ScHTMLTableMap::~ScHTMLTableMap()
+{
+}
+
+ScHTMLTable* ScHTMLTableMap::FindTable( ScHTMLTableId nTableId, bool bDeep ) const
+{
+ ScHTMLTable* pResult = 0;
+ if( mpCurrTable && (nTableId == mpCurrTable->GetTableId()) )
+ pResult = mpCurrTable; // cached table
+ else
+ {
+ const_iterator aFind = maTables.find( nTableId );
+ if( aFind != maTables.end() )
+ pResult = aFind->second.get(); // table from this container
+ }
+
+ // not found -> search deep in nested tables
+ if( !pResult && bDeep )
+ for( const_iterator aIter = begin(), aEnd = end(); !pResult && (aIter != aEnd); ++aIter )
+ pResult = aIter->second->FindNestedTable( nTableId );
+
+ SetCurrTable( pResult );
+ return pResult;
+}
+
+ScHTMLTable* ScHTMLTableMap::CreateTable( const ImportInfo& rInfo, bool bPreFormText )
+{
+ ScHTMLTable* pTable = new ScHTMLTable( mrParentTable, rInfo, bPreFormText );
+ maTables[ pTable->GetTableId() ].reset( pTable );
+ SetCurrTable( pTable );
+ return pTable;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Simplified forward iterator for convenience.
+
+ Before the iterator can be dereferenced, it must be tested with the is()
+ method. The iterator may be invalid directly after construction (e.g. empty
+ container).
+ */
+class ScHTMLTableIterator
+{
+public:
+ /** Constructs the iterator for the passed table map.
+ @param pTableMap Pointer to the table map (is allowed to be NULL). */
+ explicit ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
+
+ inline bool is() const { return mpTableMap && maIter != maEnd; }
+ inline ScHTMLTable* operator->() { return maIter->second.get(); }
+ inline ScHTMLTable& operator*() { return *maIter->second; }
+ inline ScHTMLTableIterator& operator++() { ++maIter; return *this; }
+
+private:
+ ScHTMLTableMap::const_iterator maIter;
+ ScHTMLTableMap::const_iterator maEnd;
+ const ScHTMLTableMap* mpTableMap;
+};
+
+ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap ) :
+ mpTableMap(pTableMap)
+{
+ if( pTableMap )
+ {
+ maIter = pTableMap->begin();
+ maEnd = pTableMap->end();
+ }
+}
+
+// ============================================================================
+
+ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
+ mnTableId( rnUnusedId ),
+ mrnUnusedId( rnUnusedId )
+{
+ ++mrnUnusedId;
+}
+
+// ----------------------------------------------------------------------------
+
+ScHTMLTable::ScHTMLTable( ScHTMLTable& rParentTable, const ImportInfo& rInfo, bool bPreFormText ) :
+ mpParentTable( &rParentTable ),
+ maTableId( rParentTable.maTableId.mrnUnusedId ),
+ maTableItemSet( rParentTable.GetCurrItemSet() ),
+ mrEditEngine( rParentTable.mrEditEngine ),
+ mrEEParseList( rParentTable.mrEEParseList ),
+ mpCurrEntryList( 0 ),
+ maSize( 1, 1 ),
+ mbBorderOn( false ),
+ mbPreFormText( bPreFormText ),
+ mbRowOn( false ),
+ mbDataOn( false ),
+ mbPushEmptyLine( false )
+{
+ if( mbPreFormText )
+ {
+ ImplRowOn();
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ }
+ else
+ {
+ ProcessFormatOptions( maTableItemSet, rInfo );
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_BORDER:
+ mbBorderOn = ((aIter->GetString().Len() == 0) || (aIter->GetNumber() != 0));
+ break;
+ case HTML_O_ID:
+ maTableName = aIter->GetString();
+ break;
+ }
+ }
+ }
+
+ CreateNewEntry( rInfo );
+}
+
+ScHTMLTable::ScHTMLTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ::std::vector< ScEEParseEntry* >& rEEParseList,
+ ScHTMLTableId& rnUnusedId
+) :
+ mpParentTable( 0 ),
+ maTableId( rnUnusedId ),
+ maTableItemSet( rPool ),
+ mrEditEngine( rEditEngine ),
+ mrEEParseList( rEEParseList ),
+ mpCurrEntryList( 0 ),
+ maSize( 1, 1 ),
+ mbBorderOn( false ),
+ mbPreFormText( false ),
+ mbRowOn( false ),
+ mbDataOn( false ),
+ mbPushEmptyLine( false )
+{
+ // open the first "cell" of the document
+ ImplRowOn();
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ mxCurrEntry = CreateEntry();
+}
+
+ScHTMLTable::~ScHTMLTable()
+{
+}
+
+const SfxItemSet& ScHTMLTable::GetCurrItemSet() const
+{
+ // first try cell item set, then row item set, then table item set
+ return mxDataItemSet.get() ? *mxDataItemSet : (mxRowItemSet.get() ? *mxRowItemSet : maTableItemSet);
+}
+
+ScHTMLSize ScHTMLTable::GetSpan( const ScHTMLPos& rCellPos ) const
+{
+ ScHTMLSize aSpan( 1, 1 );
+ const ScRange* pRange = NULL;
+ if( ( (pRange = maVMergedCells.Find( rCellPos.MakeAddr() ) ) != 0)
+ || ( (pRange = maHMergedCells.Find( rCellPos.MakeAddr() ) ) != 0)
+ )
+ aSpan.Set( pRange->aEnd.Col() - pRange->aStart.Col() + 1, pRange->aEnd.Row() - pRange->aStart.Row() + 1 );
+ return aSpan;
+}
+
+ScHTMLTable* ScHTMLTable::FindNestedTable( ScHTMLTableId nTableId ) const
+{
+ return mxNestedTables.get() ? mxNestedTables->FindTable( nTableId, true ) : 0;
+}
+
+void ScHTMLTable::PutItem( const SfxPoolItem& rItem )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
+ if( mxCurrEntry.get() && mxCurrEntry->IsEmpty() )
+ mxCurrEntry->GetItemSet().Put( rItem );
+}
+
+void ScHTMLTable::PutText( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
+ if( mxCurrEntry.get() )
+ {
+ if( !mxCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
+ mxCurrEntry->AdjustStart( rInfo );
+ else
+ mxCurrEntry->AdjustEnd( rInfo );
+ }
+}
+
+void ScHTMLTable::InsertPara( const ImportInfo& rInfo )
+{
+ if( mxCurrEntry.get() && mbDataOn && !IsEmptyCell() )
+ mxCurrEntry->SetImportAlways();
+ PushEntry( rInfo );
+ CreateNewEntry( rInfo );
+ InsertLeadingEmptyLine();
+}
+
+void ScHTMLTable::BreakOn()
+{
+ // empty line, if <br> is at start of cell
+ mbPushEmptyLine = !mbPreFormText && mbDataOn && IsEmptyCell();
+}
+
+void ScHTMLTable::HeadingOn()
+{
+ // call directly, InsertPara() has not been called before
+ InsertLeadingEmptyLine();
+}
+
+void ScHTMLTable::InsertLeadingEmptyLine()
+{
+ // empty line, if <p>, </p>, <h?>, or </h*> are not at start of cell
+ mbPushEmptyLine = !mbPreFormText && mbDataOn && !IsEmptyCell();
+}
+
+void ScHTMLTable::AnchorOn()
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
+ // don't skip entries with single hyperlinks
+ if( mxCurrEntry.get() )
+ mxCurrEntry->SetImportAlways();
+}
+
+ScHTMLTable* ScHTMLTable::TableOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ return InsertNestedTable( rInfo, false );
+}
+
+ScHTMLTable* ScHTMLTable::TableOff( const ImportInfo& rInfo )
+{
+ return mbPreFormText ? this : CloseTable( rInfo );
+}
+
+ScHTMLTable* ScHTMLTable::PreOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ return InsertNestedTable( rInfo, true );
+}
+
+ScHTMLTable* ScHTMLTable::PreOff( const ImportInfo& rInfo )
+{
+ return mbPreFormText ? CloseTable( rInfo ) : this;
+}
+
+void ScHTMLTable::RowOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no rows allowed in global and preformatted tables
+ {
+ ImplRowOn();
+ ProcessFormatOptions( *mxRowItemSet, rInfo );
+ }
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::RowOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no rows allowed in global and preformatted tables
+ ImplRowOff();
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::DataOn( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no cells allowed in global and preformatted tables
+ {
+ // read needed options from the <td> tag
+ ScHTMLSize aSpanSize( 1, 1 );
+ ::std::auto_ptr< String > pValStr, pNumStr;
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_COLSPAN:
+ aSpanSize.mnCols = static_cast< SCCOL >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
+ break;
+ case HTML_O_ROWSPAN:
+ aSpanSize.mnRows = static_cast< SCROW >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
+ break;
+ case HTML_O_SDVAL:
+ pValStr.reset( new String( aIter->GetString() ) );
+ break;
+ case HTML_O_SDNUM:
+ pNumStr.reset( new String( aIter->GetString() ) );
+ break;
+ }
+ }
+
+ ImplDataOn( aSpanSize );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
+ CreateNewEntry( rInfo );
+ mxCurrEntry->pValStr = pValStr.release();
+ mxCurrEntry->pNumStr = pNumStr.release();
+ }
+ else
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::DataOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo, true );
+ if( mpParentTable && !mbPreFormText ) // no cells allowed in global and preformatted tables
+ ImplDataOff();
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::BodyOn( const ImportInfo& rInfo )
+{
+ bool bPushed = PushEntry( rInfo );
+ if( !mpParentTable )
+ {
+ // do not start new row, if nothing (no title) precedes the body.
+ if( bPushed || !mbRowOn )
+ ImplRowOn();
+ if( bPushed || !mbDataOn )
+ ImplDataOn( ScHTMLSize( 1, 1 ) );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
+ }
+ CreateNewEntry( rInfo );
+}
+
+void ScHTMLTable::BodyOff( const ImportInfo& rInfo )
+{
+ PushEntry( rInfo );
+ if( !mpParentTable )
+ {
+ ImplDataOff();
+ ImplRowOff();
+ }
+ CreateNewEntry( rInfo );
+}
+
+ScHTMLTable* ScHTMLTable::CloseTable( const ImportInfo& rInfo )
+{
+ if( mpParentTable ) // not allowed to close global table
+ {
+ PushEntry( rInfo, mbDataOn );
+ ImplDataOff();
+ ImplRowOff();
+ mpParentTable->PushTableEntry( GetTableId() );
+ mpParentTable->CreateNewEntry( rInfo );
+ if( mbPreFormText ) // enclose preformatted table with empty lines in parent table
+ mpParentTable->InsertLeadingEmptyLine();
+ return mpParentTable;
+ }
+ return this;
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nIndex = static_cast< size_t >( nCellPos );
+ if( nIndex >= rSizes.size() ) return 0;
+ return (nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]);
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nBeginIdx = static_cast< size_t >( ::std::max< SCCOLROW >( nCellBegin, 0 ) );
+ size_t nEndIdx = static_cast< size_t >( ::std::min< SCCOLROW >( nCellEnd, static_cast< SCCOLROW >( rSizes.size() ) ) );
+ if (nBeginIdx >= nEndIdx ) return 0;
+ return rSizes[ nEndIdx - 1 ] - ((nBeginIdx == 0) ? 0 : rSizes[ nBeginIdx - 1 ]);
+}
+
+SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient ) const
+{
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ return rSizes.empty() ? 0 : rSizes.back();
+}
+
+ScHTMLSize ScHTMLTable::GetDocSize( const ScHTMLPos& rCellPos ) const
+{
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
+ return ScHTMLSize(
+ static_cast< SCCOL >( GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols ) ),
+ static_cast< SCROW >( GetDocSize( tdRow, rCellPos.mnRow, rCellPos.mnRow + aCellSpan.mnRows ) ) );
+}
+
+SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
+{
+ return maDocBasePos.Get( eOrient ) + GetDocSize( eOrient, 0, nCellPos );
+}
+
+ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
+{
+ return ScHTMLPos(
+ static_cast< SCCOL >( GetDocPos( tdCol, rCellPos.mnCol ) ),
+ static_cast< SCROW >( GetDocPos( tdRow, rCellPos.mnRow ) ) );
+}
+
+void ScHTMLTable::GetDocRange( ScRange& rRange ) const
+{
+ rRange.aStart = rRange.aEnd = maDocBasePos.MakeAddr();
+ rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1, static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0 );
+}
+
+void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const
+{
+ DBG_ASSERT( pDoc, "ScHTMLTable::ApplyCellBorders - no document" );
+ if( pDoc && mbBorderOn )
+ {
+ const SCCOL nLastCol = maSize.mnCols - 1;
+ const SCROW nLastRow = maSize.mnRows - 1;
+ const long nOuterLine = DEF_LINE_WIDTH_2;
+ const long nInnerLine = DEF_LINE_WIDTH_0;
+ SvxBorderLine aOuterLine( NULL, nOuterLine, ::editeng::SOLID );
+ SvxBorderLine aInnerLine( NULL, nInnerLine, ::editeng::SOLID );
+ SvxBoxItem aBorderItem( ATTR_BORDER );
+
+ for( SCCOL nCol = 0; nCol <= nLastCol; ++nCol )
+ {
+ SvxBorderLine* pLeftLine = (nCol == 0) ? &aOuterLine : &aInnerLine;
+ SvxBorderLine* pRightLine = (nCol == nLastCol) ? &aOuterLine : &aInnerLine;
+ SCCOL nCellCol1 = static_cast< SCCOL >( GetDocPos( tdCol, nCol ) ) + rFirstPos.Col();
+ SCCOL nCellCol2 = nCellCol1 + static_cast< SCCOL >( GetDocSize( tdCol, nCol ) ) - 1;
+ for( SCROW nRow = 0; nRow <= nLastRow; ++nRow )
+ {
+ SvxBorderLine* pTopLine = (nRow == 0) ? &aOuterLine : &aInnerLine;
+ SvxBorderLine* pBottomLine = (nRow == nLastRow) ? &aOuterLine : &aInnerLine;
+ SCROW nCellRow1 = GetDocPos( tdRow, nRow ) + rFirstPos.Row();
+ SCROW nCellRow2 = nCellRow1 + GetDocSize( tdRow, nRow ) - 1;
+ for( SCCOL nCellCol = nCellCol1; nCellCol <= nCellCol2; ++nCellCol )
+ {
+ aBorderItem.SetLine( (nCellCol == nCellCol1) ? pLeftLine : 0, BOX_LINE_LEFT );
+ aBorderItem.SetLine( (nCellCol == nCellCol2) ? pRightLine : 0, BOX_LINE_RIGHT );
+ for( SCROW nCellRow = nCellRow1; nCellRow <= nCellRow2; ++nCellRow )
+ {
+ aBorderItem.SetLine( (nCellRow == nCellRow1) ? pTopLine : 0, BOX_LINE_TOP );
+ aBorderItem.SetLine( (nCellRow == nCellRow2) ? pBottomLine : 0, BOX_LINE_BOTTOM );
+ pDoc->ApplyAttr( nCellCol, nCellRow, rFirstPos.Tab(), aBorderItem );
+ }
+ }
+ }
+ }
+ }
+
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->ApplyCellBorders( pDoc, rFirstPos );
+}
+
+// ----------------------------------------------------------------------------
+
+bool ScHTMLTable::IsEmptyCell() const
+{
+ return mpCurrEntryList && mpCurrEntryList->empty();
+}
+
+bool ScHTMLTable::IsSpaceCharInfo( const ImportInfo& rInfo )
+{
+ return (rInfo.nToken == HTML_TEXTTOKEN) && (rInfo.aText.Len() == 1) && (rInfo.aText.GetChar( 0 ) == ' ');
+}
+
+ScHTMLTable::ScHTMLEntryPtr ScHTMLTable::CreateEntry() const
+{
+ return ScHTMLEntryPtr( new ScHTMLEntry( GetCurrItemSet() ) );
+}
+
+void ScHTMLTable::CreateNewEntry( const ImportInfo& rInfo )
+{
+ DBG_ASSERT( !mxCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
+ mxCurrEntry = CreateEntry();
+ mxCurrEntry->aSel = rInfo.aSelection;
+}
+
+void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry )
+{
+ // HTML entry list does not own the entries
+ rEntryList.push_back( rxEntry.get() );
+ // mrEEParseList (reference to member of ScEEParser) owns the entries
+ mrEEParseList.push_back( rxEntry.release() );
+}
+
+bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rxEntry )
+{
+ bool bPushed = false;
+ if( rxEntry.get() && rxEntry->HasContents() )
+ {
+ if( mpCurrEntryList )
+ {
+ if( mbPushEmptyLine )
+ {
+ ScHTMLEntryPtr xEmptyEntry = CreateEntry();
+ ImplPushEntryToList( *mpCurrEntryList, xEmptyEntry );
+ mbPushEmptyLine = false;
+ }
+ ImplPushEntryToList( *mpCurrEntryList, rxEntry );
+ bPushed = true;
+ }
+ else if( mpParentTable )
+ {
+ bPushed = mpParentTable->PushEntry( rxEntry );
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScHTMLTable::PushEntry - cannot push entry, no parent found" );
+ }
+ }
+ return bPushed;
+}
+
+bool ScHTMLTable::PushEntry( const ImportInfo& rInfo, bool bLastInCell )
+{
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
+ bool bPushed = false;
+ if( mxCurrEntry.get() )
+ {
+ mxCurrEntry->AdjustEnd( rInfo );
+ mxCurrEntry->Strip( mrEditEngine );
+
+ // import entry always, if it is the last in cell, and cell is still empty
+ if( bLastInCell && IsEmptyCell() )
+ {
+ mxCurrEntry->SetImportAlways();
+ // don't insert empty lines before single empty entries
+ if( mxCurrEntry->IsEmpty() )
+ mbPushEmptyLine = false;
+ }
+
+ bPushed = PushEntry( mxCurrEntry );
+ mxCurrEntry.reset();
+ }
+ return bPushed;
+}
+
+bool ScHTMLTable::PushTableEntry( ScHTMLTableId nTableId )
+{
+ DBG_ASSERT( nTableId != SC_HTML_GLOBAL_TABLE, "ScHTMLTable::PushTableEntry - cannot push global table" );
+ bool bPushed = false;
+ if( nTableId != SC_HTML_GLOBAL_TABLE )
+ {
+ ScHTMLEntryPtr xEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
+ bPushed = PushEntry( xEntry );
+ }
+ return bPushed;
+}
+
+ScHTMLTable* ScHTMLTable::GetExistingTable( ScHTMLTableId nTableId ) const
+{
+ ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mxNestedTables.get()) ?
+ mxNestedTables->FindTable( nTableId, false ) : 0;
+ DBG_ASSERT( pTable || (nTableId == SC_HTML_GLOBAL_TABLE), "ScHTMLTable::GetExistingTable - table not found" );
+ return pTable;
+}
+
+ScHTMLTable* ScHTMLTable::InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText )
+{
+ if( !mxNestedTables.get() )
+ mxNestedTables.reset( new ScHTMLTableMap( *this ) );
+ if( bPreFormText ) // enclose new preformatted table with empty lines
+ InsertLeadingEmptyLine();
+ return mxNestedTables->CreateTable( rInfo, bPreFormText );
+}
+
+void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
+{
+ ScRange* pRange;
+
+ /* Find an unused cell by skipping all merged ranges that cover the
+ current cell position stored in maCurrCell. */
+ while( ((pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0) || ((pRange = maHMergedCells.Find( maCurrCell.MakeAddr() )) != 0) )
+ maCurrCell.mnCol = pRange->aEnd.Col() + 1;
+ mpCurrEntryList = &maEntryMap[ maCurrCell ];
+
+ /* If the new cell is merged horizontally, try to find collisions with
+ other vertically merged ranges. In this case, shrink existing
+ vertically merged ranges (do not shrink the new cell). */
+ SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols;
+ for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() )
+ if( (pRange = maVMergedCells.Find( aAddr )) != 0 )
+ pRange->aEnd.SetRow( maCurrCell.mnRow - 1 );
+
+ // insert the new range into the cell lists
+ ScRange aNewRange( maCurrCell.MakeAddr() );
+ aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
+ if( rSpanSize.mnRows > 1 )
+ {
+ maVMergedCells.Append( aNewRange );
+ /* Do not insert vertically merged ranges into maUsedCells yet,
+ because they may be shrunken (see above). The final vertically
+ merged ranges are inserted in FillEmptyCells(). */
+ }
+ else
+ {
+ if( rSpanSize.mnCols > 1 )
+ maHMergedCells.Append( aNewRange );
+ /* Insert horizontally merged ranges and single cells into
+ maUsedCells, they will not be changed anymore. */
+ maUsedCells.Join( aNewRange );
+ }
+
+ // adjust table size
+ maSize.mnCols = ::std::max< SCCOL >( maSize.mnCols, aNewRange.aEnd.Col() + 1 );
+ maSize.mnRows = ::std::max< SCROW >( maSize.mnRows, aNewRange.aEnd.Row() + 1 );
+}
+
+void ScHTMLTable::ImplRowOn()
+{
+ if( mbRowOn )
+ ImplRowOff();
+ mxRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
+ maCurrCell.mnCol = 0;
+ mbRowOn = true;
+ mbDataOn = false;
+}
+
+void ScHTMLTable::ImplRowOff()
+{
+ if( mbDataOn )
+ ImplDataOff();
+ if( mbRowOn )
+ {
+ mxRowItemSet.reset();
+ ++maCurrCell.mnRow;
+ mbRowOn = mbDataOn = false;
+ }
+}
+
+void ScHTMLTable::ImplDataOn( const ScHTMLSize& rSpanSize )
+{
+ if( mbDataOn )
+ ImplDataOff();
+ if( !mbRowOn )
+ ImplRowOn();
+ mxDataItemSet.reset( new SfxItemSet( *mxRowItemSet ) );
+ InsertNewCell( rSpanSize );
+ mbDataOn = true;
+ mbPushEmptyLine = false;
+}
+
+void ScHTMLTable::ImplDataOff()
+{
+ if( mbDataOn )
+ {
+ mxDataItemSet.reset();
+ ++maCurrCell.mnCol;
+ mpCurrEntryList = 0;
+ mbDataOn = false;
+ }
+}
+
+void ScHTMLTable::ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo )
+{
+ // special handling for table header cells
+ if( rInfo.nToken == HTML_TABLEHEADER_ON )
+ {
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+ }
+
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_ALIGN:
+ {
+ SvxCellHorJustify eVal = SVX_HOR_JUSTIFY_STANDARD;
+ const String& rOptVal = aIter->GetString();
+ if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) )
+ eVal = SVX_HOR_JUSTIFY_RIGHT;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_center ) )
+ eVal = SVX_HOR_JUSTIFY_CENTER;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) )
+ eVal = SVX_HOR_JUSTIFY_LEFT;
+ if( eVal != SVX_HOR_JUSTIFY_STANDARD )
+ rItemSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY ) );
+ }
+ break;
+
+ case HTML_O_VALIGN:
+ {
+ SvxCellVerJustify eVal = SVX_VER_JUSTIFY_STANDARD;
+ const String& rOptVal = aIter->GetString();
+ if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_top ) )
+ eVal = SVX_VER_JUSTIFY_TOP;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_middle ) )
+ eVal = SVX_VER_JUSTIFY_CENTER;
+ else if( rOptVal.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_VA_bottom ) )
+ eVal = SVX_VER_JUSTIFY_BOTTOM;
+ if( eVal != SVX_VER_JUSTIFY_STANDARD )
+ rItemSet.Put( SvxVerJustifyItem( eVal, ATTR_VER_JUSTIFY ) );
+ }
+ break;
+
+ case HTML_O_BGCOLOR:
+ {
+ Color aColor;
+ aIter->GetColor( aColor );
+ rItemSet.Put( SvxBrushItem( aColor, ATTR_BACKGROUND ) );
+ }
+ break;
+ }
+ }
+}
+
+void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize )
+{
+ DBG_ASSERT( nCellPos >= 0, "ScHTMLTable::SetDocSize - unexpected negative position" );
+ ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ size_t nIndex = static_cast< size_t >( nCellPos );
+ // expand with height/width == 1
+ while( nIndex >= rSizes.size() )
+ rSizes.push_back( rSizes.empty() ? 1 : (rSizes.back() + 1) );
+ // update size of passed position and all following
+ // #i109987# only grow, don't shrink - use the largest needed size
+ SCsCOLROW nDiff = nSize - ((nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ]));
+ if( nDiff > 0 )
+ for( ScSizeVec::iterator aIt = rSizes.begin() + nIndex, aEnd = rSizes.end(); aIt != aEnd; ++aIt )
+ *aIt += nDiff;
+}
+
+void ScHTMLTable::CalcNeededDocSize(
+ ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nCellSpan, SCCOLROW nRealDocSize )
+{
+ SCCOLROW nDiffSize = 0;
+ // in merged columns/rows: reduce needed size by size of leading columns
+ while( nCellSpan > 1 )
+ {
+ nDiffSize += GetDocSize( eOrient, nCellPos );
+ --nCellSpan;
+ ++nCellPos;
+ }
+ // set remaining needed size to last column/row
+ nRealDocSize -= ::std::min< SCCOLROW >( nRealDocSize - 1, nDiffSize );
+ SetDocSize( eOrient, nCellPos, nRealDocSize );
+}
+
+// ----------------------------------------------------------------------------
+
+void ScHTMLTable::FillEmptyCells()
+{
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->FillEmptyCells();
+
+ // insert the final vertically merged ranges into maUsedCells
+ for ( size_t i = 0, nRanges = maVMergedCells.size(); i < nRanges; ++i )
+ {
+ ScRange* pRange = maVMergedCells[ i ];
+ maUsedCells.Join( *pRange );
+ }
+
+ for( ScAddress aAddr; aAddr.Row() < maSize.mnRows; aAddr.IncRow() )
+ {
+ for( aAddr.SetCol( 0 ); aAddr.Col() < maSize.mnCols; aAddr.IncCol() )
+ {
+ if( !maUsedCells.Find( aAddr ) )
+ {
+ // create a range for the lock list (used to calc. cell span)
+ ScRange aRange( aAddr );
+ do
+ {
+ aRange.aEnd.IncCol();
+ }
+ while( (aRange.aEnd.Col() < maSize.mnCols) && !maUsedCells.Find( aRange.aEnd ) );
+ aRange.aEnd.IncCol( -1 );
+ maUsedCells.Join( aRange );
+
+ // insert a dummy entry
+ ScHTMLEntryPtr xEntry = CreateEntry();
+ ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], xEntry );
+ }
+ }
+ }
+}
+
+void ScHTMLTable::RecalcDocSize()
+{
+ // recalc table sizes recursively from inner to outer
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
+ aIter->RecalcDocSize();
+
+ /* Two passes: first calculates the sizes of single columns/rows, then
+ the sizes of spanned columns/rows. This allows to fill nested tables
+ into merged cells optimally. */
+ static const sal_uInt16 PASS_SINGLE = 0;
+ static const sal_uInt16 PASS_SPANNED = 1;
+ for( sal_uInt16 nPass = PASS_SINGLE; nPass <= PASS_SPANNED; ++nPass )
+ {
+ // iterate through every table cell
+ ScHTMLEntryMap::const_iterator aMapIterEnd = maEntryMap.end();
+ for( ScHTMLEntryMap::const_iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
+ {
+ const ScHTMLPos& rCellPos = aMapIter->first;
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
+
+ const ScHTMLEntryList& rEntryList = aMapIter->second;
+ ScHTMLEntryList::const_iterator aListIter;
+ ScHTMLEntryList::const_iterator aListIterEnd = rEntryList.end();
+
+ // process the dimension of the current cell in this pass?
+ // (pass is single and span is 1) or (pass is not single and span is not 1)
+ bool bProcessColWidth = ((nPass == PASS_SINGLE) == (aCellSpan.mnCols == 1));
+ bool bProcessRowHeight = ((nPass == PASS_SINGLE) == (aCellSpan.mnRows == 1));
+ if( bProcessColWidth || bProcessRowHeight )
+ {
+ ScHTMLSize aDocSize( 1, 0 ); // resulting size of the cell in document
+
+ // expand the cell size for each cell parse entry
+ for( aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
+ {
+ ScHTMLTable* pTable = GetExistingTable( (*aListIter)->GetTableId() );
+ // find entry with maximum width
+ if( bProcessColWidth && pTable )
+ aDocSize.mnCols = ::std::max( aDocSize.mnCols, static_cast< SCCOL >( pTable->GetDocSize( tdCol ) ) );
+ // add up height of each entry
+ if( bProcessRowHeight )
+ aDocSize.mnRows += pTable ? pTable->GetDocSize( tdRow ) : 1;
+ }
+ if( !aDocSize.mnRows )
+ aDocSize.mnRows = 1;
+
+ if( bProcessColWidth )
+ CalcNeededDocSize( tdCol, rCellPos.mnCol, aCellSpan.mnCols, aDocSize.mnCols );
+ if( bProcessRowHeight )
+ CalcNeededDocSize( tdRow, rCellPos.mnRow, aCellSpan.mnRows, aDocSize.mnRows );
+ }
+ }
+ }
+}
+
+void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
+{
+ maDocBasePos = rBasePos;
+ // after the previous assignment it is allowed to call GetDocPos() methods
+
+ // iterate through every table cell
+ ScHTMLEntryMap::iterator aMapIterEnd = maEntryMap.end();
+ for( ScHTMLEntryMap::iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
+ {
+ // fixed doc position of the entire cell (first entry)
+ const ScHTMLPos aCellDocPos( GetDocPos( aMapIter->first ) );
+ // fixed doc size of the entire cell
+ const ScHTMLSize aCellDocSize( GetDocSize( aMapIter->first ) );
+
+ // running doc position for single entries
+ ScHTMLPos aEntryDocPos( aCellDocPos );
+
+ ScHTMLEntryList& rEntryList = aMapIter->second;
+ ScHTMLEntry* pEntry = 0;
+ ScHTMLEntryList::iterator aListIterEnd = rEntryList.end();
+ for( ScHTMLEntryList::iterator aListIter = rEntryList.begin(); aListIter != aListIterEnd; ++aListIter )
+ {
+ pEntry = *aListIter;
+ if( ScHTMLTable* pTable = GetExistingTable( pEntry->GetTableId() ) )
+ {
+ pTable->RecalcDocPos( aEntryDocPos ); // recalc nested table
+ pEntry->nCol = SCCOL_MAX;
+ pEntry->nRow = SCROW_MAX;
+ SCROW nTableRows = static_cast< SCROW >( pTable->GetDocSize( tdRow ) );
+
+ // use this entry to pad empty space right of table
+ if( mpParentTable ) // ... but not in global table
+ {
+ SCCOL nStartCol = aEntryDocPos.mnCol + static_cast< SCCOL >( pTable->GetDocSize( tdCol ) );
+ SCCOL nNextCol = aEntryDocPos.mnCol + aCellDocSize.mnCols;
+ if( nStartCol < nNextCol )
+ {
+ pEntry->nCol = nStartCol;
+ pEntry->nRow = aEntryDocPos.mnRow;
+ pEntry->nColOverlap = nNextCol - nStartCol;
+ pEntry->nRowOverlap = nTableRows;
+ }
+ }
+ aEntryDocPos.mnRow += nTableRows;
+ }
+ else
+ {
+ pEntry->nCol = aEntryDocPos.mnCol;
+ pEntry->nRow = aEntryDocPos.mnRow;
+ if( mpParentTable ) // do not merge in global table
+ pEntry->nColOverlap = aCellDocSize.mnCols;
+ ++aEntryDocPos.mnRow;
+ }
+ }
+
+ // pEntry points now to last entry.
+ if( pEntry )
+ {
+ if( (pEntry == rEntryList.front()) && (pEntry->GetTableId() == SC_HTML_NO_TABLE) )
+ {
+ // pEntry is the only entry in this cell - merge rows of cell with single non-table entry.
+ pEntry->nRowOverlap = aCellDocSize.mnRows;
+ }
+ else
+ {
+ // fill up incomplete entry lists
+ SCROW nFirstUnusedRow = aCellDocPos.mnRow + aCellDocSize.mnRows;
+ while( aEntryDocPos.mnRow < nFirstUnusedRow )
+ {
+ ScHTMLEntryPtr xDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
+ xDummyEntry->nCol = aEntryDocPos.mnCol;
+ xDummyEntry->nRow = aEntryDocPos.mnRow;
+ xDummyEntry->nColOverlap = aCellDocSize.mnCols;
+ ImplPushEntryToList( rEntryList, xDummyEntry );
+ ++aEntryDocPos.mnRow;
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+ScHTMLGlobalTable::ScHTMLGlobalTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ::std::vector< ScEEParseEntry* >& rEEParseList,
+ ScHTMLTableId& rnUnusedId
+) :
+ ScHTMLTable( rPool, rEditEngine, rEEParseList, rnUnusedId )
+{
+}
+
+ScHTMLGlobalTable::~ScHTMLGlobalTable()
+{
+}
+
+void ScHTMLGlobalTable::Recalc()
+{
+ // Fills up empty cells with a dummy entry. */
+ FillEmptyCells();
+ // recalc table sizes of all nested tables and this table
+ RecalcDocSize();
+ // recalc document positions of all entries in this table and in nested tables
+ RecalcDocPos( GetDocPos() );
+}
+
+// ============================================================================
+
+ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
+ ScHTMLParser( pEditEngine, pDoc ),
+ mnUnusedId( SC_HTML_GLOBAL_TABLE ),
+ mbTitleOn( false )
+{
+ mxGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, maList, mnUnusedId ) );
+ mpCurrTable = mxGlobTable.get();
+}
+
+ScHTMLQueryParser::~ScHTMLQueryParser()
+{
+}
+
+sal_uLong ScHTMLQueryParser::Read( SvStream& rStrm, const String& rBaseURL )
+{
+ SvKeyValueIteratorRef xValues;
+ SvKeyValueIterator* pAttributes = 0;
+
+ SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
+ if( pObjSh && pObjSh->IsLoading() )
+ {
+ pAttributes = pObjSh->GetHeaderAttributes();
+ }
+ else
+ {
+ /* When not loading, set up fake HTTP headers to force the SfxHTMLParser
+ to use UTF8 (used when pasting from clipboard) */
+ const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
+ if( pCharSet )
+ {
+ String aContentType = String::CreateFromAscii( "text/html; charset=" );
+ aContentType.AppendAscii( pCharSet );
+
+ xValues = new SvKeyValueIterator;
+ xValues->Append( SvKeyValue( String::CreateFromAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ), aContentType ) );
+ pAttributes = xValues;
+ }
+ }
+
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScHTMLQueryParser, HTMLImportHdl ) );
+ sal_uLong nErr = pEdit->Read( rStrm, rBaseURL, EE_FORMAT_HTML, pAttributes );
+ pEdit->SetImportHdl( aOldLink );
+
+ mxGlobTable->Recalc();
+ nColMax = static_cast< SCCOL >( mxGlobTable->GetDocSize( tdCol ) - 1 );
+ nRowMax = static_cast< SCROW >( mxGlobTable->GetDocSize( tdRow ) - 1 );
+
+ return nErr;
+}
+
+const ScHTMLTable* ScHTMLQueryParser::GetGlobalTable() const
+{
+ return mxGlobTable.get();
+}
+
+void ScHTMLQueryParser::ProcessToken( const ImportInfo& rInfo )
+{
+ switch( rInfo.nToken )
+ {
+// --- meta data ---
+ case HTML_META: MetaOn( rInfo ); break; // <meta>
+
+// --- title handling ---
+ case HTML_TITLE_ON: TitleOn( rInfo ); break; // <title>
+ case HTML_TITLE_OFF: TitleOff( rInfo ); break; // </title>
+
+// --- body handling ---
+ case HTML_BODY_ON: mpCurrTable->BodyOn( rInfo ); break; // <body>
+ case HTML_BODY_OFF: mpCurrTable->BodyOff( rInfo ); break; // </body>
+
+// --- insert text ---
+ case HTML_TEXTTOKEN: InsertText( rInfo ); break; // any text
+ case HTML_LINEBREAK: mpCurrTable->BreakOn(); break; // <br>
+ case HTML_HEAD1_ON: // <h1>
+ case HTML_HEAD2_ON: // <h2>
+ case HTML_HEAD3_ON: // <h3>
+ case HTML_HEAD4_ON: // <h4>
+ case HTML_HEAD5_ON: // <h5>
+ case HTML_HEAD6_ON: // <h6>
+ case HTML_PARABREAK_ON: mpCurrTable->HeadingOn(); break; // <p>
+
+// --- misc. contents ---
+ case HTML_ANCHOR_ON: mpCurrTable->AnchorOn(); break; // <a>
+
+// --- table handling ---
+ case HTML_TABLE_ON: TableOn( rInfo ); break; // <table>
+ case HTML_TABLE_OFF: TableOff( rInfo ); break; // </table>
+ case HTML_TABLEROW_ON: mpCurrTable->RowOn( rInfo ); break; // <tr>
+ case HTML_TABLEROW_OFF: mpCurrTable->RowOff( rInfo ); break; // </tr>
+ case HTML_TABLEHEADER_ON: // <th>
+ case HTML_TABLEDATA_ON: mpCurrTable->DataOn( rInfo ); break; // <td>
+ case HTML_TABLEHEADER_OFF: // </th>
+ case HTML_TABLEDATA_OFF: mpCurrTable->DataOff( rInfo ); break; // </td>
+ case HTML_PREFORMTXT_ON: PreOn( rInfo ); break; // <pre>
+ case HTML_PREFORMTXT_OFF: PreOff( rInfo ); break; // </pre>
+
+// --- formatting ---
+ case HTML_FONT_ON: FontOn( rInfo ); break; // <font>
+
+ case HTML_BIGPRINT_ON: // <big>
+ //! TODO: store current font size, use following size
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 3 ], 100, ATTR_FONT_HEIGHT ) );
+ break;
+ case HTML_SMALLPRINT_ON: // <small>
+ //! TODO: store current font size, use preceding size
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ 0 ], 100, ATTR_FONT_HEIGHT ) );
+ break;
+
+ case HTML_BOLD_ON: // <b>
+ case HTML_STRONG_ON: // <strong>
+ mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ break;
+
+ case HTML_ITALIC_ON: // <i>
+ case HTML_EMPHASIS_ON: // <em>
+ case HTML_ADDRESS_ON: // <address>
+ case HTML_BLOCKQUOTE_ON: // <blockquote>
+ case HTML_BLOCKQUOTE30_ON: // <bq>
+ case HTML_CITIATION_ON: // <cite>
+ case HTML_VARIABLE_ON: // <var>
+ mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ break;
+
+ case HTML_DEFINSTANCE_ON: // <dfn>
+ mpCurrTable->PutItem( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ mpCurrTable->PutItem( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ break;
+
+ case HTML_UNDERLINE_ON: // <u>
+ mpCurrTable->PutItem( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+ break;
+ }
+}
+
+void ScHTMLQueryParser::InsertText( const ImportInfo& rInfo )
+{
+ mpCurrTable->PutText( rInfo );
+ if( mbTitleOn )
+ maTitle.Append( rInfo.aText );
+}
+
+void ScHTMLQueryParser::FontOn( const ImportInfo& rInfo )
+{
+ for( ScHTMLOptionIterator aIter( rInfo ); aIter.is(); ++aIter )
+ {
+ switch( aIter->GetToken() )
+ {
+ case HTML_O_FACE :
+ {
+ const String& rFace = aIter->GetString();
+ String aFontName;
+ xub_StrLen nPos = 0;
+ while( nPos != STRING_NOTFOUND )
+ {
+ // font list separator: VCL = ';' HTML = ','
+ String aFName = rFace.GetToken( 0, ',', nPos );
+ aFName.EraseLeadingAndTrailingChars();
+ ScGlobal::AddToken( aFontName, aFName, ';' );
+ }
+ if ( aFontName.Len() )
+ mpCurrTable->PutItem( SvxFontItem( FAMILY_DONTKNOW,
+ aFontName, EMPTY_STRING, PITCH_DONTKNOW,
+ RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ }
+ break;
+ case HTML_O_SIZE :
+ {
+ sal_uInt32 nSize = getLimitedValue< sal_uInt32 >( aIter->GetNumber(), 1, SC_HTML_FONTSIZES );
+ mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ nSize - 1 ], 100, ATTR_FONT_HEIGHT ) );
+ }
+ break;
+ case HTML_O_COLOR :
+ {
+ Color aColor;
+ aIter->GetColor( aColor );
+ mpCurrTable->PutItem( SvxColorItem( aColor, ATTR_FONT_COLOR ) );
+ }
+ break;
+ }
+ }
+}
+
+void ScHTMLQueryParser::MetaOn( const ImportInfo& rInfo )
+{
+ if( mpDoc->GetDocumentShell() )
+ {
+ HTMLParser* pParser = static_cast< HTMLParser* >( rInfo.pParser );
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ pParser->ParseMetaOptions(
+ xDPS->getDocumentProperties(),
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
+ }
+}
+
+void ScHTMLQueryParser::TitleOn( const ImportInfo& /*rInfo*/ )
+{
+ mbTitleOn = true;
+ maTitle.Erase();
+}
+
+void ScHTMLQueryParser::TitleOff( const ImportInfo& rInfo )
+{
+ if( mbTitleOn )
+ {
+ maTitle.EraseLeadingAndTrailingChars();
+ if( maTitle.Len() && mpDoc->GetDocumentShell() ) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+
+ xDPS->getDocumentProperties()->setTitle(maTitle);
+ }
+ InsertText( rInfo );
+ mbTitleOn = false;
+ }
+}
+
+void ScHTMLQueryParser::TableOn( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->TableOn( rInfo );
+}
+
+void ScHTMLQueryParser::TableOff( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->TableOff( rInfo );
+}
+
+void ScHTMLQueryParser::PreOn( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->PreOn( rInfo );
+}
+
+void ScHTMLQueryParser::PreOff( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->PreOff( rInfo );
+}
+
+void ScHTMLQueryParser::CloseTable( const ImportInfo& rInfo )
+{
+ mpCurrTable = mpCurrTable->CloseTable( rInfo );
+}
+
+// ----------------------------------------------------------------------------
+
+IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
+{
+ switch( pInfo->eState )
+ {
+ case HTMLIMP_START:
+ break;
+
+ case HTMLIMP_NEXTTOKEN:
+ case HTMLIMP_UNKNOWNATTR:
+ ProcessToken( *pInfo );
+ break;
+
+ case HTMLIMP_INSERTPARA:
+ mpCurrTable->InsertPara( *pInfo );
+ break;
+
+ case HTMLIMP_SETATTR:
+ case HTMLIMP_INSERTTEXT:
+ case HTMLIMP_INSERTFIELD:
+ break;
+
+ case HTMLIMP_END:
+ while( mpCurrTable->GetTableId() != SC_HTML_GLOBAL_TABLE )
+ CloseTable( *pInfo );
+ break;
+
+ default:
+ DBG_ERRORFILE( "ScHTMLQueryParser::HTMLImportHdl - unknown ImportInfo::eState" );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/XclExpChangeTrack.hxx b/sc/source/filter/inc/XclExpChangeTrack.hxx
new file mode 100644
index 000000000000..29799635aa2b
--- /dev/null
+++ b/sc/source/filter/inc/XclExpChangeTrack.hxx
@@ -0,0 +1,679 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCLEXPCHANGETRACK_HXX
+#define SC_XCLEXPCHANGETRACK_HXX
+
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <rtl/uuid.h>
+#include "bigrange.hxx"
+#include "chgtrack.hxx"
+#include "xelink.hxx"
+#include "ftools.hxx"
+#include "excrecds.hxx"
+
+//___________________________________________________________________
+
+class ScBaseCell;
+
+//___________________________________________________________________
+// XclExpUserBView - one UserBView record for each user
+
+class XclExpUserBView : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ sal_uInt8 aGUID[ 16 ];
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID );
+
+ inline const sal_uInt8* GetGUID() const { return aGUID; }
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpUserBViewList - list of UserBView records
+
+class XclExpUserBViewList : public ExcEmptyRec, private List
+{
+private:
+ inline XclExpUserBView* _First() { return (XclExpUserBView*) List::First(); }
+ inline XclExpUserBView* _Next() { return (XclExpUserBView*) List::Next(); }
+
+public:
+ XclExpUserBViewList( const ScChangeTrack& rChangeTrack );
+ virtual ~XclExpUserBViewList();
+
+ inline const XclExpUserBView* First() { return (const XclExpUserBView*) List::First(); }
+ inline const XclExpUserBView* Next() { return (const XclExpUserBView*) List::Next(); }
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpUsersViewBegin - begin of view block (one per sheet)
+
+class XclExpUsersViewBegin : public ExcRecord
+{
+private:
+ sal_uInt8 aGUID[ 16 ];
+ sal_uInt32 nCurrTab;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab );
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// XclExpUsersViewEnd - end of view block (one per sheet)
+
+class XclExpUsersViewEnd : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0191 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0198 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0192 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "User Names" stream
+
+class XclExpChTr0x0197 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record without content
+
+class XclExpChTrEmpty : public ExcRecord
+{
+private:
+ sal_uInt16 nRecNum;
+
+public:
+ inline XclExpChTrEmpty( sal_uInt16 nNum ) : nRecNum( nNum ) {}
+ virtual ~XclExpChTrEmpty();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "Revision Log" stream
+
+class XclExpChTr0x0195 : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ virtual ~XclExpChTr0x0195();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+//___________________________________________________________________
+// dummy record for "Revision Log" stream
+
+class XclExpChTr0x0194 : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ DateTime aDateTime;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTr0x0194( const ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTr0x0194();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+inline XclExpChTr0x0194::XclExpChTr0x0194( const ScChangeTrack& rChangeTrack ) :
+ sUsername( rChangeTrack.GetUser() ),
+ aDateTime( rChangeTrack.GetFixDateTime() )
+{
+}
+
+//___________________________________________________________________
+// XclExpChTrHeader - header record, includes action count
+
+class XclExpChTrHeader : public ExcRecord
+{
+private:
+ sal_uInt8 aGUID[ 16 ];
+ sal_uInt32 nCount;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrHeader() : nCount( 0 ) {}
+ virtual ~XclExpChTrHeader();
+
+ inline void SetGUID( const sal_uInt8* pGUID ) { memcpy( aGUID, pGUID, 16 ); }
+ inline void SetCount( sal_uInt32 nNew ) { nCount = nNew; }
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrInfo - header of action group of a user
+
+class XclExpChTrInfo : public ExcRecord
+{
+private:
+ XclExpString sUsername;
+ sal_Int32 mnLogNumber;
+ DateTime aDateTime;
+ sal_uInt8 aGUID[ 16 ];
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrInfo(
+ const String& rUsername,
+ const DateTime& rDateTime,
+ const sal_uInt8* pGUID,
+ sal_Int32 nLogNumber );
+ virtual ~XclExpChTrInfo();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+inline XclExpChTrInfo::XclExpChTrInfo( const String& rUsername, const DateTime& rDateTime, const sal_uInt8* pGUID, sal_Int32 nLogNumber ) :
+ sUsername( rUsername ),
+ mnLogNumber( nLogNumber ),
+ aDateTime( rDateTime )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+//___________________________________________________________________
+// XclExpChTrTabIdBuffer - buffer for tab id's
+
+class XclExpChTrTabIdBuffer
+{
+private:
+ sal_uInt16* pBuffer;
+ sal_uInt16* pLast;
+ sal_uInt16 nBufSize;
+ sal_uInt16 nLastId;
+
+public:
+ XclExpChTrTabIdBuffer( sal_uInt16 nCount );
+ XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy );
+ ~XclExpChTrTabIdBuffer();
+
+ void InitFill( sal_uInt16 nIndex );
+ void InitFillup();
+
+ sal_uInt16 GetId( sal_uInt16 nIndex ) const;
+ void Remove();
+
+ inline sal_uInt16 GetBufferCount() const
+ { return static_cast< sal_uInt16 >( (pLast - pBuffer) + 1 ); }
+ inline void GetBufferCopy( sal_uInt16* pDest ) const
+ { memcpy( pDest, pBuffer, sizeof(sal_uInt16) * GetBufferCount() ); }
+};
+
+//___________________________________________________________________
+// XclExpChTrTabIdBufferList
+
+class XclExpChTrTabIdBufferList : private List
+{
+private:
+ inline XclExpChTrTabIdBuffer* First() { return (XclExpChTrTabIdBuffer*) List::First(); }
+ inline XclExpChTrTabIdBuffer* Next() { return (XclExpChTrTabIdBuffer*) List::Next(); }
+
+public:
+ virtual ~XclExpChTrTabIdBufferList();
+
+ inline void Append( XclExpChTrTabIdBuffer* pNew )
+ { List::Insert( pNew, LIST_APPEND ); }
+};
+
+//___________________________________________________________________
+// XclExpChTrTabId - tab id record
+
+class XclExpChTrTabId : public ExcRecord
+{
+private:
+ sal_uInt16* pBuffer;
+ sal_uInt16 nTabCount;
+ bool mbInRevisionHeaders;
+
+ inline void Clear() { if( pBuffer ) delete[] pBuffer; pBuffer = NULL; }
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ inline XclExpChTrTabId( sal_uInt16 nCount ) :
+ pBuffer( NULL ), nTabCount( nCount ), mbInRevisionHeaders( false ) {}
+ XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer, bool bInRevisionHeaders = false );
+ virtual ~XclExpChTrTabId();
+
+ void Copy( const XclExpChTrTabIdBuffer& rBuffer );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrAction - base class for action records
+
+class XclExpChTrAction : public ExcRecord
+{
+private:
+ String sUsername;
+ DateTime aDateTime;
+ sal_uInt32 nIndex; // action number
+ XclExpChTrAction* pAddAction; // additional record for this action
+ sal_Bool bAccepted;
+
+protected:
+ const XclExpTabInfo& rTabInfo; // for table num export (sc num -> xcl num)
+ const XclExpChTrTabIdBuffer& rIdBuffer; // for table num export (xcl num -> tab id)
+ sal_uInt32 nLength; // this is not the record size
+ sal_uInt16 nOpCode; // EXC_CHTR_OP_***
+ sal_Bool bForceInfo;
+
+ XclExpChTrAction( const XclExpChTrAction& rCopy );
+
+ void SetAddAction( XclExpChTrAction* pAction );
+ void AddDependentContents(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ ScChangeTrack& rChangeTrack );
+
+ inline void Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const;
+ inline void Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const;
+ inline sal_uInt16 GetTabId( SCTAB nTabId ) const;
+ inline void WriteTabId( XclExpStream& rStrm, SCTAB nTabId ) const;
+
+ // save header data, call SaveActionData()
+ virtual void SaveCont( XclExpStream& rStrm );
+ inline sal_Size GetHeaderByteCount() const { return 12; }
+
+ // overload to save action data without header, called by SaveCont()
+ virtual void SaveActionData( XclExpStream& rStrm ) const = 0;
+ // overload to get action size without header, called by GetLen()
+ virtual sal_Size GetActionByteCount() const = 0;
+
+ // do something before writing the record
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ // do something after writing the record
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+ inline sal_uInt32 GetActionNumber() const { return nIndex; }
+ inline sal_Bool GetAccepted() const { return bAccepted; }
+
+public:
+ XclExpChTrAction(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ sal_uInt16 nNewOpCode = EXC_CHTR_OP_UNKNOWN );
+ virtual ~XclExpChTrAction();
+
+ inline const String& GetUsername() const { return sUsername; }
+ inline const DateTime& GetDateTime() const { return aDateTime; }
+ inline const XclExpChTrTabIdBuffer& GetTabIdBuffer() const { return rIdBuffer; }
+ inline sal_Bool ForceInfoRecord() const { return bForceInfo; }
+
+ // set own index & return new index
+ // could be overloaded to use more indexes per action
+ virtual void SetIndex( sal_uInt32& rIndex );
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual sal_Size GetLen() const;
+
+ inline XclExpChTrAction* GetAddAction() { return pAddAction; }
+};
+
+inline void XclExpChTrAction::Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const
+{
+ rStrm << (sal_uInt16) rAddress.Row()
+ << (sal_uInt16) rAddress.Col();
+}
+
+inline void XclExpChTrAction::Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const
+{
+ rStrm << (sal_uInt16) rRange.aStart.Row()
+ << (sal_uInt16) rRange.aEnd.Row()
+ << (sal_uInt16) rRange.aStart.Col()
+ << (sal_uInt16) rRange.aEnd.Col();
+}
+
+inline sal_uInt16 XclExpChTrAction::GetTabId( SCTAB nTab ) const
+{
+ return rIdBuffer.GetId( rTabInfo.GetXclTab( nTab ) );
+}
+
+inline void XclExpChTrAction::WriteTabId( XclExpStream& rStrm, SCTAB nTab ) const
+{
+ rStrm << GetTabId( nTab );
+}
+
+//___________________________________________________________________
+// XclExpChTrData - cell content itself
+
+struct XclExpChTrData
+{
+ XclExpString* pString;
+ XclExpStringRef mpFormattedString;
+ const ScFormulaCell* mpFormulaCell;
+ XclTokenArrayRef mxTokArr;
+ XclExpRefLog maRefLog;
+ double fValue;
+ sal_Int32 nRKValue;
+ sal_uInt16 nType;
+ sal_Size nSize;
+
+ XclExpChTrData();
+ ~XclExpChTrData();
+ void Clear();
+
+ void WriteFormula(
+ XclExpStream& rStrm,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ void Write(
+ XclExpStream& rStrm,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+};
+
+//___________________________________________________________________
+// XclExpChTrCellContent - changed cell content
+
+class XclExpChTrCellContent : public XclExpChTrAction, protected XclExpRoot
+{
+private:
+ XclExpChTrData* pOldData;
+ XclExpChTrData* pNewData;
+ sal_uInt16 nOldLength; // this is not the record size
+
+ void MakeEmptyChTrData( XclExpChTrData*& rpData );
+
+protected:
+ ScAddress aPosition;
+
+ void GetCellData(
+ const XclExpRoot& rRoot,
+ const ScBaseCell* pScCell,
+ XclExpChTrData*& rpData,
+ sal_uInt32& rXclLength1,
+ sal_uInt16& rXclLength2 );
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrCellContent(
+ const ScChangeActionContent& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ virtual ~XclExpChTrCellContent();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrInsert - insert/delete columns/rows
+
+class XclExpChTrInsert : public XclExpChTrAction
+{
+protected:
+ ScRange aRange;
+
+ XclExpChTrInsert( const XclExpChTrInsert& rCopy ) :
+ XclExpChTrAction( rCopy ), aRange( rCopy.aRange ) {}
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrInsert(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTrInsert();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrInsertTab - insert table
+
+class XclExpChTrInsertTab : public XclExpChTrAction, protected XclExpRoot
+{
+private:
+ SCTAB nTab;
+
+protected:
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrInsertTab(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer );
+ virtual ~XclExpChTrInsertTab();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrMoveRange - move cell range
+
+class XclExpChTrMoveRange : public XclExpChTrAction
+{
+protected:
+ ScRange aSourceRange;
+ ScRange aDestRange;
+
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+ virtual void PrepareSaveAction( XclExpStream& rStrm ) const;
+ virtual void CompleteSaveAction( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTrMoveRange(
+ const ScChangeActionMove& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack );
+ virtual ~XclExpChTrMoveRange();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTr0x019A - additional data for delete action
+
+class XclExpChTr0x014A : public XclExpChTrInsert
+{
+protected:
+ virtual void SaveActionData( XclExpStream& rStrm ) const;
+
+public:
+ XclExpChTr0x014A( const XclExpChTrInsert& rAction );
+ virtual ~XclExpChTr0x014A();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetActionByteCount() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChTrActionStack - temporary action stack
+
+class XclExpChTrActionStack : private Stack
+{
+public:
+ virtual ~XclExpChTrActionStack();
+
+ void Push( XclExpChTrAction* pNewRec );
+ inline XclExpChTrAction* Pop() { return (XclExpChTrAction*) Stack::Pop(); }
+
+private:
+ using Stack::Push;
+};
+
+//___________________________________________________________________
+// XclExpChTrRecordList - list of "Revision Log" stream records
+
+class XclExpChTrRecordList : private List
+{
+private:
+ inline ExcRecord* First() { return (ExcRecord*) List::First(); }
+ inline ExcRecord* Next() { return (ExcRecord*) List::Next(); }
+
+public:
+ virtual ~XclExpChTrRecordList();
+
+ using List::Count;
+ void Append( ExcRecord* pNewRec );
+ void Save( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+// XclExpChangeTrack - exports the "Revision Log" stream
+
+class XclExpChangeTrack : protected XclExpRoot
+{
+private:
+ XclExpChTrRecordList aRecList;
+ XclExpChTrActionStack aActionStack;
+ XclExpChTrTabIdBufferList aTabIdBufferList;
+ XclExpChTrTabIdBuffer* pTabIdBuffer;
+
+ ScDocument* pTempDoc; // empty document
+
+ sal_uInt32 nNewAction; // action number, 1-based
+ XclExpChTrHeader* pHeader; // header record for last GUID
+ sal_uInt8 aGUID[ 16 ]; // GUID for action info records
+ sal_Bool bValidGUID;
+
+ ScChangeTrack* CreateTempChangeTrack();
+ void PushActionRecord( const ScChangeAction& rAction );
+
+ sal_Bool WriteUserNamesStream();
+
+public:
+ XclExpChangeTrack( const XclExpRoot& rRoot );
+ ~XclExpChangeTrack();
+
+ void Write();
+ void WriteXml( XclExpXmlStream& rStrm );
+};
+
+//___________________________________________________________________
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/XclImpChangeTrack.hxx b/sc/source/filter/inc/XclImpChangeTrack.hxx
new file mode 100644
index 000000000000..029e334d79d2
--- /dev/null
+++ b/sc/source/filter/inc/XclImpChangeTrack.hxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCLIMPCHANGETRACK_HXX
+#define SC_XCLIMPCHANGETRACK_HXX
+
+#include <tools/datetime.hxx>
+#include "xiroot.hxx"
+#include "xistream.hxx"
+#include "excform.hxx"
+#include "imp_op.hxx"
+
+
+//___________________________________________________________________
+
+class ScBaseCell;
+class ScChangeAction;
+class ScChangeTrack;
+class XclImpChTrFmlConverter;
+
+//___________________________________________________________________
+
+struct XclImpChTrRecHeader
+{
+ sal_uInt32 nSize;
+ sal_uInt32 nIndex;
+ sal_uInt16 nOpCode;
+ sal_uInt16 nAccept;
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
+{
+ rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
+ return rStrm;
+}
+
+//___________________________________________________________________
+
+class XclImpChangeTrack : protected XclImpRoot
+{
+private:
+ XclImpChTrRecHeader aRecHeader;
+ String sOldUsername;
+
+ ScChangeTrack* pChangeTrack;
+ SotStorageStreamRef xInStrm; // input stream
+ XclImpStream* pStrm; // stream import class
+ sal_uInt16 nTabIdCount;
+ sal_Bool bGlobExit; // global exit loop
+
+ enum { nmBase, nmFound, nmNested }
+ eNestedMode; // action with nested content actions
+
+ inline sal_Bool FoundNestedMode() { return eNestedMode == nmFound; }
+
+ void DoAcceptRejectAction( ScChangeAction* pAction );
+ void DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );
+
+ void DoInsertRange( const ScRange& rRange );
+ void DoDeleteRange( const ScRange& rRange );
+
+ inline sal_uInt8 LookAtuInt8();
+ inline double ReadRK();
+ inline sal_Bool ReadBool();
+ inline void Read2DAddress( ScAddress& rAddress );
+ inline void Read2DRange( ScRange& rRange );
+ SCTAB ReadTabNum();
+ void ReadDateTime( DateTime& rDateTime );
+
+ inline void ReadString( String& rString );
+
+ sal_Bool CheckRecord( sal_uInt16 nOpCode );
+
+ void ReadFormula(
+ ScTokenArray*& rpTokenArray,
+ const ScAddress& rPosition );
+ void ReadCell(
+ ScBaseCell*& rpCell,
+ sal_uInt32& rFormat,
+ sal_uInt16 nFlags,
+ const ScAddress& rPosition );
+
+ void ReadChTrInsert(); // 0x0137
+ void ReadChTrInfo(); // 0x0138
+ void ReadChTrCellContent(); // 0x013B
+ void ReadChTrTabId(); // 0x013D
+ void ReadChTrMoveRange(); // 0x0140
+ void ReadChTrInsertTab(); // 0x014D
+ void InitNestedMode(); // 0x014E, 0x0150
+ void ReadNestedRecords();
+ sal_Bool EndNestedMode(); // 0x014F, 0x0151
+
+ void ReadRecords();
+
+public:
+ XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
+ ~XclImpChangeTrack();
+
+ // reads extended 3D ref info following the formulas, returns sc tab nums
+ // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
+ sal_Bool Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo );
+
+ void Apply();
+};
+
+inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
+{
+ pStrm->PushPosition();
+ sal_uInt8 nValue;
+ *pStrm >> nValue;
+ pStrm->PopPosition();
+ return nValue;
+}
+
+inline double XclImpChangeTrack::ReadRK()
+{
+ return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
+}
+
+inline sal_Bool XclImpChangeTrack::ReadBool()
+{
+ return (pStrm->ReaduInt16() != 0);
+}
+
+inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
+{
+ rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+}
+
+inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
+{
+ rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
+ rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+ rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
+}
+
+inline void XclImpChangeTrack::ReadString( String& rString )
+{
+ rString = pStrm->ReadUniString();
+}
+
+//___________________________________________________________________
+// derived class for special 3D ref handling
+
+class XclImpChTrFmlConverter : public ExcelToSc8
+{
+private:
+ XclImpChangeTrack& rChangeTrack;
+
+ virtual bool Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );
+
+public:
+ inline XclImpChTrFmlConverter(
+ const XclImpRoot& rRoot,
+ XclImpChangeTrack& rXclChTr );
+ virtual ~XclImpChTrFmlConverter();
+};
+
+inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
+ const XclImpRoot& rRoot,
+ XclImpChangeTrack& rXclChTr ) :
+ ExcelToSc8( rRoot ),
+ rChangeTrack( rXclChTr )
+{
+}
+
+//___________________________________________________________________
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/biff.hxx b/sc/source/filter/inc/biff.hxx
new file mode 100644
index 000000000000..d2cba2e8d06a
--- /dev/null
+++ b/sc/source/filter/inc/biff.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_BASE_HXX
+#define SC_BASE_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+
+// Stream wrapper class
+class ScBiffReader
+{
+ protected:
+ sal_uInt16 mnId;
+ sal_uInt16 mnLength;
+ sal_uInt32 mnOffset;
+ SvStream *mpStream;
+ bool mbEndOfFile;
+
+ public:
+ ScBiffReader( SfxMedium& rMedium );
+ ~ScBiffReader();
+ bool recordsLeft() { return mpStream && !mpStream->IsEof(); }
+ bool IsEndOfFile() { return mbEndOfFile; }
+ void SetEof( bool bValue ){ mbEndOfFile = bValue; }
+ bool nextRecord();
+ sal_uInt16 getId() { return mnId; }
+ sal_uInt16 getLength() { return mnLength; }
+ SvStream& getStream() { return *mpStream; }
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/colrowst.hxx b/sc/source/filter/inc/colrowst.hxx
new file mode 100644
index 000000000000..525db195bac1
--- /dev/null
+++ b/sc/source/filter/inc/colrowst.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_COLROWST_HXX
+#define SC_COLROWST_HXX
+
+#include "xiroot.hxx"
+#include <mdds/flat_segment_tree.hpp>
+
+#define XLS_USE_NEW_ROW_CONT 1
+
+
+class XclImpStream;
+
+// ============================================================================
+
+class XclImpColRowSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpColRowSettings( const XclImpRoot& rRoot );
+ virtual ~XclImpColRowSettings();
+
+ void SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec = false );
+ void SetWidthRange( SCCOL nCol1, SCCOL nCol2, sal_uInt16 nWidth );
+ void HideCol( SCCOL nCol );
+ void HideColRange( SCCOL nCol1, SCCOL nCol2 );
+
+ void SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags );
+ void SetHeight( SCROW nRow, sal_uInt16 nHeight );
+ void SetRowSettings( SCROW nRow, sal_uInt16 nHeight, sal_uInt16 nFlags );
+ void SetManualRowHeight( SCROW nScRow );
+
+ void SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex );
+ /** Inserts all column and row settings of the specified sheet, except the hidden flags. */
+ void Convert( SCTAB nScTab );
+ /** Sets the HIDDEN flags at all hidden columns and rows in the specified sheet. */
+ void ConvertHiddenFlags( SCTAB nScTab );
+
+private:
+ ScfUInt16Vec maWidths; /// Column widths in twips.
+ ScfUInt8Vec maColFlags; /// Flags for all columns.
+ ///
+ typedef ::mdds::flat_segment_tree<SCROW, sal_uInt16> RowHeightsType;
+ typedef ::mdds::flat_segment_tree<SCROW, sal_uInt8> RowFlagsType;
+ typedef ::mdds::flat_segment_tree<SCROW, bool> RowHiddenType;
+ RowHeightsType maRowHeights;
+ RowFlagsType maRowFlags;
+ RowHiddenType maHiddenRows;
+
+ SCROW mnLastScRow;
+
+ sal_uInt16 mnDefWidth; /// Default width from DEFCOLWIDTH or STANDARDWIDTH record.
+ sal_uInt16 mnDefHeight; /// Default height from DEFAULTROWHEIGHT record.
+ sal_uInt16 mnDefRowFlags; /// Default row flags from DEFAULTROWHEIGHT record.
+
+ bool mbHasStdWidthRec; /// true = Width from STANDARDWIDTH (overrides DEFCOLWIDTH record).
+ bool mbHasDefHeight; /// true = mnDefHeight and mnDefRowFlags are valid.
+ bool mbDirty;
+};
+
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/decl.h b/sc/source/filter/inc/decl.h
new file mode 100644
index 000000000000..91157cf9a9a8
--- /dev/null
+++ b/sc/source/filter/inc/decl.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_DECL_H
+#define SC_DECL_H
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+enum WKTYP { eWK_UNKNOWN = -2, eWK_1 = 0, eWK_2, eWK3, eWK4, eWK_Error, eWK123 };
+typedef void ( BEARBFKT )( void );
+typedef sal_Char STRING16[ 16 ];
+typedef sal_Char STRING14[ 14 ];
+typedef sal_Char STRING8[ 8 ];
+typedef sal_Char STRING6[ 6 ];
+typedef sal_uInt16 USHORT4[ 4 ];
+//typedef unsigned short USHORT4[ 4 ];
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/dif.hxx b/sc/source/filter/inc/dif.hxx
new file mode 100644
index 000000000000..374ea301b976
--- /dev/null
+++ b/sc/source/filter/inc/dif.hxx
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_DIF_HXX
+#define SC_DIF_HXX
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <tools/string.hxx>
+
+#include "address.hxx"
+#include "global.hxx"
+
+class SvStream;
+class SvNumberFormatter;
+class ScDocument;
+class ScPatternAttr;
+
+extern const sal_Unicode pKeyTABLE[];
+extern const sal_Unicode pKeyVECTORS[];
+extern const sal_Unicode pKeyTUPLES[];
+extern const sal_Unicode pKeyDATA[];
+extern const sal_Unicode pKeyBOT[];
+extern const sal_Unicode pKeyEOD[];
+extern const sal_Unicode pKeyTRUE[];
+extern const sal_Unicode pKeyFALSE[];
+extern const sal_Unicode pKeyNA[];
+extern const sal_Unicode pKeyV[];
+extern const sal_Unicode pKey1_0[];
+
+enum TOPIC
+{
+ T_UNKNOWN,
+ T_TABLE, T_VECTORS, T_TUPLES, T_DATA, T_LABEL, T_COMMENT, T_SIZE,
+ T_PERIODICITY, T_MAJORSTART, T_MINORSTART, T_TRUELENGTH, T_UINITS,
+ T_DISPLAYUNITS,
+ T_END
+};
+
+enum DATASET { D_BOT, D_EOD, D_NUMERIC, D_STRING, D_UNKNOWN, D_SYNT_ERROR };
+
+class DifAttrCache;
+class ScPatternAttr;
+
+class DifParser
+{
+public:
+ String aData;
+ double fVal;
+ sal_uInt32 nVector;
+ sal_uInt32 nVal;
+ sal_uInt32 nNumFormat;
+ CharSet eCharSet;
+private:
+ SvNumberFormatter* pNumFormatter;
+ SvStream& rIn;
+ sal_Bool bPlain;
+ String aLookAheadLine;
+
+ bool ReadNextLine( String& rStr );
+ bool LookAhead();
+ DATASET GetNumberDataset( const sal_Unicode* pPossibleNumericData );
+ static inline sal_Bool IsBOT( const sal_Unicode* pRef );
+ static inline sal_Bool IsEOD( const sal_Unicode* pRef );
+ static inline sal_Bool Is1_0( const sal_Unicode* pRef );
+public:
+ DifParser( SvStream&, const sal_uInt32 nOption, ScDocument&, CharSet );
+
+ TOPIC GetNextTopic( void );
+
+ DATASET GetNextDataset( void );
+
+ const sal_Unicode* ScanIntVal( const sal_Unicode* pStart, sal_uInt32& rRet );
+ sal_Bool ScanFloatVal( const sal_Unicode* pStart );
+
+ inline sal_Bool IsNumber( const sal_Unicode cChar );
+ inline sal_Bool IsNumberEnding( const sal_Unicode cChar );
+
+ static inline sal_Bool IsV( const sal_Unicode* pRef );
+
+ inline sal_Bool IsPlain( void ) const;
+};
+
+inline sal_Bool DifParser::IsBOT( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyBOT[0] &&
+ pRef[ 1 ] == pKeyBOT[1] &&
+ pRef[ 2 ] == pKeyBOT[2] &&
+ pRef[ 3 ] == pKeyBOT[3] );
+}
+
+inline sal_Bool DifParser::IsEOD( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyEOD[0] &&
+ pRef[ 1 ] == pKeyEOD[1] &&
+ pRef[ 2 ] == pKeyEOD[2] &&
+ pRef[ 3 ] == pKeyEOD[3] );
+}
+
+inline sal_Bool DifParser::Is1_0( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKey1_0[0] &&
+ pRef[ 1 ] == pKey1_0[1] &&
+ pRef[ 2 ] == pKey1_0[2] &&
+ pRef[ 3 ] == pKey1_0[3] );
+}
+
+inline sal_Bool DifParser::IsV( const sal_Unicode* pRef )
+{
+ return ( pRef[ 0 ] == pKeyV[0] &&
+ pRef[ 1 ] == pKeyV[1] );
+}
+
+inline sal_Bool DifParser::IsNumber( const sal_Unicode cChar )
+{
+ return ( cChar >= '0' && cChar <= '9' );
+}
+
+inline sal_Bool DifParser::IsNumberEnding( const sal_Unicode cChar )
+{
+ return ( cChar == 0x00 );
+}
+
+inline sal_Bool DifParser::IsPlain( void ) const
+{
+ return bPlain;
+}
+
+class DifColumn
+{
+ friend class DifAttrCache;
+
+ struct ENTRY
+ {
+ sal_uInt32 nNumFormat;
+ SCROW nStart;
+ SCROW nEnd;
+ };
+
+ ENTRY *pAkt;
+ boost::ptr_vector<ENTRY> aEntries;
+
+ DifColumn();
+
+ void SetLogical( SCROW nRow );
+
+ void SetNumFormat( SCROW nRow, const sal_uInt32 nNumFormat );
+
+ void NewEntry( const SCROW nPos, const sal_uInt32 nNumFormat );
+
+ void Apply( ScDocument&, const SCCOL nCol, const SCTAB nTab, const ScPatternAttr& );
+
+ void Apply( ScDocument &rDoc, const SCCOL nCol, const SCTAB nTab );
+};
+
+class DifAttrCache
+{
+public:
+
+ DifAttrCache( const sal_Bool bPlain );
+
+ ~DifAttrCache();
+
+ void SetLogical( const SCCOL nCol, const SCROW nRow );
+
+ void SetNumFormat( const SCCOL nCol, const SCROW nRow, const sal_uInt32 nNumFormat );
+
+ void Apply( ScDocument&, SCTAB nTab );
+
+private:
+
+ DifColumn** ppCols;
+ sal_Bool bPlain;
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/eeimport.hxx b/sc/source/filter/inc/eeimport.hxx
new file mode 100644
index 000000000000..ed74cc22c140
--- /dev/null
+++ b/sc/source/filter/inc/eeimport.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_EEIMPORT_HXX
+#define SC_EEIMPORT_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include "filter.hxx"
+#include "scdllapi.h"
+
+class ScDocument;
+class ScEEParser;
+class ScTabEditEngine;
+class SvStream;
+class Table;
+
+struct ScEEParseEntry;
+
+class ScEEImport : public ScEEAbsImport
+{
+protected:
+ ScRange maRange;
+ ScDocument* mpDoc;
+ ScEEParser* mpParser;
+ ScTabEditEngine* mpEngine;
+ Table* mpRowHeights;
+
+ sal_Bool GraphicSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* );
+ void InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* );
+public:
+ ScEEImport( ScDocument* pDoc, const ScRange& rRange );
+ virtual ~ScEEImport();
+
+ virtual sal_uLong Read( SvStream& rStream, const String& rBaseURL );
+ virtual ScRange GetRange() { return maRange; }
+ virtual void WriteToDocument( sal_Bool bSizeColsRows = false,
+ double nOutputFactor = 1.0,
+ SvNumberFormatter* pFormatter = NULL,
+ bool bConvertDate = true );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/eeparser.hxx b/sc/source/filter/inc/eeparser.hxx
new file mode 100644
index 000000000000..0f5e2ddc627e
--- /dev/null
+++ b/sc/source/filter/inc/eeparser.hxx
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EEPARSER_HXX
+#define SC_EEPARSER_HXX
+
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#include <vcl/graph.hxx>
+#include <tools/table.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/editdata.hxx>
+#include <address.hxx>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <vector>
+
+const sal_Char nHorizontal = 1;
+const sal_Char nVertical = 2;
+const sal_Char nHoriVerti = nHorizontal | nVertical;
+
+struct ScHTMLImage
+{
+ String aURL;
+ Size aSize;
+ Point aSpace;
+ String aFilterName;
+ Graphic* pGraphic; // wird von WriteToDocument uebernommen
+ sal_Char nDir; // 1==hori, 2==verti, 3==beides
+
+ ScHTMLImage() :
+ aSize( 0, 0 ), aSpace( 0, 0 ), pGraphic( NULL ),
+ nDir( nHorizontal )
+ {}
+ ~ScHTMLImage()
+ { if ( pGraphic ) delete pGraphic; }
+};
+
+struct ScEEParseEntry
+{
+ SfxItemSet aItemSet;
+ ESelection aSel; // Selection in EditEngine
+ String* pValStr; // HTML evtl. SDVAL String
+ String* pNumStr; // HTML evtl. SDNUM String
+ String* pName; // HTML evtl. Anchor/RangeName
+ String aAltText; // HTML IMG ALT Text
+ boost::ptr_vector< ScHTMLImage > maImageList; // Grafiken in dieser Zelle
+ SCCOL nCol; // relativ zum Beginn des Parse
+ SCROW nRow;
+ sal_uInt16 nTab; // HTML TableInTable
+ sal_uInt16 nTwips; // RTF ColAdjust etc.
+ SCCOL nColOverlap; // merged cells wenn >1
+ SCROW nRowOverlap; // merged cells wenn >1
+ sal_uInt16 nOffset; // HTML PixelOffset
+ sal_uInt16 nWidth; // HTML PixelWidth
+ bool bHasGraphic; // HTML any image loaded
+ bool bEntirePara; // TRUE = use entire paragraph, false = use selection
+
+ ScEEParseEntry( SfxItemPool* pPool ) :
+ aItemSet( *pPool ), pValStr( NULL ),
+ pNumStr( NULL ), pName( NULL ),
+ nCol(SCCOL_MAX), nRow(SCROW_MAX), nTab(0),
+ nColOverlap(1), nRowOverlap(1),
+ nOffset(0), nWidth(0), bHasGraphic(false), bEntirePara(true)
+ {}
+ ScEEParseEntry( const SfxItemSet& rItemSet ) :
+ aItemSet( rItemSet ), pValStr( NULL ),
+ pNumStr( NULL ), pName( NULL ),
+ nCol(SCCOL_MAX), nRow(SCROW_MAX), nTab(0),
+ nColOverlap(1), nRowOverlap(1),
+ nOffset(0), nWidth(0), bHasGraphic(false), bEntirePara(true)
+ {}
+ ~ScEEParseEntry()
+ {
+ if ( pValStr )
+ delete pValStr;
+ if ( pNumStr )
+ delete pNumStr;
+ if ( pName )
+ delete pName;
+ if ( maImageList.size() )
+ maImageList.clear();
+ }
+};
+
+
+class EditEngine;
+
+class ScEEParser
+{
+protected:
+ EditEngine* pEdit;
+ SfxItemPool* pPool;
+ SfxItemPool* pDocPool;
+ ::std::vector< ScEEParseEntry* > maList;
+ ScEEParseEntry* pActEntry;
+ Table* pColWidths;
+ int nLastToken;
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ SCCOL nColMax;
+ SCROW nRowMax;
+
+ void NewActEntry( ScEEParseEntry* );
+
+public:
+ ScEEParser( EditEngine* );
+ virtual ~ScEEParser();
+
+ virtual sal_uLong Read( SvStream&, const String& rBaseURL ) = 0;
+
+ Table* GetColWidths() const { return pColWidths; }
+ void GetDimensions( SCCOL& nCols, SCROW& nRows ) const
+ { nCols = nColMax; nRows = nRowMax; }
+
+ inline size_t ListSize() const{ return maList.size(); }
+ ScEEParseEntry* ListEntry( size_t index ) { return maList[ index ]; }
+ const ScEEParseEntry* ListEntry( size_t index ) const { return maList[ index ]; }
+};
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excdefs.hxx b/sc/source/filter/inc/excdefs.hxx
new file mode 100644
index 000000000000..ae8a1cd4c861
--- /dev/null
+++ b/sc/source/filter/inc/excdefs.hxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCDEFS_HXX
+#define SC_EXCDEFS_HXX
+
+#include <sal/types.h>
+
+// (0x009B, 0x009D, 0x009E) AUTOFILTER ========================================
+
+// flags
+const sal_uInt16 EXC_AFFLAG_AND = 0x0000;
+const sal_uInt16 EXC_AFFLAG_OR = 0x0001;
+const sal_uInt16 EXC_AFFLAG_ANDORMASK = 0x0003;
+const sal_uInt16 EXC_AFFLAG_SIMPLE1 = 0x0004;
+const sal_uInt16 EXC_AFFLAG_SIMPLE2 = 0x0008;
+const sal_uInt16 EXC_AFFLAG_TOP10 = 0x0010;
+const sal_uInt16 EXC_AFFLAG_TOP10TOP = 0x0020;
+const sal_uInt16 EXC_AFFLAG_TOP10PERC = 0x0040;
+
+// data types
+const sal_uInt8 EXC_AFTYPE_NOTUSED = 0x00;
+const sal_uInt8 EXC_AFTYPE_RK = 0x02;
+const sal_uInt8 EXC_AFTYPE_DOUBLE = 0x04;
+const sal_uInt8 EXC_AFTYPE_STRING = 0x06;
+const sal_uInt8 EXC_AFTYPE_BOOLERR = 0x08;
+const sal_uInt8 EXC_AFTYPE_INVALID = 0x0A;
+const sal_uInt8 EXC_AFTYPE_EMPTY = 0x0C;
+const sal_uInt8 EXC_AFTYPE_NOTEMPTY = 0x0E;
+
+// comparison operands
+const sal_uInt8 EXC_AFOPER_NONE = 0x00;
+const sal_uInt8 EXC_AFOPER_LESS = 0x01;
+const sal_uInt8 EXC_AFOPER_EQUAL = 0x02;
+const sal_uInt8 EXC_AFOPER_LESSEQUAL = 0x03;
+const sal_uInt8 EXC_AFOPER_GREATER = 0x04;
+const sal_uInt8 EXC_AFOPER_NOTEQUAL = 0x05;
+const sal_uInt8 EXC_AFOPER_GREATEREQUAL = 0x06;
+
+// (0x00AE, 0x00AF) SCENARIO, SCENMAN =========================================
+
+#define EXC_SCEN_MAXCELL 32
+
+// defines for change tracking ================================================
+
+#define EXC_STREAM_USERNAMES CREATE_STRING( "User Names" )
+#define EXC_STREAM_REVLOG CREATE_STRING( "Revision Log" )
+
+// opcodes
+#define EXC_CHTR_OP_COLFLAG 0x0001
+#define EXC_CHTR_OP_DELFLAG 0x0002
+#define EXC_CHTR_OP_INSROW 0x0000
+#define EXC_CHTR_OP_INSCOL EXC_CHTR_OP_COLFLAG
+#define EXC_CHTR_OP_DELROW EXC_CHTR_OP_DELFLAG
+#define EXC_CHTR_OP_DELCOL (EXC_CHTR_OP_COLFLAG|EXC_CHTR_OP_DELFLAG)
+#define EXC_CHTR_OP_MOVE 0x0004
+#define EXC_CHTR_OP_INSTAB 0x0005
+#define EXC_CHTR_OP_CELL 0x0008
+#define EXC_CHTR_OP_RENAME 0x0009
+#define EXC_CHTR_OP_NAME 0x000A
+#define EXC_CHTR_OP_FORMAT 0x000B
+#define EXC_CHTR_OP_UNKNOWN 0xFFFF
+
+// data types
+#define EXC_CHTR_TYPE_MASK 0x0007
+#define EXC_CHTR_TYPE_FORMATMASK 0xFF00
+#define EXC_CHTR_TYPE_EMPTY 0x0000
+#define EXC_CHTR_TYPE_RK 0x0001
+#define EXC_CHTR_TYPE_DOUBLE 0x0002
+#define EXC_CHTR_TYPE_STRING 0x0003
+#define EXC_CHTR_TYPE_BOOL 0x0004
+#define EXC_CHTR_TYPE_FORMULA 0x0005
+
+// accept flags
+#define EXC_CHTR_NOTHING 0x0000
+#define EXC_CHTR_ACCEPT 0x0001
+#define EXC_CHTR_REJECT 0x0003
+
+// ============================================================================
+
+#endif // _EXCDEFS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excdoc.hxx b/sc/source/filter/inc/excdoc.hxx
new file mode 100644
index 000000000000..75c0f2433569
--- /dev/null
+++ b/sc/source/filter/inc/excdoc.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCDOC_HXX
+#define SC_EXCDOC_HXX
+
+#include <tools/solar.h>
+#include "excrecds.hxx"
+#include "xeroot.hxx"
+#include "root.hxx"
+#include <boost/shared_ptr.hpp>
+
+//------------------------------------------------------------------ Forwards -
+
+class SvStream;
+class ScBaseCell;
+class ScHorizontalCellIterator;
+class ScDocument;
+class ScProgress;
+
+class NameBuffer;
+
+class XclExpChangeTrack;
+
+
+//------------------------------------------------------------ class ExcTable -
+
+class XclExpCellTable;
+
+class ExcTable : public XclExpRecordBase, public XclExpRoot
+{
+private:
+ typedef XclExpRecordList< ExcBundlesheetBase > ExcBoundsheetList;
+ typedef boost::shared_ptr< XclExpCellTable > XclExpCellTableRef;
+
+ XclExpRecordList<> aRecList;
+ XclExpCellTableRef mxCellTable;
+
+ SCTAB mnScTab; // table number SC document
+ sal_uInt16 nExcTab; // table number Excel document
+ sal_uInt16 nAktRow; // fuer'n Iterator
+ sal_uInt16 nAktCol;
+
+ NameBuffer* pTabNames;
+
+ // pRec mit new anlegen und vergessen, delete macht ExcTable selber!
+ void Add( XclExpRecordBase* pRec );
+
+ void FillAsXmlTable( SCTAB nCodeNameIdx );
+
+public:
+ ExcTable( const XclExpRoot& rRoot );
+ ExcTable( const XclExpRoot& rRoot, SCTAB nScTab );
+ ~ExcTable();
+
+ void FillAsHeader( ExcBoundsheetList& rBoundsheetList );
+ void FillAsTable( SCTAB nCodeNameIdx );
+ void FillAsEmptyTable( SCTAB nCodeNameIdx );
+
+ void Write( XclExpStream& );
+ void WriteXml( XclExpXmlStream& );
+};
+
+
+//--------------------------------------------------------- class ExcDocument -
+
+class ExcDocument : protected XclExpRoot
+{
+friend class ExcTable;
+
+private:
+ typedef XclExpRecordList< ExcTable > ExcTableList;
+ typedef ExcTableList::RecordRefType ExcTableRef;
+ typedef XclExpRecordList< ExcBundlesheetBase > ExcBoundsheetList;
+ typedef ExcBoundsheetList::RecordRefType ExcBoundsheetRef;
+
+ ExcTable aHeader;
+
+ ExcTableList maTableList;
+ ExcBoundsheetList maBoundsheetList;
+
+ XclExpChangeTrack* pExpChangeTrack;
+
+public:
+ explicit ExcDocument( const XclExpRoot& rRoot );
+ virtual ~ExcDocument();
+
+ void ReadDoc( void );
+ void Write( SvStream& rSvStrm );
+ void WriteXml( XclExpXmlStream& );
+};
+
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
new file mode 100644
index 000000000000..ebc3696e9a0f
--- /dev/null
+++ b/sc/source/filter/inc/excform.hxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCFORM_HXX
+#define SC_EXCFORM_HXX
+
+#include "xlformula.hxx"
+#include "xiroot.hxx"
+#include "formel.hxx"
+
+#include <vector>
+
+class ScRangeList;
+
+
+class ExcelToSc : public ExcelConverterBase, protected XclImpRoot
+{
+protected:
+ enum ExtensionType { EXTENSION_ARRAY, EXTENSION_NLR, EXTENSION_MEMAREA };
+ typedef ::std::vector< ExtensionType > ExtensionTypeVec;
+
+ sal_Bool bExternName; // wenn External Name gefunden wurde
+ static const sal_uInt16 nRowMask;
+ static const sal_uInt16 nLastInd; // letzter Index fuer Excel->SC-
+ // Token Umsetzung
+ XclFunctionProvider maFuncProv;
+ const XclBiff meBiff;
+
+ // ---------------------------------------------------------------
+ void DoMulArgs( DefTokenId eId, sal_uInt8 nNumArgs );
+
+ void ExcRelToScRel( sal_uInt16 nRow, sal_uInt8 nCol, ScSingleRefData&, const sal_Bool bName );
+
+public:
+ ExcelToSc( const XclImpRoot& rRoot );
+ virtual ~ExcelToSc();
+ virtual ConvErr Convert( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen,
+ bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, SCsTAB nTab, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const ::std::vector<String>& rTabNames );
+
+ virtual sal_Bool GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
+
+ void GetDummy( const ScTokenArray*& );
+ const ScTokenArray* GetBoolErr( XclBoolError );
+ sal_Bool GetShrFmla( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen );
+
+ static void SetError( ScFormulaCell& rCell, const ConvErr eErr );
+
+ static inline sal_Bool IsComplColRange( const sal_uInt16 nCol1, const sal_uInt16 nCol2 );
+ static inline sal_Bool IsComplRowRange( const sal_uInt16 nRow1, const sal_uInt16 nRow2 );
+
+ void SetComplCol( ScComplexRefData& );
+ void SetComplRow( ScComplexRefData& );
+
+ void ReadExtensions( const ExtensionTypeVec& rExtensions,
+ XclImpStream& aIn );
+ void ReadExtensionArray( unsigned int n,
+ XclImpStream& aIn );
+ void ReadExtensionNlr( XclImpStream& aIn );
+ void ReadExtensionMemArea( XclImpStream& aIn );
+};
+
+
+inline sal_Bool ExcelToSc::IsComplColRange( const sal_uInt16 nCol1, const sal_uInt16 nCol2 )
+{
+ return ( nCol1 == 0x00 ) && ( nCol2 == 0xFF );
+}
+
+
+inline sal_Bool ExcelToSc::IsComplRowRange( const sal_uInt16 nRow1, const sal_uInt16 nRow2 )
+{
+ return ( ( nRow1 & 0x3FFF ) == 0x0000 ) && ( ( nRow2 & 0x3FFF ) == 0x3FFF );
+}
+
+// ============================================================================
+
+class XclImpLinkManager;
+class XclImpExtName;
+
+class ExcelToSc8 : public ExcelToSc
+{
+public:
+
+ struct ExternalTabInfo
+ {
+ ScRange maRange;
+ ::rtl::OUString maTabName;
+ sal_uInt16 mnFileId;
+ bool mbExternal;
+
+ ExternalTabInfo();
+ };
+
+private:
+ const XclImpLinkManager& rLinkMan;
+
+ void ExcRelToScRel8( sal_uInt16 nRow, sal_uInt16 nCol, ScSingleRefData&,
+ const sal_Bool bName );
+
+ bool GetExternalFileIdFromXti( sal_uInt16 nIxti, sal_uInt16& rFileId ) const;
+
+ virtual bool Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );
+
+ bool HandleOleLink(sal_uInt16 nXtiIndex, const XclImpExtName& rExtName, ExternalTabInfo& rExtInfo);
+public:
+ ExcelToSc8( const XclImpRoot& rRoot );
+ virtual ~ExcelToSc8();
+
+ virtual ConvErr Convert( const ScTokenArray*& rpTokArray, XclImpStream& rStrm, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, SCsTAB nTab, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
+ const String& rUrl, const ::std::vector<String>& rTabNames );
+
+ static inline sal_Bool IsComplRowRange( const sal_uInt16 nRow1, const sal_uInt16 nRow2 );
+
+ virtual sal_Bool GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
+};
+
+
+inline sal_Bool ExcelToSc8::IsComplRowRange( const sal_uInt16 nRow1, const sal_uInt16 nRow2 )
+{
+ return ( nRow1 == 0x0000 ) && ( nRow2 == 0xFFFF );
+}
+
+
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx
new file mode 100644
index 000000000000..923bec596d88
--- /dev/null
+++ b/sc/source/filter/inc/excimp8.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCIMP8_HXX
+#define SC_EXCIMP8_HXX
+
+#include <string.h>
+#include "imp_op.hxx"
+#include "root.hxx"
+#include "excscen.hxx"
+#include "excdefs.hxx"
+#include "ftools.hxx"
+#include "queryparam.hxx"
+
+class SotStorage;
+
+class ScBaseCell;
+class ScRangeList;
+class ScDBData;
+
+class ScfSimpleProgressBar;
+
+class XclImpStream;
+
+
+
+class ImportExcel8 : public ImportExcel
+{
+public:
+ ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm );
+ virtual ~ImportExcel8( void );
+
+ virtual FltError Read( void );
+
+protected:
+ // represents codename ( and associated modules )
+ // not speficied directly in the binary format
+ std::vector< String > AutoGeneratedCodeNames;
+ ExcScenarioList aScenList;
+
+ void Calccount( void ); // 0x0C
+ void Precision( void ); // 0x0E
+ void Delta( void ); // 0x10
+ void Iteration( void ); // 0x11
+ void Boundsheet( void ); // 0x85
+ void FilterMode( void ); // 0x9B
+ void AutoFilterInfo( void ); // 0x9D
+ void AutoFilter( void ); // 0x9E
+ void Scenman( void ); // 0xAE
+ void Scenario( void ); // 0xAF
+ void ReadBasic( void ); // 0xD3
+ void Labelsst( void ); // 0xFD
+
+ void Hlink( void ); // 0x01B8
+ void Codename( sal_Bool bWBGlobals ); // 0x01BA
+ void SheetProtection( void ); // 0x0867
+
+ virtual void EndSheet( void );
+ virtual void PostDocLoad( void );
+
+private:
+ void LoadDocumentProperties();
+};
+
+
+
+//___________________________________________________________________
+// classes AutoFilterData, AutoFilterBuffer
+
+class XclImpAutoFilterData : private ExcRoot
+{
+private:
+ ScDBData* pCurrDBData;
+ ScQueryParam aParam;
+ SCSIZE nFirstEmpty;
+ sal_Bool bActive;
+ sal_Bool bHasConflict;
+ sal_Bool bCriteria;
+ sal_Bool bAutoOrAdvanced;
+ ScRange aCriteriaRange;
+
+ void CreateFromDouble( String& rStr, double fVal );
+ void SetCellAttribs();
+ void InsertQueryParam();
+ void AmendAFName(const sal_Bool bUseUnNamed);
+
+protected:
+public:
+ XclImpAutoFilterData(
+ RootData* pRoot,
+ const ScRange& rRange);
+
+ inline bool IsActive() const { return bActive; }
+ inline bool IsFiltered() const { return bAutoOrAdvanced; }
+ inline SCTAB Tab() const { return aParam.nTab; }
+ inline SCCOL StartCol() const { return aParam.nCol1; }
+ inline SCROW StartRow() const { return aParam.nRow1; }
+ inline SCCOL EndCol() const { return aParam.nCol2; }
+ inline SCROW EndRow() const { return aParam.nRow2; }
+
+ void ReadAutoFilter( XclImpStream& rStrm );
+
+ inline void Activate() { bActive = sal_True; }
+ void SetAdvancedRange( const ScRange* pRange );
+ void SetExtractPos( const ScAddress& rAddr );
+ inline void SetAutoOrAdvanced() { bAutoOrAdvanced = sal_True; }
+ void Apply();
+ void CreateScDBData();
+ void EnableRemoveFilter();
+};
+
+
+class XclImpAutoFilterBuffer : private List
+{
+private:
+ using List::Insert;
+
+ inline XclImpAutoFilterData* _First() { return (XclImpAutoFilterData*) List::First(); }
+ inline XclImpAutoFilterData* _Next() { return (XclImpAutoFilterData*) List::Next(); }
+
+ inline void Append( XclImpAutoFilterData* pData )
+ { List::Insert( pData, LIST_APPEND ); }
+protected:
+public:
+ XclImpAutoFilterBuffer();
+ virtual ~XclImpAutoFilterBuffer();
+
+ void Insert( RootData* pRoot, const ScRange& rRange);
+ void AddAdvancedRange( const ScRange& rRange );
+ void AddExtractPos( const ScRange& rRange );
+ void Apply();
+
+ XclImpAutoFilterData* GetByTab( SCTAB nTab );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
new file mode 100644
index 000000000000..781f985fa416
--- /dev/null
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -0,0 +1,511 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCRECDS_HXX
+#define SC_EXCRECDS_HXX
+
+#include <tools/solar.h>
+#include <svl/zforlist.hxx>
+#include <tools/string.hxx>
+#include <vcl/vclenum.hxx>
+#include <tools/color.hxx>
+
+
+#include <vector>
+#include "olinetab.hxx"
+#include "filter.hxx"
+#include "rangelst.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+#include "xeformula.hxx"
+#include "xestring.hxx"
+#include "root.hxx"
+#include "excdefs.hxx"
+#include "cell.hxx"
+#include <boost/shared_ptr.hpp>
+
+//------------------------------------------------------------------ Forwards -
+
+class SvStream;
+class Font;
+class List;
+class ScPatternAttr;
+class ScTokenArray;
+class ScRangeData;
+class ScDBData;
+class ScEditCell;
+class SfxItemSet;
+class EditTextObject;
+class ScPageHFItem;
+class ScProgress;
+
+class ExcTable;
+
+//----------------------------------------------------------- class ExcRecord -
+
+class ExcRecord : public XclExpRecord
+{
+public:
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ virtual sal_uInt16 GetNum() const = 0;
+ virtual sal_Size GetLen() const = 0;
+
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+
+//--------------------------------------------------------- class ExcEmptyRec -
+
+class ExcEmptyRec : public ExcRecord
+{
+private:
+protected:
+public:
+ virtual void Save( XclExpStream& rStrm );
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+//------------------------------------------------------- class ExcRecordList -
+
+class ExcRecordList : protected List, public ExcEmptyRec
+{
+private:
+protected:
+public:
+ virtual ~ExcRecordList();
+
+ using List::Count;
+
+ inline ExcRecord* First( void ) { return ( ExcRecord* ) List::First(); }
+ inline ExcRecord* Next( void ) { return ( ExcRecord* ) List::Next(); }
+
+ inline void Append( ExcRecord* pNew ) { if( pNew ) List::Insert( pNew, LIST_APPEND ); }
+ inline const ExcRecord* Get( sal_uInt32 nNum ) const { return ( ExcRecord* ) List::GetObject( nNum ); }
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+//--------------------------------------------------------- class ExcDummyRec -
+
+class ExcDummyRec : public ExcRecord
+{
+protected:
+public:
+ virtual void Save( XclExpStream& rStrm );
+ virtual sal_uInt16 GetNum() const;
+ virtual const sal_uInt8* GetData() const = 0; // byte data must contain header and body
+};
+
+
+//------------------------------------------------------- class ExcBoolRecord -
+// stores sal_Bool as 16bit val ( 0x0000 | 0x0001 )
+
+class ExcBoolRecord : public ExcRecord
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+ sal_Bool bVal;
+
+ inline ExcBoolRecord() : bVal( false ) {}
+
+public:
+ inline ExcBoolRecord( const sal_Bool bDefault ) : bVal( bDefault ) {}
+
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//--------------------------------------------------------- class ExcBof_Base -
+
+class ExcBof_Base : public ExcRecord
+{
+private:
+protected:
+ sal_uInt16 nDocType;
+ sal_uInt16 nVers;
+ sal_uInt16 nRupBuild;
+ sal_uInt16 nRupYear;
+public:
+ ExcBof_Base( void );
+};
+
+
+//-------------------------------------------------------------- class ExcBof -
+// Header Record fuer WORKSHEETS
+
+class ExcBof : public ExcBof_Base
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ ExcBof( void );
+
+ virtual sal_uInt16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//------------------------------------------------------------- class ExcBofW -
+// Header Record fuer WORKBOOKS
+
+class ExcBofW : public ExcBof_Base
+{
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ ExcBofW( void );
+
+ virtual sal_uInt16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//-------------------------------------------------------------- class ExcEof -
+
+class ExcEof : public ExcRecord
+{
+private:
+public:
+ virtual sal_uInt16 GetNum( void ) const;
+ virtual sal_Size GetLen( void ) const;
+};
+
+
+//--------------------------------------------------------- class ExcDummy_00 -
+// INTERFACEHDR to FNGROUPCOUNT (see excrecds.cxx)
+
+class ExcDummy_00 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const sal_uInt8* GetData( void ) const;
+};
+
+// EXC_ID_WINDOWPROTECTION
+class XclExpWindowProtection : public XclExpBoolRecord
+{
+ public:
+ XclExpWindowProtection(bool bValue);
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// EXC_ID_PROTECT Document Protection
+class XclExpProtection : public XclExpBoolRecord
+{
+ public:
+ XclExpProtection(bool bValue);
+};
+
+class XclExpPassHash : public XclExpRecord
+{
+public:
+ XclExpPassHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aHash);
+ virtual ~XclExpPassHash();
+
+private:
+ virtual void WriteBody(XclExpStream& rStrm);
+
+private:
+ sal_uInt16 mnHash;
+};
+
+
+//-------------------------------------------------------- class ExcDummy_04x -
+// PASSWORD to BOOKBOOL (see excrecds.cxx), no 1904
+
+class ExcDummy_040 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const sal_uInt8* GetData( void ) const;
+};
+
+
+
+class ExcDummy_041 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const sal_uInt8* GetData( void ) const;
+};
+
+
+//------------------------------------------------------------- class Exc1904 -
+
+class Exc1904 : public ExcBoolRecord
+{
+public:
+ Exc1904( ScDocument& rDoc );
+ virtual sal_uInt16 GetNum( void ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ sal_Bool bDateCompatibility;
+};
+
+
+//------------------------------------------------------ class ExcBundlesheet -
+
+class ExcBundlesheetBase : public ExcRecord
+{
+protected:
+ sal_Size nStrPos;
+ sal_Size nOwnPos; // Position NACH # und Len
+ sal_uInt16 nGrbit;
+ SCTAB nTab;
+
+ ExcBundlesheetBase();
+
+public:
+ ExcBundlesheetBase( RootData& rRootData, SCTAB nTab );
+
+ inline void SetStreamPos( sal_Size nNewStrPos ) { nStrPos = nNewStrPos; }
+ void UpdateStreamPos( XclExpStream& rStrm );
+
+ virtual sal_uInt16 GetNum() const;
+};
+
+
+
+class ExcBundlesheet : public ExcBundlesheetBase
+{
+private:
+ ByteString aName;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBundlesheet( RootData& rRootData, SCTAB nTab );
+ virtual sal_Size GetLen() const;
+};
+
+//--------------------------------------------------------- class ExcDummy_02 -
+// sheet dummies: CALCMODE to SETUP
+
+class ExcDummy_02a : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen( void ) const;
+ virtual const sal_uInt8* GetData( void ) const;
+};
+
+
+// ----------------------------------------------------------------------------
+
+/** This record contains the Windows country IDs for the UI and document language. */
+class XclExpCountry : public XclExpRecord
+{
+public:
+ explicit XclExpCountry( const XclExpRoot& rRoot );
+
+private:
+ sal_uInt16 mnUICountry; /// The UI country ID.
+ sal_uInt16 mnDocCountry; /// The document country ID.
+
+ /** Writes the body of the COUNTRY record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+
+// XclExpWsbool ===============================================================
+
+class XclExpWsbool : public XclExpUInt16Record
+{
+public:
+ explicit XclExpWsbool( bool bFitToPages, SCTAB nScTab = -1, XclExpFilterManager* pManager = NULL );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ SCTAB mnScTab;
+ XclExpFilterManager* mpManager;
+};
+
+
+// ============================================================================
+
+class XclExpFiltermode : public XclExpEmptyRecord
+{
+public:
+ explicit XclExpFiltermode();
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpAutofilterinfo : public XclExpUInt16Record
+{
+public:
+ explicit XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol );
+
+ inline const ScAddress GetStartPos() const { return maStartPos; }
+ inline SCCOL GetColCount() const { return static_cast< SCCOL >( GetValue() ); }
+
+private:
+ ScAddress maStartPos;
+};
+
+// ----------------------------------------------------------------------------
+
+class ExcFilterCondition
+{
+private:
+ sal_uInt8 nType;
+ sal_uInt8 nOper;
+ double fVal;
+ XclExpString* pText;
+
+protected:
+public:
+ ExcFilterCondition();
+ ~ExcFilterCondition();
+
+ inline sal_Bool IsEmpty() const { return (nType == EXC_AFTYPE_NOTUSED); }
+ inline sal_Bool HasEqual() const { return (nOper == EXC_AFOPER_EQUAL); }
+ sal_uLong GetTextBytes() const;
+
+ void SetCondition( sal_uInt8 nTp, sal_uInt8 nOp, double fV, String* pT );
+
+ void Save( XclExpStream& rStrm );
+ void SaveXml( XclExpXmlStream& rStrm );
+ void SaveText( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpAutofilter : public XclExpRecord, protected XclExpRoot
+{
+private:
+ sal_uInt16 nCol;
+ sal_uInt16 nFlags;
+ ExcFilterCondition aCond[ 2 ];
+
+ sal_Bool AddCondition( ScQueryConnect eConn, sal_uInt8 nType,
+ sal_uInt8 nOp, double fVal, String* pText,
+ sal_Bool bSimple = false );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+protected:
+public:
+ XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC );
+
+ inline sal_uInt16 GetCol() const { return nCol; }
+ inline sal_Bool HasCondition() const { return !aCond[ 0 ].IsEmpty(); }
+ inline sal_Bool HasTop10() const { return ::get_flag( nFlags, EXC_AFFLAG_TOP10 ); }
+
+ sal_Bool AddEntry( const ScQueryEntry& rEntry );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class ExcAutoFilterRecs : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcAutoFilterRecs();
+
+ void AddObjRecs();
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ bool HasFilterMode() const;
+
+private:
+ XclExpAutofilter* GetByCol( SCCOL nCol ); // always 0-based
+ sal_Bool IsFiltered( SCCOL nCol );
+
+private:
+ typedef XclExpRecordList< XclExpAutofilter > XclExpAutofilterList;
+ typedef XclExpAutofilterList::RecordRefType XclExpAutofilterRef;
+
+ XclExpAutofilterList maFilterList;
+ XclExpFiltermode* pFilterMode;
+ XclExpAutofilterinfo* pFilterInfo;
+ ScRange maRef;
+ bool mbAutoFilter;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Sheet filter manager. Contains auto filters or advanced filters from all sheets. */
+class XclExpFilterManager : protected XclExpRoot
+{
+public:
+ explicit XclExpFilterManager( const XclExpRoot& rRoot );
+
+ /** Creates the filter records for the specified sheet.
+ @descr Creates and inserts related built-in NAME records. Therefore this
+ function is called from the name buffer itself. */
+ void InitTabFilter( SCTAB nScTab );
+
+ /** Returns a record object containing all filter records for the specified sheet. */
+ XclExpRecordRef CreateRecord( SCTAB nScTab );
+
+ /** Returns whether or not FilterMode is present */
+ bool HasFilterMode( SCTAB nScTab );
+
+private:
+ using XclExpRoot::CreateRecord;
+
+ typedef boost::shared_ptr< ExcAutoFilterRecs > XclExpTabFilterRef;
+ typedef ::std::map< SCTAB, XclExpTabFilterRef > XclExpTabFilterMap;
+
+ XclExpTabFilterMap maFilterMap;
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/excscen.hxx b/sc/source/filter/inc/excscen.hxx
new file mode 100644
index 000000000000..5b7e3f0d2f59
--- /dev/null
+++ b/sc/source/filter/inc/excscen.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXCSCEN_HXX
+#define SC_EXCSCEN_HXX
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+struct RootData;
+class XclImpRoot;
+class XclImpStream;
+class ScDocument;
+
+class ExcScenarioCell
+{
+private:
+ String aValue;
+public:
+ const sal_uInt16 nCol;
+ const sal_uInt16 nRow;
+
+ ExcScenarioCell( const sal_uInt16 nC, const sal_uInt16 nR );
+
+ inline void SetValue( const String& rVal ) { aValue = rVal; }
+
+ inline const String& GetValue( void ) const { return aValue; }
+};
+
+class ExcScenario
+{
+public:
+
+ ExcScenario( XclImpStream& rIn, const RootData& rRoot );
+
+ ~ExcScenario();
+
+ void Apply( const XclImpRoot& rRoot, const sal_Bool bLast = false );
+
+protected:
+
+ String* pName;
+ String* pComment;
+ String* pUserName;
+ sal_uInt8 nProtected;
+ const sal_uInt16 nTab;
+ boost::ptr_vector<ExcScenarioCell> aEntries;
+};
+
+struct ExcScenarioList
+{
+ ExcScenarioList () : nLastScenario(0) {}
+
+ void Apply( const XclImpRoot& rRoot );
+
+ sal_uInt16 nLastScenario;
+ boost::ptr_vector<ExcScenario> aEntries;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/exp_op.hxx b/sc/source/filter/inc/exp_op.hxx
new file mode 100644
index 000000000000..3dabe04e6070
--- /dev/null
+++ b/sc/source/filter/inc/exp_op.hxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXP_OP_HXX
+#define SC_EXP_OP_HXX
+
+#include "filter.hxx"
+#include "root.hxx"
+#include "xeroot.hxx"
+
+
+class ScDocument;
+class ScPatternAttr;
+class ScFormulaCell;
+class ExcDocument;
+class SotStorage;
+
+
+class ExportTyp
+{
+protected:
+ SvStream& aOut; // Ausgabe-Stream
+ ScDocument* pD; // Dokument
+ CharSet eZielChar; // Ziel-Zeichensatz
+public:
+ ExportTyp( SvStream& aStream, ScDocument* pDoc, CharSet eDest ):
+ aOut( aStream )
+ {
+ eZielChar = eDest;
+ pD = pDoc;
+ }
+
+ virtual FltError Write() = 0;
+};
+
+
+
+#if ENABLE_LOTUS123_EXPORT
+class ExportWK1 : public ExportTyp
+{
+private:
+ sal_uInt8 GenFormByte( const ScPatternAttr& );
+ void Bof();
+ void Eof();
+ void Calcmode();
+ void Calcorder();
+ void Split();
+ void Sync();
+ void Dimensions();
+ void Window1();
+ void Colw();
+ void Blank( const sal_uInt16 nC, const sal_uInt16 nR, const ScPatternAttr& );
+ void Number( const sal_uInt16 nC, const sal_uInt16 nR, const double f, const ScPatternAttr& );
+ void Label( const sal_uInt16 nC, const sal_uInt16 nR, const String&, const ScPatternAttr& );
+ void Formula( const sal_uInt16 nC, const sal_uInt16 nR, const ScFormulaCell*, const ScPatternAttr& );
+ void Protect();
+ void Footer();
+ void Header();
+ void Margins();
+ void Labelfmt();
+ void Calccount();
+ void Cursorw12();
+ void WKString( const sal_uInt16 nC, const sal_uInt16 nR, const ScFormulaCell*, const ScPatternAttr& );
+ void Snrange();
+ void Hidcol();
+ void Cpi();
+public:
+
+ static const sal_uInt16 WK1MAXCOL;
+ static const sal_uInt16 WK1MAXROW;
+
+ inline ExportWK1( SvStream& r, ScDocument* p, CharSet e ) :
+ ExportTyp( r, p, e ) {};
+
+ FltError Write();
+};
+#endif
+
+
+
+class ExportBiff5 : public ExportTyp, protected XclExpRoot
+{
+private:
+ ExcDocument* pExcDoc;
+
+protected:
+ RootData* pExcRoot;
+
+public:
+ ExportBiff5( XclExpRootData& rExpData, SvStream& rStrm );
+ virtual ~ExportBiff5();
+ FltError Write();
+};
+
+
+
+
+class ExportBiff8 : public ExportBiff5
+{
+public:
+ ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm );
+ virtual ~ExportBiff8();
+};
+
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/expbase.hxx b/sc/source/filter/inc/expbase.hxx
new file mode 100644
index 000000000000..fe840674383a
--- /dev/null
+++ b/sc/source/filter/inc/expbase.hxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_EXPBASE_HXX
+#define SC_EXPBASE_HXX
+
+#include <tools/solar.h>
+#include "global.hxx"
+#include "address.hxx"
+
+
+class SvStream;
+class ScFieldEditEngine;
+
+class ScExportBase
+{
+public:
+#if defined UNX
+ static const sal_Char sNewLine;
+#else
+ static const sal_Char sNewLine[];
+#endif
+
+protected:
+
+ SvStream& rStrm;
+ ScRange aRange;
+ ScDocument* pDoc;
+ SvNumberFormatter* pFormatter;
+ ScFieldEditEngine* pEditEngine;
+
+public:
+
+ ScExportBase( SvStream&, ScDocument*, const ScRange& );
+ virtual ~ScExportBase();
+
+ // Hidden Cols/Rows an den Raendern trimmen,
+ // return: sal_True wenn Bereich vorhanden
+ // Start/End/Col/Row muessen gueltige Ausgangswerte sein
+ sal_Bool TrimDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const;
+
+ // Ausgabebereich einer Tabelle ermitteln,
+ // Hidden Cols/Rows an den Raendern beruecksichtigt,
+ // return: sal_True wenn Bereich vorhanden
+ sal_Bool GetDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const;
+
+ // Tabelle nicht vorhanden oder leer
+ sal_Bool IsEmptyTable( SCTAB nTab ) const;
+
+ ScFieldEditEngine& GetEditEngine() const;
+
+};
+
+
+#endif // SC_EXPBASE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/fapihelper.hxx b/sc/source/filter/inc/fapihelper.hxx
new file mode 100644
index 000000000000..36b8c873f213
--- /dev/null
+++ b/sc/source/filter/inc/fapihelper.hxx
@@ -0,0 +1,350 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FAPIHELPER_HXX
+#define SC_FAPIHELPER_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <tools/color.hxx>
+#include <comphelper/types.hxx>
+#include "ftools.hxx"
+#include "scdllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace comphelper { class IDocPasswordVerifier; }
+
+// Static helper functions ====================================================
+
+class SfxMedium;
+class SfxObjectShell;
+
+/** Static API helper functions. */
+class ScfApiHelper
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > XInterfaceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > XServiceFactoryRef;
+ typedef ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > UnoAnySequence;
+
+public:
+ /** Converts a tools color to a UNO color value. */
+ inline static sal_Int32 ConvertToApiColor( const Color& rColor )
+ { return static_cast< sal_Int32 >( rColor.GetColor() ); }
+ /** Converts a UNO color value to a tools color. */
+ inline static Color ConvertFromApiColor( sal_Int32 nApiColor )
+ { return Color( static_cast< ColorData >( nApiColor ) ); }
+
+ /** Converts a non-empty vector into a UNO sequence containing elements of the same type. */
+ template< typename Type >
+ static ::com::sun::star::uno::Sequence< Type >
+ VectorToSequence( const ::std::vector< Type >& rVector );
+
+ /** Returns the service name provided via the XServiceName interface, or an empty string on error. */
+ static ::rtl::OUString GetServiceName( XInterfaceRef xInt );
+
+ /** Returns the multi service factory from a document shell. */
+ static XServiceFactoryRef GetServiceFactory( SfxObjectShell* pShell );
+
+ /** Creates an instance from the passed service name, using the passed service factory. */
+ static XInterfaceRef CreateInstance(
+ XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the service factory of the passed object. */
+ static XInterfaceRef CreateInstance(
+ SfxObjectShell* pShell,
+ const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the process service factory. */
+ static XInterfaceRef CreateInstance( const ::rtl::OUString& rServiceName );
+
+ /** Creates an instance from the passed service name, using the passed service factory. */
+ static XInterfaceRef CreateInstanceWithArgs(
+ XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName,
+ const UnoAnySequence& rArgs );
+
+ /** Creates an instance from the passed service name, using the process service factory. */
+ static XInterfaceRef CreateInstanceWithArgs(
+ const ::rtl::OUString& rServiceName,
+ const UnoAnySequence& rArgs );
+
+ /** Opens a password dialog and returns the encryption data.
+ @return The encryption data or an empty sequence on 'Cancel' or any error. */
+ static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > QueryEncryptionDataForMedium( SfxMedium& rMedium,
+ ::comphelper::IDocPasswordVerifier& rVerifier,
+ const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 );
+};
+
+template< typename Type >
+::com::sun::star::uno::Sequence< Type > ScfApiHelper::VectorToSequence( const ::std::vector< Type >& rVector )
+{
+ DBG_ASSERT( !rVector.empty(), "ScfApiHelper::VectorToSequence - vector is empty" );
+ return ::com::sun::star::uno::Sequence< Type >( &rVector.front(), static_cast< sal_Int32 >( rVector.size() ) );
+}
+
+// Property sets ==============================================================
+
+/** 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 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 XMultiPropertySet interface. If the
+ implementation does not support the XMultiPropertySet interface, all
+ properties are handled separately in a loop.
+ */
+class ScfPropertySet
+{
+public:
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+ typedef ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XMultiPropertySet > XMultiPropSetRef;
+ typedef ::com::sun::star::uno::Any UnoAny;
+ typedef ::com::sun::star::uno::Sequence< UnoAny > UnoAnySequence;
+ typedef ::com::sun::star::uno::Sequence< ::rtl::OUString > OUStringSequence;
+
+public:
+ inline explicit ScfPropertySet() {}
+ /** Constructs a property set wrapper with the passed UNO property set. */
+ inline explicit ScfPropertySet( XPropertySetRef xPropSet ) { Set( xPropSet ); }
+ /** Constructs a property set wrapper after querying the XPropertySet interface. */
+ template< typename InterfaceType >
+ inline explicit ScfPropertySet( ::com::sun::star::uno::Reference< InterfaceType > xInterface ) { Set( xInterface ); }
+
+ /** Sets the passed UNO property set and releases the old UNO property set. */
+ void Set( XPropertySetRef xPropSet );
+ /** Queries the passed interface for an XPropertySet and releases the old UNO property set. */
+ template< typename InterfaceType >
+ inline void Set( ::com::sun::star::uno::Reference< InterfaceType > xInterface )
+ { Set( XPropertySetRef( xInterface, ::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 XPropertySetRef GetApiPropertySet() const { return mxPropSet; }
+
+ /** Returns the service name provided via the XServiceName interface, or an empty string on error. */
+ ::rtl::OUString GetServiceName() const;
+
+ // Get properties ---------------------------------------------------------
+
+ /** Returns true, if the property set contains the specified property. */
+ bool HasProperty( const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified property from the property set.
+ @return true, if the Any could be filled with the property value. */
+ bool GetAnyProperty( UnoAny& rValue, const ::rtl::OUString& rPropName ) 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& rValue, const ::rtl::OUString& rPropName ) const
+ { UnoAny aAny; return GetAnyProperty( aAny, rPropName ) && (aAny >>= rValue); }
+
+ /** Gets the specified Boolean property from the property set.
+ @return true = property contains true; false = property contains false or error occurred. */
+ bool GetBoolProperty( const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified Boolean property from the property set.
+ @return true, if the passed Boolean variable could be filled with the property value. */
+ bool GetStringProperty( String& rValue, const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified color property from the property set.
+ @return true, if the passed color variable could be filled with the property value. */
+ bool GetColorProperty( Color& rColor, const ::rtl::OUString& rPropName ) const;
+
+ /** Gets the specified properties from 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 GetProperties( UnoAnySequence& rValues, const OUStringSequence& rPropNames ) const;
+
+ // Set properties ---------------------------------------------------------
+
+ /** Puts the passed Any into the property set. */
+ void SetAnyProperty( const ::rtl::OUString& rPropName, const UnoAny& rValue );
+
+ /** Puts the passed value into the property set. */
+ template< typename Type >
+ inline void SetProperty( const ::rtl::OUString& rPropName, const Type& rValue )
+ { SetAnyProperty( rPropName, ::com::sun::star::uno::makeAny( rValue ) ); }
+
+ /** Puts the passed Boolean value into the property set. */
+ inline void SetBoolProperty( const ::rtl::OUString& rPropName, bool bValue )
+ { SetAnyProperty( rPropName, ::comphelper::makeBoolAny( bValue ) ); }
+
+ /** Puts the passed string into the property set. */
+ inline void SetStringProperty( const ::rtl::OUString& rPropName, const String& rValue )
+ { SetProperty( rPropName, ::rtl::OUString( rValue ) ); }
+
+ /** Puts the passed color into the property set. */
+ inline void SetColorProperty( const ::rtl::OUString& rPropName, const Color& rColor )
+ { SetProperty( rPropName, ScfApiHelper::ConvertToApiColor( rColor ) ); }
+
+ /** 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 OUStringSequence& rPropNames, const UnoAnySequence& rValues );
+
+ // ------------------------------------------------------------------------
+private:
+ XPropertySetRef mxPropSet; /// The mandatory property set interface.
+ XMultiPropSetRef mxMultiPropSet; /// The optional multi property set interface.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Generic helper class for reading from and writing to property sets.
+
+ Usage:
+ 1) Call the constructor with a null-terminated array of ASCII strings.
+ 2a) Read properties from a property set: Call the ReadFromPropertySet()
+ function, then get the properties with the ReadValue() functions or the
+ operator>> stream operator. The properties are returned in order of the
+ array of property names passed in the constructor.
+ 2b) Write properties to a property set: Call InitializeWrite() to start a
+ new cycle. Set the values with the WriteValue() functions or the
+ operator<< stream operator. The order of the properties is equal to the
+ array of property names passed in the constructor. Finally, call the
+ WriteToPropertySet() function.
+ */
+class ScfPropSetHelper
+{
+public:
+ typedef ::com::sun::star::uno::Any UnoAny;
+
+public:
+ /** @param ppPropNames A null-terminated array of ASCII property names. */
+ explicit ScfPropSetHelper( const sal_Char* const* ppcPropNames );
+
+ // read properties --------------------------------------------------------
+
+ /** Reads all values from the passed property set. */
+ void ReadFromPropertySet( const ScfPropertySet& rPropSet );
+
+ /** Reads the next value from the value sequence. */
+ template< typename Type >
+ bool ReadValue( Type& rValue );
+ /** Reads an Any from the value sequence. */
+ bool ReadValue( UnoAny& rAny );
+ /** Reads a tools string from the value sequence. */
+ bool ReadValue( String& rString );
+ /** Reads a color value from the value sequence. */
+ bool ReadValue( Color& rColor );
+ /** Reads a C++ boolean value from the value sequence. */
+ bool ReadValue( bool& rbValue );
+
+ // write properties -------------------------------------------------------
+
+ /** Must be called before reading or storing property values in the helper. */
+ void InitializeWrite( bool bClearAllAnys = false );
+
+ /** Writes the next value to the value sequence. */
+ template< typename Type >
+ void WriteValue( const Type& rValue );
+ /** Writes an Any to the value sequence. */
+ void WriteValue( const UnoAny& rAny );
+ /** Writes a tools string to the value sequence. */
+ inline void WriteValue( const String& rString )
+ { WriteValue( ::rtl::OUString( rString ) ); }
+ /** Writes a color value to the value sequence. */
+ inline void WriteValue( const Color& rColor )
+ { WriteValue( ScfApiHelper::ConvertToApiColor( rColor ) ); }
+ /** Writes a C++ boolean value to the value sequence. */
+ void WriteValue( const bool& rbValue );
+
+ /** Writes all values to the passed property set. */
+ void WriteToPropertySet( ScfPropertySet& rPropSet ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns a pointer to the next Any to be written to. */
+ UnoAny* GetNextAny();
+
+private:
+ typedef ::com::sun::star::uno::Sequence< ::rtl::OUString > OUStringSequence;
+ typedef ::com::sun::star::uno::Sequence< UnoAny > UnoAnySequence;
+
+ OUStringSequence maNameSeq; /// Sequence of property names.
+ UnoAnySequence maValueSeq; /// Sequence of property values.
+ ScfInt32Vec maNameOrder; /// Maps initial order to alphabetical order.
+ size_t mnNextIdx; /// Counter for next Any to be processed.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+bool ScfPropSetHelper::ReadValue( Type& rValue )
+{
+ UnoAny* pAny = GetNextAny();
+ return pAny && (*pAny >>= rValue);
+}
+
+template< typename Type >
+void ScfPropSetHelper::WriteValue( const Type& rValue )
+{
+ UnoAny* pAny = GetNextAny();
+ if( pAny )
+ *pAny <<= rValue;
+}
+
+template< typename Type >
+ScfPropSetHelper& operator>>( ScfPropSetHelper& rPropSetHelper, Type& rValue )
+{
+ rPropSetHelper.ReadValue( rValue );
+ return rPropSetHelper;
+}
+
+template< typename Type >
+ScfPropSetHelper& operator<<( ScfPropSetHelper& rPropSetHelper, const Type& rValue )
+{
+ rPropSetHelper.WriteValue( rValue );
+ return rPropSetHelper;
+}
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/filt_pch.hxx b/sc/source/filter/inc/filt_pch.hxx
new file mode 100644
index 000000000000..2943677712bd
--- /dev/null
+++ b/sc/source/filter/inc/filt_pch.hxx
@@ -0,0 +1,313 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ItemID-Defines etc. muessen immer ganz vorne stehen
+
+#include "scitems.hxx"
+
+
+#define _ZFORLIST_DECLARE_TABLE
+
+#define SC_PROGRESS_CXX
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+#include <rtl/textenc.h>
+#include <sal/types.h>
+#include <sal/config.h>
+#include <rtl/textcvt.h>
+#include <rtl/string.hxx>
+#include <rtl/string.h>
+#include <rtl/ustring.h>
+#include <rtl/memory.h>
+#include <rtl/ustring.hxx>
+#include <rtl/locale.hxx>
+#include <rtl/locale.h>
+#include <tools/contnr.hxx>
+#include <i18npool/lang.h>
+#include <global.hxx>
+#include <tools/stream.hxx>
+#include <tools/errinf.hxx>
+#include <tools/rtti.hxx>
+#include <tools/errcode.hxx>
+#include <tools/ref.hxx>
+#include <tools/link.hxx>
+#include <tools/debug.hxx>
+#include <tools/time.hxx>
+#include <tools/date.hxx>
+#include <svl/svarray.hxx>
+#include <vcl/sv.h>
+#include <vcl/timer.hxx>
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+#include <tools/color.hxx>
+#include <filter.hxx>
+#include <rangelst.hxx>
+#include <osl/mutex.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <cppu/macros.hxx>
+#include <uno/lbnames.h>
+#include <uno/any2.h>
+#include <uno/data.h>
+#include <typelib/typedescription.h>
+#include <typelib/uik.h>
+#include <typelib/typeclass.h>
+#include <com/sun/star/uno/Type.h>
+#include <com/sun/star/uno/TypeClass.hdl>
+#include <com/sun/star/uno/Type.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <com/sun/star/uno/genfunc.h>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/XInterface.hdl>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/RuntimeException.hdl>
+#include <com/sun/star/uno/Exception.hdl>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <svl/hint.hxx>
+#include <svl/poolitem.hxx>
+#include <document.hxx>
+#include <vcl/prntypes.hxx>
+#include <table.hxx>
+#include <column.hxx>
+#include <markarr.hxx>
+#include <root.hxx>
+#include <flttypes.hxx>
+#include <svl/solar.hrc>
+#include <sfx2/sfxsids.hrc>
+#include <svl/cntwids.hrc>
+#include <sfx2/cntids.hrc>
+#include <tools/mempool.hxx>
+#include <compiler.hxx>
+#include <formula/compiler.hrc>
+#include <sfx2/sfx.hrc>
+#include <scitems.hxx>
+#include <svx/svxids.hrc>
+#include <svl/itemset.hxx>
+#include <svl/memberid.hrc>
+#include <tools/table.hxx>
+#include <flttools.hxx>
+#include <vcl/vclenum.hxx>
+#include <tools/resid.hxx>
+#include <tools/rc.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/fract.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/mapmod.hxx>
+#include <tools/mapunit.hxx>
+#include <vcl/region.hxx>
+#include <svl/lstner.hxx>
+#include <patattr.hxx>
+#include <vcl/font.hxx>
+#include <svl/cenumitm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/cintitem.hxx>
+#include <svl/brdcst.hxx>
+#include <tools/globname.hxx>
+#include <sot/factory.hxx>
+#include <sot/object.hxx>
+#include <sot/sotdata.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/alpha.hxx>
+#include <vcl/gdimtf.hxx>
+#include <tools/unqidx.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/animate.hxx>
+#include <vcl/graph.h>
+#include <vcl/gfxlink.hxx>
+#include <rsc/rscsfx.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/accel.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <namebuff.hxx>
+#include <tools/shl.hxx>
+#include <tools/pstm.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <tools/unqid.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <uno/sequence2.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <attrib.hxx>
+#include <svl/zforlist.hxx>
+#include <editeng/fontitem.hxx>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XEventListener.hdl>
+#include <com/sun/star/lang/EventObject.hdl>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <vcl/outdev.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValue.hdl>
+#include <com/sun/star/beans/PropertyState.hdl>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <collect.hxx>
+#include <vcl/window.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <tools/wintypes.hxx>
+#include <vcl/inputctx.hxx>
+#include <vcl/event.hxx>
+#include <tools/ownlist.hxx>
+#include <vcl/cmdevt.hxx>
+#include <vcl/vclenum.hxx>
+#include <cell.hxx>
+#include <osl/interlck.h>
+#include <sfx2/sfxuno.hxx>
+#include <colrowst.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/URL.hdl>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hdl>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hdl>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XTypeProvider.hdl>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/uuid.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/factory.hxx>
+#include <uno/dispatcher.h>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/XRegistryKey.hdl>
+#include <com/sun/star/registry/InvalidRegistryException.hdl>
+#include <com/sun/star/registry/InvalidValueException.hdl>
+#include <com/sun/star/registry/RegistryKeyType.hdl>
+#include <com/sun/star/registry/RegistryValueType.hdl>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+#include <com/sun/star/registry/InvalidValueException.hpp>
+#include <com/sun/star/registry/RegistryKeyType.hpp>
+#include <com/sun/star/registry/RegistryValueType.hpp>
+#include <sot/storage.hxx>
+#include <tools/datetime.hxx>
+#include <osl/thread.h>
+#include <imp_op.hxx>
+#include <otlnbuff.hxx>
+#include <tokstack.hxx>
+#include <com/sun/star/container/NoSuchElementException.hdl>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <vcl/svapp.hxx>
+#include <osl/thread.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <vcl/apptypes.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <com/sun/star/lang/WrappedTargetException.hdl>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <sfx2/shell.hxx>
+#include <tools/stack.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XComponent.hdl>
+#include <editeng/svxenum.hxx>
+#include <formel.hxx>
+#include <com/sun/star/container/XElementAccess.hdl>
+#include <com/sun/star/container/XElementAccess.hpp>
+#include <svl/itempool.hxx>
+#include <editeng/eeitem.hxx>
+#include <rangenam.hxx>
+#include <vcl/syswin.hxx>
+#include <svl/smplhint.hxx>
+#include <fontbuff.hxx>
+#include <vcl/ctrl.hxx>
+#include <vcl/field.hxx>
+#include <vcl/spinfld.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/combobox.h>
+#include <tools/fldunit.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFrame.hdl>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindow.hdl>
+#include <com/sun/star/awt/Rectangle.hdl>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XFocusListener.hdl>
+#include <com/sun/star/awt/FocusEvent.hdl>
+#include <com/sun/star/awt/FocusEvent.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/awt/XKeyListener.hdl>
+#include <com/sun/star/awt/KeyEvent.hdl>
+#include <com/sun/star/awt/InputEvent.hdl>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/InputEvent.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/XMouseListener.hdl>
+#include <com/sun/star/awt/MouseEvent.hdl>
+#include <com/sun/star/awt/MouseEvent.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hdl>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hdl>
+#include <com/sun/star/awt/PaintEvent.hdl>
+#include <com/sun/star/awt/PaintEvent.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hdl>
+#include <com/sun/star/awt/WindowEvent.hdl>
+#include <com/sun/star/awt/WindowEvent.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XController.hdl>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModel.hdl>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hdl>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/container/XIndexAccess.hdl>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <excrecds.hxx>
+#include <scerrors.hxx>
+#include <docpool.hxx>
+#include <svx/msdffimp.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hdl>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <tools/urlobj.hxx>
+#include <editeng/colritem.hxx>
+#include <vcl/wrkwin.hxx>
+#include <excimp8.hxx>
+#include <excscen.hxx>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hdl>
+#include <com/sun/star/frame/FrameActionEvent.hdl>
+#include <com/sun/star/frame/FrameAction.hdl>
+#include <com/sun/star/frame/FrameActionEvent.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hdl>
+#include <com/sun/star/frame/XFrames.hpp>
+#include <com/sun/star/frame/XFrames.hdl>
+#include <svx/msdffdef.hxx>
+#include <vcl/image.hxx>
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/fkttab.h b/sc/source/filter/inc/fkttab.h
new file mode 100644
index 000000000000..5604fff3ac7d
--- /dev/null
+++ b/sc/source/filter/inc/fkttab.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FKTTAB_H
+#define SC_FKTTAB_H
+
+#include "decl.h"
+
+// Prefixes der Operationen
+extern const sal_Char *cPre[ 256 ];
+
+// Infixes der Operationen
+extern const sal_Char *cInf[ 256 ];
+
+// Postfixes der Operationen
+extern const sal_Char *cPost[ 256 ];
+
+// Bearbeitungsfunktion sal_Char *X( sal_Char * )
+extern BEARBFKT *pFkt[ 256 ];
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/flttypes.hxx b/sc/source/filter/inc/flttypes.hxx
new file mode 100644
index 000000000000..c34fff6c2299
--- /dev/null
+++ b/sc/source/filter/inc/flttypes.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FLTTYPES_HXX
+#define SC_FLTTYPES_HXX
+
+enum BiffTyp
+{
+ BiffX = 0x0000,
+ Biff2 = 0x2000, Biff2M = 0x2002, Biff2C = 0x2004,
+ Biff3 = 0x3000, Biff3W = 0x3001, Biff3M = 0x3002, Biff3C = 0x3004,
+ Biff4 = 0x4000, Biff4W = 0x4001, Biff4M = 0x4002, Biff4C = 0x4004,
+ Biff5 = 0x5000, Biff5W = 0x5001, Biff5V = 0x5002, Biff5C = 0x5004, Biff5M4 = 0x5008,
+ Biff8 = 0x8000, Biff8W = 0x8001, Biff8V = 0x8002, Biff8C = 0x8004, Biff8M4 = 0x8008
+};
+
+enum Lotus123Typ
+{
+ Lotus_X,
+ Lotus_WK1,
+ Lotus_WK3,
+ Lotus_WK4,
+ Lotus_FM3
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/formel.hxx b/sc/source/filter/inc/formel.hxx
new file mode 100644
index 000000000000..f76eeeb3d0a8
--- /dev/null
+++ b/sc/source/filter/inc/formel.hxx
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMEL_HXX
+#define SC_FORMEL_HXX
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+#include <compiler.hxx>
+#include <global.hxx>
+
+#include "root.hxx"
+#include "tokstack.hxx"
+
+#include <boost/ptr_container/ptr_map.hpp>
+#include <vector>
+
+class XclImpStream;
+class ScTokenArray;
+class ScFormulaCell;
+struct ScSingleRefData;
+struct ScComplexRefData;
+
+enum ConvErr
+{
+ ConvOK = 0,
+ ConvErrNi, // nicht implemntierter/unbekannter Opcode aufgetreten
+ ConvErrNoMem, // Fehler beim Speicheranfordern
+ ConvErrExternal,// Add-Ins aus Excel werden nicht umgesetzt
+ ConvErrCount // Nicht alle Bytes der Formel 'erwischt'
+};
+
+enum FORMULA_TYPE
+{
+ FT_CellFormula,
+ FT_RangeName,
+ FT_SharedFormula
+};
+
+class _ScRangeListTabs
+{
+ typedef ::std::vector<ScRange> RangeListType;
+ typedef ::boost::ptr_map<SCTAB, RangeListType> TabRangeType;
+ TabRangeType maTabRanges;
+ RangeListType::const_iterator maItrCur;
+ RangeListType::const_iterator maItrCurEnd;
+
+public:
+ _ScRangeListTabs ();
+ ~_ScRangeListTabs();
+
+ void Append( ScSingleRefData aSRD, SCTAB nTab, bool bLimit = true );
+ void Append( ScComplexRefData aCRD, SCTAB nTab, bool bLimit = true );
+
+ const ScRange* First ( SCTAB nTab = 0 );
+ const ScRange* Next ();
+
+ bool HasRanges () const { return !maTabRanges.empty(); }
+};
+
+class ConverterBase
+{
+protected:
+ TokenPool aPool; // User Token + Predefined Token
+ TokenStack aStack;
+ ScAddress aEingPos;
+ ConvErr eStatus;
+ sal_Char* pBuffer; // Universal-Puffer
+ sal_uInt16 nBufferSize; // ...und seine Groesse
+
+ ConverterBase( sal_uInt16 nNewBuffer );
+ virtual ~ConverterBase();
+
+ void Reset();
+
+public:
+ inline SCCOL GetEingabeCol( void ) const { return aEingPos.Col(); }
+ inline SCROW GetEingabeRow( void ) const { return aEingPos.Row(); }
+ inline SCTAB GetEingabeTab( void ) const { return aEingPos.Tab(); }
+ inline ScAddress GetEingPos( void ) const { return aEingPos; }
+};
+
+
+
+class ExcelConverterBase : public ConverterBase
+{
+protected:
+ ExcelConverterBase( sal_uInt16 nNewBuffer );
+ virtual ~ExcelConverterBase();
+
+public:
+ void Reset();
+ void Reset( const ScAddress& rEingPos );
+
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, XclImpStream& rStrm, sal_Size nFormulaLen,
+ bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, SCsTAB nTab,
+ const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+};
+
+
+
+class LotusConverterBase : public ConverterBase
+{
+protected:
+ SvStream& aIn;
+ sal_Int32 nBytesLeft;
+
+ inline void Ignore( const long nSeekRel );
+ inline void Read( sal_Char& nByte );
+ inline void Read( sal_uInt8& nByte );
+ inline void Read( sal_uInt16& nUINT16 );
+ inline void Read( sal_Int16& nINT16 );
+ inline void Read( double& fDouble );
+ inline void Read( sal_uInt32& nUINT32 );
+
+ LotusConverterBase( SvStream& rStr, sal_uInt16 nNewBuffer );
+ virtual ~LotusConverterBase();
+
+public:
+ void Reset( const ScAddress& rEingPos );
+
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, sal_Int32& nRest,
+ const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
+
+protected:
+ using ConverterBase::Reset;
+};
+
+
+inline void LotusConverterBase::Ignore( const long nSeekRel )
+{
+ aIn.SeekRel( nSeekRel );
+ nBytesLeft -= nSeekRel;
+}
+
+inline void LotusConverterBase::Read( sal_Char& nByte )
+{
+ aIn >> nByte;
+ nBytesLeft--;
+}
+
+inline void LotusConverterBase::Read( sal_uInt8& nByte )
+{
+ aIn >> nByte;
+ nBytesLeft--;
+}
+
+inline void LotusConverterBase::Read( sal_uInt16& nUINT16 )
+{
+ aIn >> nUINT16;
+ nBytesLeft -= 2;
+}
+
+inline void LotusConverterBase::Read( sal_Int16& nINT16 )
+{
+ aIn >> nINT16;
+ nBytesLeft -= 2;
+}
+
+inline void LotusConverterBase::Read( double& fDouble )
+{
+ aIn >> fDouble;
+ nBytesLeft -= 8;
+}
+
+inline void LotusConverterBase::Read( sal_uInt32& nUINT32 )
+{
+ aIn >> nUINT32;
+ nBytesLeft -= 4;
+}
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/fprogressbar.hxx b/sc/source/filter/inc/fprogressbar.hxx
new file mode 100644
index 000000000000..cfcd872eff89
--- /dev/null
+++ b/sc/source/filter/inc/fprogressbar.hxx
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FPROGRESSBAR_HXX
+#define SC_FPROGRESSBAR_HXX
+
+#include <boost/noncopyable.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include "globstr.hrc"
+#include "ftools.hxx"
+#include "scdllapi.h"
+
+class SfxObjectShell;
+class ScProgress;
+
+// ============================================================================
+
+const sal_Int32 SCF_INV_SEGMENT = -1;
+
+// ============================================================================
+
+/** Progress bar for complex progress representation.
+
+ The progress bar contains one or more segments, each with customable
+ size. Each segment is represented by a unique identifier. While showing the
+ progress bar, several segments can be started simultaneously. The progress
+ bar displays the sum of all started segments on screen.
+
+ It is possible to create a full featured ScfProgressBar object from
+ any segment. This sub progress bar works only on that parent segment, with
+ the effect, that if the sub progress bar reaches 100%, the parent segment is
+ filled completely.
+
+ After adding segments, the progress bar has to be activated. In this step the
+ total size of all segments is calculated. Therefore it is not possible to add
+ more segments from here.
+
+ If a sub progress bar is created from a segment, and the main progress bar
+ has been started (but not the sub progress bar), it is still possible to add
+ segments to the sub progress bar. It is not allowed to get the sub progress bar
+ of a started segment. And it is not allowed to modify the segment containing
+ a sub progress bar directly.
+
+ Following a few code examples, how to use the progress bar.
+
+ Example 1: Simple progress bar (see also ScfSimpleProgressBar below).
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg = aProgress.AddSegment( 50 ); // segment with 50 steps (1 step = 2%)
+
+ aProgress.ActivateSegment( nSeg ); // start segment nSeg
+ aProgress.Progress(); // 0->1; display: 2%
+ aProgress.ProgressAbs( 9 ); // 1->9; display: 18%
+
+ Example 2: Progress bar with 2 segments.
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg1 = aProgress.AddSegment( 70 ); // segment with 70 steps
+ sal_Int32 nSeg2 = aProgress.AddSegment( 30 ); // segment with 30 steps
+ // both segments: 100 steps (1 step = 1%)
+
+ aProgress.ActivateSegment( nSeg1 ); // start first segment
+ aProgress.Progress(); // 0->1, display: 1%
+ aProgress.Progress( 2 ); // 1->3, display: 3%
+ aProgress.ActivateSegment( nSeg2 ); // start second segment
+ aProgress.Progress( 5 ); // 0->5, display: 8% (5+3 steps)
+ aProgress.ActivateSegment( nSeg1 ); // continue with first segment
+ aProgress.Progress(); // 3->4, display: 9% (5+4 steps)
+
+ Example 3: Progress bar with 2 segments, one contains a sub progress bar.
+
+ ScfProgressBar aProgress( ... );
+ sal_Int32 nSeg1 = aProgress.AddSegment( 75 ); // segment with 75 steps
+ sal_Int32 nSeg2 = aProgress.AddSegment( 25 ); // segment with 25 steps
+ // both segments: 100 steps (1 step = 1%)
+
+ aProgress.ActivateSegment( nSeg1 ); // start first segment
+ aProgress.Progress(); // 0->1, display: 1%
+
+ ScfProgressBar& rSubProgress = aProgress.GetSegmentProgressBar( nSeg2 );
+ // sub progress bar from second segment
+ sal_Int32 nSubSeg = rSubProgress.AddSegment( 5 ); // 5 steps, mapped to second segment
+ // => 1 step = 5 steps in parent = 5%
+
+ rSubProgress.ActivateSegment( nSubSeg ); // start the segment (auto activate parent segment)
+ rSubProgress.Progress(); // 0->1 (0->5 in parent); display: 6% (1+5)
+
+ // not allowed (second segment active): aProgress.Progress();
+ // not allowed (first segment not empty): aProgress.GetSegmentProgressBar( nSeg1 );
+ */
+class ScfProgressBar : private boost::noncopyable
+{
+public:
+ explicit ScfProgressBar( SfxObjectShell* pDocShell, const String& rText );
+ explicit ScfProgressBar( SfxObjectShell* pDocShell, sal_uInt16 nResId );
+ virtual ~ScfProgressBar();
+
+ /** Adds a new segment to the progress bar.
+ @return the identifier of the segment. */
+ sal_Int32 AddSegment( sal_Size nSize );
+ /** Returns a complete progress bar for the specified segment.
+ @descr The progress bar can be used to create sub segments inside of the
+ segment. Do not delete it (done by root progress bar)!
+ @return A reference to an ScfProgressBar connected to the segment. */
+ ScfProgressBar& GetSegmentProgressBar( sal_Int32 nSegment );
+
+ /** Returns true, if any progress segment has been started. */
+ inline bool IsStarted() const { return mbInProgress; }
+ /** Returns true, if the current progress segment is already full. */
+ bool IsFull() const;
+
+ /** Starts the progress bar or activates another segment. */
+ void ActivateSegment( sal_Int32 nSegment );
+ /** Starts the progress bar (with first segment). */
+ inline void Activate() { ActivateSegment( 0 ); }
+ /** Set current segment to the specified absolute position. */
+ void ProgressAbs( sal_Size nPos );
+ /** Increase current segment by the passed value. */
+ void Progress( sal_Size nDelta = 1 );
+
+private:
+ struct ScfProgressSegment;
+
+ /** Used to create sub progress bars. */
+ explicit ScfProgressBar(
+ ScfProgressBar& rParProgress,
+ ScfProgressSegment* pParSegment );
+
+ /** Initializes all members on construction. */
+ void Init( SfxObjectShell* pDocShell );
+
+ /** Returns the segment specified by list index. */
+ ScfProgressSegment* GetSegment( sal_Int32 nSegment );
+ /** Activates progress bar and sets current segment. */
+ void SetCurrSegment( ScfProgressSegment* pSegment );
+ /** Increases mnTotalPos and calls the system progress bar. */
+ void IncreaseProgressBar( sal_Size nDelta );
+
+private:
+ /** Contains all data of a segment of the progress bar. */
+ struct ScfProgressSegment
+ {
+ typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;
+
+ ScfProgressBarPtr mxProgress; /// Pointer to sub progress bar for this segment.
+ sal_Size mnSize; /// Size of this segment.
+ sal_Size mnPos; /// Current position of this segment.
+
+ explicit ScfProgressSegment( sal_Size nSize );
+ ~ScfProgressSegment();
+ };
+
+ typedef ::std::auto_ptr< ScProgress > ScProgressPtr;
+ typedef boost::ptr_vector< ScfProgressSegment > ScfSegmentList;
+
+ ScfSegmentList maSegments; /// List of progress segments.
+ String maText; /// UI string for system progress.
+
+ ScProgressPtr mxSysProgress; /// System progress bar.
+ SfxObjectShell* mpDocShell; /// The document shell for the progress bar.
+ ScfProgressBar* mpParentProgress; /// Parent progress bar, if this is a segment progress bar.
+ ScfProgressSegment* mpParentSegment; /// Parent segment, if this is a segment progress bar.
+ ScfProgressSegment* mpCurrSegment; /// Current segment for progress.
+
+ sal_Size mnTotalSize; /// Total size of all segments.
+ sal_Size mnTotalPos; /// Sum of positions of all segments.
+ sal_Size mnUnitSize; /// Size between two calls of system progress.
+ sal_Size mnNextUnitPos; /// Limit for next system progress call.
+ sal_Size mnSysProgressScale; /// Additionally scaling factor for system progress.
+ bool mbInProgress; /// true = progress bar started.
+};
+
+// ============================================================================
+
+/** A simplified progress bar with only one segment. */
+class ScfSimpleProgressBar
+{
+public:
+ explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText );
+ explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, sal_uInt16 nResId );
+
+ /** Set progress bar to the specified position. */
+ inline void ProgressAbs( sal_Size nPos ) { maProgress.ProgressAbs( nPos ); }
+ /** Increase progress bar by 1. */
+ inline void Progress( sal_Size nDelta = 1 ) { maProgress.Progress( nDelta ); }
+
+private:
+ /** Initializes and starts the progress bar. */
+ void Init( sal_Size nSize );
+
+private:
+ ScfProgressBar maProgress; /// The used progress bar.
+};
+
+// ============================================================================
+
+/** A simplified progress bar based on the stream position of an existing stream. */
+class ScfStreamProgressBar
+{
+public:
+ explicit ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, sal_uInt16 nResId = STR_LOAD_DOC );
+
+ /** Sets the progress bar to the current stream position. */
+ void Progress();
+
+private:
+ /** Initializes and starts the progress bar. */
+ void Init( SfxObjectShell* pDocShell, const String& rText );
+
+private:
+ typedef ::std::auto_ptr< ScfSimpleProgressBar > ScfSimpleProgressBarPtr;
+
+ ScfSimpleProgressBarPtr mxProgress; /// The used progress bar.
+ SvStream& mrStrm; /// The used stream.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx
new file mode 100644
index 000000000000..cf15e543e0ee
--- /dev/null
+++ b/sc/source/filter/inc/ftools.hxx
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FTOOLS_HXX
+#define SC_FTOOLS_HXX
+
+#include <vector>
+#include <map>
+#include <limits>
+#include <memory>
+#include <tools/string.hxx>
+#include <tools/debug.hxx>
+#include <sal/macros.h>
+#include <oox/helper/helper.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include "filter.hxx"
+#include "scdllapi.h"
+
+// Common macros ==============================================================
+
+/** Expands to a pointer behind the last element of a STATIC data array (like STL end()). */
+#define STATIC_TABLE_END( array ) ((array)+SAL_N_ELEMENTS(array))
+
+/** Expands to a temporary String, created from an ASCII character array. */
+#define CREATE_STRING( ascii ) String( RTL_CONSTASCII_USTRINGPARAM( ascii ) )
+
+// items and item sets --------------------------------------------------------
+
+/** Expands to the item (with type 'itemtype') with Which-ID 'which'. */
+#define GETITEM( itemset, itemtype, which ) \
+ static_cast< const itemtype & >( (itemset).Get( which ) )
+
+/** Expands to the value (with type 'valuetype') of the item with Which-ID 'which'. */
+#define GETITEMVALUE( itemset, itemtype, which, valuetype ) \
+ static_cast< valuetype >( GETITEM( itemset, itemtype, which ).GetValue() )
+
+/** Expands to the value of the SfxBoolItem with Which-ID 'which'. */
+#define GETITEMBOOL( itemset, which ) \
+ GETITEMVALUE( itemset, SfxBoolItem, which, bool )
+
+// Global static helpers ======================================================
+
+// Value range limit helpers --------------------------------------------------
+
+/** Returns the value, if it is not less than nMin, otherwise nMin. */
+template< typename ReturnType, typename Type >
+inline ReturnType llimit_cast( Type nValue, ReturnType nMin )
+{ return static_cast< ReturnType >( ::std::max< Type >( nValue, nMin ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise the minimum value of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType llimit_cast( Type nValue )
+{ return llimit_cast( nValue, ::std::numeric_limits< ReturnType >::min() ); }
+
+/** Returns the value, if it is not greater than nMax, otherwise nMax. */
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue, ReturnType nMax )
+{ return static_cast< ReturnType >( ::std::min< Type >( nValue, nMax ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise the maximum value of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType ulimit_cast( Type nValue )
+{ return ulimit_cast( nValue, ::std::numeric_limits< ReturnType >::max() ); }
+
+/** Returns the value, if it is not less than nMin and not greater than nMax, otherwise one of the limits. */
+template< typename ReturnType, typename Type >
+inline ReturnType limit_cast( Type nValue, ReturnType nMin, ReturnType nMax )
+{ return static_cast< ReturnType >( ::std::max< Type >( ::std::min< Type >( nValue, nMax ), nMin ) ); }
+
+/** Returns the value, if it fits into ReturnType, otherwise one of the limits of ReturnType. */
+template< typename ReturnType, typename Type >
+inline ReturnType limit_cast( Type nValue )
+{ return limit_cast( nValue, ::std::numeric_limits< ReturnType >::min(), ::std::numeric_limits< ReturnType >::max() ); }
+
+// Read from bitfields --------------------------------------------------------
+
+/** Returns true, if at least one of the bits set in nMask is set in nBitField. */
+template< typename Type >
+inline bool get_flag( 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 get_flagvalue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
+{ return ::get_flag( nBitField, nMask ) ? nSet : nUnset; }
+
+/** Extracts a value from a bit field.
+ @descr Returns in rnRet the data fragment from nBitField, that starts at bit nStartBit
+ (0-based, bit 0 is rightmost) with the width of nBitCount. rnRet will be right-aligned (normalized).
+ For instance: extract_value( n, 0x4321, 8, 4 ) stores 3 in n (value in bits 8-11). */
+template< typename ReturnType, typename Type >
+inline ReturnType extract_value( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{ return static_cast< ReturnType >( ((1UL << nBitCount) - 1) & (nBitField >> nStartBit) ); }
+
+// Write to bitfields ---------------------------------------------------------
+
+/** Sets or clears (according to bSet) all set bits of nMask in rnBitField. */
+template< typename Type >
+inline void set_flag( Type& rnBitField, Type nMask, bool bSet = true )
+{ if( bSet ) rnBitField |= nMask; else rnBitField &= ~nMask; }
+
+/** Inserts a value into a bitfield.
+ @descr Inserts the lower nBitCount bits of nValue into rnBitField, starting
+ there at bit nStartBit. Other contents of rnBitField keep unchanged. */
+template< typename Type, typename InsertType >
+void insert_value( Type& rnBitField, InsertType nValue, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{
+ unsigned long nMask = ((1UL << nBitCount) - 1);
+ Type nNewValue = static_cast< Type >( nValue & nMask );
+ (rnBitField &= ~(nMask << nStartBit)) |= (nNewValue << nStartBit);
+}
+
+// ============================================================================
+
+class Color;
+class SfxPoolItem;
+class SfxItemSet;
+class ScStyleSheet;
+class ScStyleSheetPool;
+class SotStorage;
+class SotStorageRef;
+class SotStorageStreamRef;
+class SvStream;
+
+/** Contains static methods used anywhere in the filters. */
+class ScfTools : boost::noncopyable
+{
+public:
+
+// *** common methods *** -----------------------------------------------------
+
+ /** Reads a 10-byte-long-double and converts it to double. */
+ static double ReadLongDouble( SvStream& rStrm );
+ /** Returns system text encoding for byte string conversion. */
+ static rtl_TextEncoding GetSystemTextEncoding();
+ /** Returns a string representing the hexadecimal value of nValue. */
+ static String GetHexStr( sal_uInt16 nValue );
+
+ /** Mixes RGB components with given transparence.
+ @param nTrans Foreground transparence (0x00 == full nFore ... 0x80 = full nBack). */
+ static sal_uInt8 GetMixedColorComp( sal_uInt8 nFore, sal_uInt8 nBack, sal_uInt8 nTrans );
+ /** Mixes colors with given transparence.
+ @param nTrans Foreground transparence (0x00 == full rFore ... 0x80 = full rBack). */
+ static Color GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8 nTrans );
+
+// *** conversion of names *** ------------------------------------------------
+
+ /** Converts a string to a valid Calc defined name or database range name.
+ @descr Defined names in Calc may contain letters, digits (*), underscores, periods (*),
+ colons (*), question marks, and dollar signs.
+ (*) = not allowed at first position. */
+ static void ConvertToScDefinedName( String& rName );
+
+// *** streams and storages *** -----------------------------------------------
+
+ /** Tries to open an existing storage with the specified name in the passed storage (read-only). */
+ static SotStorageRef OpenStorageRead( SotStorageRef xStrg, const String& rStrgName );
+ /** Creates and opens a storage with the specified name in the passed storage (read/write). */
+ static SotStorageRef OpenStorageWrite( SotStorageRef xStrg, const String& rStrgName );
+
+ /** Tries to open an existing stream with the specified name in the passed storage (read-only). */
+ static SotStorageStreamRef OpenStorageStreamRead( SotStorageRef xStrg, const String& rStrmName );
+ /** Creates and opens a stream with the specified name in the passed storage (read/write). */
+ static SotStorageStreamRef OpenStorageStreamWrite( SotStorageRef xStrg, const String& rStrmName );
+
+// *** item handling *** ------------------------------------------------------
+
+ /** Returns true, if the passed item set contains the item.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItem( const SfxItemSet& rItemSet, sal_uInt16 nWhichId, bool bDeep );
+ /** Returns true, if the passed item set contains at least one of the items.
+ @param pnWhichIds Zero-terminated array of Which-IDs.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItems( const SfxItemSet& rItemSet, const sal_uInt16* pnWhichIds, bool bDeep );
+
+ /** Puts the item into the passed item set.
+ @descr The item will be put into the item set, if bSkipPoolDef is false,
+ or if the item differs from the default pool item.
+ @param rItemSet The destination item set.
+ @param rItem The item to put into the item set.
+ @param nWhichId The Which-ID to set with the item.
+ @param bSkipPoolDef true = Do not put item if it is equal to pool default; false = Always put the item. */
+ static void PutItem(
+ SfxItemSet& rItemSet, const SfxPoolItem& rItem,
+ sal_uInt16 nWhichId, bool bSkipPoolDef );
+
+ /** Puts the item into the passed item set.
+ @descr The item will be put into the item set, if bSkipPoolDef is false,
+ or if the item differs from the default pool item.
+ @param rItemSet The destination item set.
+ @param rItem The item to put into the item set.
+ @param bSkipPoolDef true = Do not put item if it is equal to pool default; false = Always put the item. */
+ static void PutItem( SfxItemSet& rItemSet, const SfxPoolItem& rItem, bool bSkipPoolDef );
+
+// *** style sheet handling *** -----------------------------------------------
+
+ /** Creates and returns a cell style sheet and inserts it into the pool.
+ @descr If the style sheet is already in the pool, another unused style name is used.
+ @param bForceName Controls behaviour, if the style already exists:
+ true = Old existing style will be renamed; false = New style gets another name. */
+ static ScStyleSheet& MakeCellStyleSheet(
+ ScStyleSheetPool& rPool,
+ const String& rStyleName, bool bForceName );
+ /** Creates and returns a page style sheet and inserts it into the pool.
+ @descr If the style sheet is already in the pool, another unused style name is used.
+ @param bForceName Controls behaviour, if the style already exists:
+ true = Old existing style will be renamed; false = New style gets another name. */
+ static ScStyleSheet& MakePageStyleSheet(
+ ScStyleSheetPool& rPool,
+ const String& rStyleName, bool bForceName );
+
+// *** byte string import operations *** --------------------------------------
+
+ /** Reads and returns a zero terminted byte string. */
+ static ByteString ReadCString( SvStream& rStrm );
+ /** Reads and returns a zero terminted byte string. */
+ inline static String ReadCString( SvStream& rStrm, rtl_TextEncoding eTextEnc )
+ { return String( ReadCString( rStrm ), eTextEnc ); }
+
+ /** Reads and returns a zero terminted byte string and decreases a stream counter. */
+ static ByteString ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft );
+ /** Reads and returns a zero terminted byte string and decreases a stream counter. */
+ inline static String ReadCString( SvStream& rStrm, sal_Int32& rnBytesLeft, rtl_TextEncoding eTextEnc )
+ { return String( ReadCString( rStrm, rnBytesLeft ), eTextEnc ); }
+
+ /** Appends a zero terminted byte string. */
+ static void AppendCString( SvStream& rStrm, ByteString& rString );
+ /** Appends a zero terminted byte string. */
+ static void AppendCString( SvStream& rStrm, String& rString, rtl_TextEncoding eTextEnc );
+
+// *** HTML table names <-> named range names *** -----------------------------
+
+ /** Returns the built-in range name for an HTML document. */
+ static const String& GetHTMLDocName();
+ /** Returns the built-in range name for all HTML tables. */
+ static const String& GetHTMLTablesName();
+ /** Returns the built-in range name for an HTML table, specified by table index. */
+ static String GetNameFromHTMLIndex( sal_uInt32 nIndex );
+ /** Returns the built-in range name for an HTML table, specified by table name. */
+ static String GetNameFromHTMLName( const String& rTabName );
+
+ /** Returns true, if rSource is the built-in range name for an HTML document. */
+ static bool IsHTMLDocName( const String& rSource );
+ /** Returns true, if rSource is the built-in range name for all HTML tables. */
+ static bool IsHTMLTablesName( const String& rSource );
+ /** Converts a built-in range name to an HTML table name.
+ @param rSource The string to be determined.
+ @param rName The HTML table name.
+ @return true, if conversion was successful. */
+ static bool GetHTMLNameFromName( const String& rSource, String& rName );
+
+private:
+ /** Returns the prefix for table index names. */
+ static const String& GetHTMLIndexPrefix();
+ /** Returns the prefix for table names. */
+ static const String& GetHTMLNamePrefix();
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static items. To enforce this, the default constructor
+ is made private */
+ ScfTools();
+};
+
+// Containers =================================================================
+
+typedef ::std::vector< sal_uInt8 > ScfUInt8Vec;
+typedef ::std::vector< sal_Int16 > ScfInt16Vec;
+typedef ::std::vector< sal_uInt16 > ScfUInt16Vec;
+typedef ::std::vector< sal_Int32 > ScfInt32Vec;
+typedef ::std::vector< sal_uInt32 > ScfUInt32Vec;
+typedef ::std::vector< ::rtl::OUString > ScfStringVec;
+
+// ----------------------------------------------------------------------------
+
+class ScFormatFilterPluginImpl : public ScFormatFilterPlugin {
+ public:
+ ScFormatFilterPluginImpl();
+ // various import filters
+ virtual FltError ScImportLotus123( SfxMedium&, ScDocument*, CharSet eSrc = RTL_TEXTENCODING_DONTKNOW );
+ virtual FltError ScImportQuattroPro( SfxMedium &rMedium, ScDocument *pDoc );
+ virtual FltError ScImportExcel( SfxMedium&, ScDocument*, const EXCIMPFORMAT );
+ // eFormat == EIF_AUTO -> passender Filter wird automatisch verwendet
+ // eFormat == EIF_BIFF5 -> nur Biff5-Stream fuehrt zum Erfolg (auch wenn in einem Excel97-Doc)
+ // eFormat == EIF_BIFF8 -> nur Biff8-Stream fuehrt zum Erfolg (nur in Excel97-Docs)
+ // eFormat == EIF_BIFF_LE4 -> nur Nicht-Storage-Dateien _koennen_ zum Erfolg fuehren
+ virtual FltError ScImportStarCalc10( SvStream&, ScDocument* );
+ virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos,
+ const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, sal_uInt32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange );
+ virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange,
+ double nOutputFactor = 1.0, sal_Bool bCalcWidthHeight = true,
+ SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true );
+
+ virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange );
+ virtual ScEEAbsImport *CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight );
+ virtual String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName );
+
+ // various export filters
+#if ENABLE_LOTUS123_EXPORT
+ virtual FltError ScExportLotus123( SvStream&, ScDocument*, ExportFormatLotus, CharSet eDest );
+#endif
+ virtual FltError ScExportExcel5( SfxMedium&, ScDocument*, ExportFormatExcel eFormat, CharSet eDest );
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScAddress& rOutPos, const CharSet eDest,
+ sal_uInt32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScExportDif( SvStream&, ScDocument*, const ScRange& rRange, const CharSet eDest,
+ sal_uInt32 nDifOption = SC_DIFOPT_EXCEL );
+ virtual FltError ScExportHTML( SvStream&, const String& rBaseURL, ScDocument*, const ScRange& rRange, const CharSet eDest, sal_Bool bAll,
+ const String& rStreamPath, String& rNonConvertibleChars );
+ virtual FltError ScExportRTF( SvStream&, ScDocument*, const ScRange& rRange, const CharSet eDest );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/funktion.h b/sc/source/filter/inc/funktion.h
new file mode 100644
index 000000000000..2377fbe16bf1
--- /dev/null
+++ b/sc/source/filter/inc/funktion.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUNKTION_H
+#define SC_FUNKTION_H
+
+// Bearbeitungsfunktionen
+void P0( void ); // 0 Parameter
+void P1( void ); // 1 Parameter
+void P2( void ); // 2 Parameter
+void P3( void ); // 3 Parameter
+void P4( void ); // 4 Parameter
+void P5( void ); // 5 Parameter
+void Pn( void ); // n Parameter
+void NI( void ); // nicht implementiert
+void ConstFloat( void ); // 0
+void Variable( void ); // 1
+void LotusRange( void ); // 2
+void FormulaReturn( void ); // 3
+void Klammer( void ); // 4
+void ConstInt( void ); // 5
+void ConstString( void ); // 6
+// ACHTUNG: unbekannte Funktionen -> P0()
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/htmlexp.hxx b/sc/source/filter/inc/htmlexp.hxx
new file mode 100644
index 000000000000..6bbc62b2f52d
--- /dev/null
+++ b/sc/source/filter/inc/htmlexp.hxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLEXP_HXX
+#define SC_HTMLEXP_HXX
+
+#include "global.hxx"
+#include <rtl/textenc.h>
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include "expbase.hxx"
+
+
+class ScDocument;
+class SfxItemSet;
+class SdrPage;
+class Graphic;
+class SdrObject;
+class OutputDevice;
+class ScDrawLayer;
+class SvStringsSortDtor;
+class ScEditCell;
+
+namespace editeng { class SvxBorderLine; }
+
+struct ScHTMLStyle
+{ // Defaults aus StyleSheet
+ Color aBackgroundColor;
+ String aFontFamilyName;
+ sal_uInt32 nFontHeight; // Item-Value
+ sal_uInt16 nFontSizeNumber; // HTML value 1-7
+ sal_uInt8 nDefaultScriptType; // Font values are valid for the default script type
+ sal_Bool bInitialized;
+
+ ScHTMLStyle() : nFontHeight(0), nFontSizeNumber(2), nDefaultScriptType(0),
+ bInitialized(0) {}
+
+ const ScHTMLStyle& operator=( const ScHTMLStyle& r )
+ {
+ aBackgroundColor = r.aBackgroundColor;
+ aFontFamilyName = r.aFontFamilyName;
+ nFontHeight = r.nFontHeight;
+ nFontSizeNumber = r.nFontSizeNumber;
+ nDefaultScriptType = r.nDefaultScriptType;
+ bInitialized = r.bInitialized;
+ return *this;
+ }
+};
+
+struct ScHTMLGraphEntry
+{
+ ScRange aRange; // ueberlagerter Zellbereich
+ Size aSize; // Groesse in Pixeln
+ Size aSpace; // Spacing in Pixeln
+ SdrObject* pObject;
+ sal_Bool bInCell; // ob in Zelle ausgegeben wird
+ sal_Bool bWritten;
+
+ ScHTMLGraphEntry( SdrObject* pObj, const ScRange& rRange,
+ const Size& rSize, sal_Bool bIn, const Size& rSpace ) :
+ aRange( rRange ), aSize( rSize ), aSpace( rSpace ),
+ pObject( pObj ), bInCell( bIn ), bWritten( false ) {}
+};
+
+
+#define SC_HTML_FONTSIZES 7
+const short nIndentMax = 23;
+
+class ScHTMLExport : public ScExportBase
+{
+ // default HtmlFontSz[1-7]
+ static const sal_uInt16 nDefaultFontSize[SC_HTML_FONTSIZES];
+ // HtmlFontSz[1-7] in s*3.ini [user]
+ static sal_uInt16 nFontSize[SC_HTML_FONTSIZES];
+ static const char* pFontSizeCss[SC_HTML_FONTSIZES];
+ static const sal_uInt16 nCellSpacing;
+ static const sal_Char sIndentSource[];
+
+ boost::ptr_vector< ScHTMLGraphEntry > aGraphList;
+ ScHTMLStyle aHTMLStyle;
+ String aBaseURL;
+ String aStreamPath;
+ String aCId; // Content-Id fuer Mail-Export
+ OutputDevice* pAppWin; // fuer Pixelei
+ SvStringsSortDtor* pSrcArr; // fuer CopyLocalFileToINet
+ SvStringsSortDtor* pDestArr;
+ String aNonConvertibleChars; // collect nonconvertible characters
+ rtl_TextEncoding eDestEnc;
+ SCTAB nUsedTables;
+ short nIndent;
+ sal_Char sIndent[nIndentMax+1];
+ sal_Bool bAll; // ganzes Dokument
+ sal_Bool bTabHasGraphics;
+ sal_Bool bTabAlignedLeft;
+ sal_Bool bCalcAsShown;
+ sal_Bool bCopyLocalFileToINet;
+ sal_Bool bTableDataWidth;
+ sal_Bool bTableDataHeight;
+
+ const SfxItemSet& PageDefaults( SCTAB nTab );
+
+ void WriteBody();
+ void WriteHeader();
+ void WriteOverview();
+ void WriteTables();
+ void WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
+ void WriteGraphEntry( ScHTMLGraphEntry* );
+ void WriteImage( String& rLinkName,
+ const Graphic&, const ByteString& rImgOptions,
+ sal_uLong nXOutFlags = 0 );
+ // nXOutFlags fuer XOutBitmap::WriteGraphic
+
+ // write to stream if and only if URL fields in edit cell
+ sal_Bool WriteFieldText( const ScEditCell* pCell );
+
+ // kopiere ggfs. eine lokale Datei ins Internet
+ sal_Bool CopyLocalFileToINet( String& rFileNm,
+ const String& rTargetNm, sal_Bool bFileToFile = false );
+ sal_Bool HasCId() { return aCId.Len() > 0; }
+ void MakeCIdURL( String& rURL );
+
+ void PrepareGraphics( ScDrawLayer*, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow );
+ void FillGraphList( const SdrPage*, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow );
+
+ void BorderToStyle( ByteString& rOut, const char* pBorderName,
+ const ::editeng::SvxBorderLine* pLine, bool& bInsertSemicolon );
+
+ sal_uInt16 GetFontSizeNumber( sal_uInt16 nHeight );
+ const char* GetFontSizeCss( sal_uInt16 nHeight );
+ sal_uInt16 ToPixel( sal_uInt16 nTwips );
+ Size MMToPixel( const Size& r100thMMSize );
+ void IncIndent( short nVal );
+ const sal_Char* GetIndentStr() { return sIndent; }
+
+public:
+ ScHTMLExport( SvStream&, const String&, ScDocument*, const ScRange&,
+ sal_Bool bAll, const String& aStreamPath );
+ virtual ~ScHTMLExport();
+ sal_uLong Write();
+ const String& GetNonConvertibleChars() const
+ { return aNonConvertibleChars; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/htmlimp.hxx b/sc/source/filter/inc/htmlimp.hxx
new file mode 100644
index 000000000000..c79bf6d4f1e2
--- /dev/null
+++ b/sc/source/filter/inc/htmlimp.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLIMP_HXX
+#define SC_HTMLIMP_HXX
+
+#include "eeimport.hxx"
+
+class ScHTMLParser;
+
+class ScHTMLImport : public ScEEImport
+{
+private:
+ static void InsertRangeName( ScDocument* pDoc, const String& rName, const ScRange& rRange );
+
+public:
+ ScHTMLImport( ScDocument* pDoc, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight = sal_True );
+ virtual ~ScHTMLImport();
+ const ScHTMLParser* GetParser() const { return (ScHTMLParser*)mpParser; }
+
+ virtual void WriteToDocument( sal_Bool bSizeColsRows = false, double nOutputFactor = 1.0,
+ SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true );
+
+ static String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName );
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx
new file mode 100644
index 000000000000..5548338e82f3
--- /dev/null
+++ b/sc/source/filter/inc/htmlpars.hxx
@@ -0,0 +1,640 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_HTMLPARS_HXX
+#define SC_HTMLPARS_HXX
+
+#include <tools/stack.hxx>
+
+#include <memory>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "rangelst.hxx"
+#include "eeparser.hxx"
+
+const sal_uInt32 SC_HTML_FONTSIZES = 7; // wie Export, HTML-Options
+
+// Pixel tolerance for SeekOffset and related.
+const sal_uInt16 SC_HTML_OFFSET_TOLERANCE_SMALL = 1; // single table
+const sal_uInt16 SC_HTML_OFFSET_TOLERANCE_LARGE = 10; // nested
+
+// ============================================================================
+// BASE class for HTML parser classes
+// ============================================================================
+
+class ScHTMLTable;
+
+/** Base class for HTML parser classes. */
+class ScHTMLParser : public ScEEParser
+{
+protected:
+ sal_uInt32 maFontHeights[ SC_HTML_FONTSIZES ];
+ ScDocument* mpDoc; /// The destination document.
+
+public:
+ explicit ScHTMLParser( EditEngine* pEditEngine, ScDocument* pDoc );
+ virtual ~ScHTMLParser();
+
+ virtual sal_uLong Read( SvStream& rStrm, const String& rBaseURL ) = 0;
+
+ /** Returns the "global table" which contains the entire HTML document. */
+ virtual const ScHTMLTable* GetGlobalTable() const = 0;
+};
+
+
+// ============================================================================
+
+SV_DECL_VARARR_SORT( ScHTMLColOffset, sal_uLong, 16, 4)
+
+struct ScHTMLTableStackEntry
+{
+ ScRangeListRef xLockedList;
+ ScEEParseEntry* pCellEntry;
+ ScHTMLColOffset* pLocalColOffset;
+ sal_uLong nFirstTableCell;
+ SCCOL nColCnt;
+ SCROW nRowCnt;
+ SCCOL nColCntStart;
+ SCCOL nMaxCol;
+ sal_uInt16 nTable;
+ sal_uInt16 nTableWidth;
+ sal_uInt16 nColOffset;
+ sal_uInt16 nColOffsetStart;
+ sal_Bool bFirstRow;
+ ScHTMLTableStackEntry( ScEEParseEntry* pE,
+ const ScRangeListRef& rL, ScHTMLColOffset* pTO,
+ sal_uLong nFTC,
+ SCCOL nCol, SCROW nRow,
+ SCCOL nStart, SCCOL nMax, sal_uInt16 nTab,
+ sal_uInt16 nTW, sal_uInt16 nCO, sal_uInt16 nCOS,
+ sal_Bool bFR )
+ : xLockedList( rL ), pCellEntry( pE ),
+ pLocalColOffset( pTO ),
+ nFirstTableCell( nFTC ),
+ nColCnt( nCol ), nRowCnt( nRow ),
+ nColCntStart( nStart ), nMaxCol( nMax ),
+ nTable( nTab ), nTableWidth( nTW ),
+ nColOffset( nCO ), nColOffsetStart( nCOS ),
+ bFirstRow( bFR )
+ {}
+ ~ScHTMLTableStackEntry() {}
+};
+DECLARE_STACK( ScHTMLTableStack, ScHTMLTableStackEntry* )
+
+struct ScHTMLAdjustStackEntry
+{
+ SCCOL nLastCol;
+ SCROW nNextRow;
+ SCROW nCurRow;
+ ScHTMLAdjustStackEntry( SCCOL nLCol, SCROW nNRow,
+ SCROW nCRow )
+ : nLastCol( nLCol ), nNextRow( nNRow ),
+ nCurRow( nCRow )
+ {}
+};
+DECLARE_STACK( ScHTMLAdjustStack, ScHTMLAdjustStackEntry* )
+
+
+// ============================================================================
+
+class EditEngine;
+class ScDocument;
+class HTMLOption;
+
+class ScHTMLLayoutParser : public ScHTMLParser
+{
+private:
+ Size aPageSize;
+ String aBaseURL;
+ ScHTMLTableStack aTableStack;
+ String aString;
+ ScRangeListRef xLockedList; // je Table
+ Table* pTables;
+ ScHTMLColOffset* pColOffset;
+ ScHTMLColOffset* pLocalColOffset; // je Table
+ sal_uLong nFirstTableCell; // je Table
+ short nTableLevel;
+ sal_uInt16 nTable;
+ sal_uInt16 nMaxTable;
+ SCCOL nColCntStart; // erste Col je Table
+ SCCOL nMaxCol; // je Table
+ sal_uInt16 nTableWidth; // je Table
+ sal_uInt16 nColOffset; // aktuell, Pixel
+ sal_uInt16 nColOffsetStart; // Startwert je Table, in Pixel
+ sal_uInt16 nMetaCnt; // fuer ParseMetaOptions
+ sal_uInt16 nOffsetTolerance; // for use with SeekOffset and related
+ sal_Bool bCalcWidthHeight; // TRUE: calculate real column width
+ // FALSE: 1 html-col = 1 sc-col
+ sal_Bool bTabInTabCell;
+ sal_Bool bFirstRow; // je Table, ob in erster Zeile
+ sal_Bool bInCell;
+ sal_Bool bInTitle;
+
+ DECL_LINK( HTMLImportHdl, ImportInfo* );
+ void NewActEntry( ScEEParseEntry* );
+ void EntryEnd( ScEEParseEntry*, const ESelection& );
+ void ProcToken( ImportInfo* );
+ void CloseEntry( ImportInfo* );
+ void NextRow( ImportInfo* );
+ void SkipLocked( ScEEParseEntry*, sal_Bool bJoin = sal_True );
+ static sal_Bool SeekOffset( ScHTMLColOffset*, sal_uInt16 nOffset,
+ SCCOL* pCol, sal_uInt16 nOffsetTol );
+ static void MakeCol( ScHTMLColOffset*, sal_uInt16& nOffset,
+ sal_uInt16& nWidth, sal_uInt16 nOffsetTol,
+ sal_uInt16 nWidthTol );
+ static void MakeColNoRef( ScHTMLColOffset*, sal_uInt16 nOffset,
+ sal_uInt16 nWidth, sal_uInt16 nOffsetTol,
+ sal_uInt16 nWidthTol );
+ static void ModifyOffset( ScHTMLColOffset*, sal_uInt16& nOldOffset,
+ sal_uInt16& nNewOffset, sal_uInt16 nOffsetTol );
+ void Colonize( ScEEParseEntry* );
+ sal_uInt16 GetWidth( ScEEParseEntry* );
+ void SetWidths();
+ void Adjust();
+
+ sal_uInt16 GetWidthPixel( const HTMLOption* );
+ sal_Bool IsAtBeginningOfText( ImportInfo* );
+
+ void TableOn( ImportInfo* );
+ void ColOn( ImportInfo* );
+ void TableRowOn( ImportInfo* );
+ void TableRowOff( ImportInfo* );
+ void TableDataOn( ImportInfo* );
+ void TableDataOff( ImportInfo* );
+ void TableOff( ImportInfo* );
+ void Image( ImportInfo* );
+ void AnchorOn( ImportInfo* );
+ void FontOn( ImportInfo* );
+
+public:
+ ScHTMLLayoutParser( EditEngine*, const String& rBaseURL, const Size& aPageSize, ScDocument* );
+ virtual ~ScHTMLLayoutParser();
+ virtual sal_uLong Read( SvStream&, const String& rBaseURL );
+ virtual const ScHTMLTable* GetGlobalTable() const;
+};
+
+
+
+// ============================================================================
+// HTML DATA QUERY PARSER
+// ============================================================================
+
+/** Declares the orientation in or for a table: column or row. */
+enum ScHTMLOrient { tdCol = 0 , tdRow = 1 };
+
+/** Type for a unique identifier for each table. */
+typedef sal_uInt16 ScHTMLTableId;
+/** Identifier of the "global table" (the entire HTML document). */
+const ScHTMLTableId SC_HTML_GLOBAL_TABLE = 0;
+/** Used as table index for normal (non-table) entries in ScHTMLEntry structs. */
+const ScHTMLTableId SC_HTML_NO_TABLE = 0;
+
+// ============================================================================
+
+/** A 2D cell position in an HTML table. */
+struct ScHTMLPos
+{
+ SCCOL mnCol;
+ SCROW mnRow;
+
+ inline explicit ScHTMLPos() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit ScHTMLPos( SCCOL nCol, SCROW nRow ) :
+ mnCol( nCol ), mnRow( nRow ) {}
+ inline explicit ScHTMLPos( const ScAddress& rAddr ) { Set( rAddr ); }
+
+ inline SCCOLROW Get( ScHTMLOrient eOrient ) const
+ { return (eOrient == tdCol) ? mnCol : mnRow; }
+ inline void Set( SCCOL nCol, SCROW nRow )
+ { mnCol = nCol; mnRow = nRow; }
+ inline void Set( const ScAddress& rAddr )
+ { Set( rAddr.Col(), rAddr.Row() ); }
+ inline void Move( SCsCOL nColDiff, SCsROW nRowDiff )
+ { mnCol = mnCol + nColDiff; mnRow = mnRow + nRowDiff; }
+ inline ScAddress MakeAddr() const
+ { return ScAddress( mnCol, mnRow, 0 ); }
+};
+
+inline bool operator==( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
+{
+ return (rPos1.mnRow == rPos2.mnRow) && (rPos1.mnCol == rPos2.mnCol);
+}
+
+inline bool operator<( const ScHTMLPos& rPos1, const ScHTMLPos& rPos2 )
+{
+ return (rPos1.mnRow < rPos2.mnRow) || ((rPos1.mnRow == rPos2.mnRow) && (rPos1.mnCol < rPos2.mnCol));
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell size in an HTML table. */
+struct ScHTMLSize
+{
+ SCCOL mnCols;
+ SCROW mnRows;
+
+ inline explicit ScHTMLSize() : mnCols( 0 ), mnRows( 0 ) {}
+ inline explicit ScHTMLSize( SCCOL nCols, SCROW nRows ) :
+ mnCols( nCols ), mnRows( nRows ) {}
+
+ inline SCCOLROW Get( ScHTMLOrient eOrient ) const
+ { return (eOrient == tdCol) ? mnCols : mnRows; }
+ inline void Set( SCCOL nCols, SCROW nRows )
+ { mnCols = nCols; mnRows = nRows; }
+ inline void Expand( SCsCOL nColDiff, SCsROW nRowDiff )
+ { mnCols = mnCols + nColDiff; mnRows = mnRows + nRowDiff; }
+};
+
+inline bool operator==( const ScHTMLSize& rSize1, const ScHTMLSize& rSize2 )
+{
+ return (rSize1.mnRows == rSize2.mnRows) && (rSize1.mnCols == rSize2.mnCols);
+}
+
+// ============================================================================
+
+/** A single entry containing a line of text or representing a table. */
+struct ScHTMLEntry : public ScEEParseEntry
+{
+public:
+ explicit ScHTMLEntry(
+ const SfxItemSet& rItemSet,
+ ScHTMLTableId nTableId = SC_HTML_NO_TABLE );
+
+ /** Returns true, if the selection of the entry is empty. */
+ inline bool IsEmpty() const { return !aSel.HasRange(); }
+ /** Returns true, if the entry has any content to be imported. */
+ bool HasContents() const;
+ /** Returns true, if the entry represents a table. */
+ inline bool IsTable() const { return nTab != SC_HTML_NO_TABLE; }
+ /** Returns true, if the entry represents a table. */
+ inline ScHTMLTableId GetTableId() const { return nTab; }
+
+ /** Sets or cleares the import always state. */
+ inline void SetImportAlways( bool bSet = true ) { mbImportAlways = bSet; }
+ /** Sets start point of the entry selection to the start of the import info object. */
+ void AdjustStart( const ImportInfo& rInfo );
+ /** Sets end point of the entry selection to the end of the import info object. */
+ void AdjustEnd( const ImportInfo& rInfo );
+ /** Deletes leading and trailing empty paragraphs from the entry. */
+ void Strip( const EditEngine& rEditEngine );
+
+ /** Returns read/write access to the item set of this entry. */
+ inline SfxItemSet& GetItemSet() { return aItemSet; }
+ /** Returns read-only access to the item set of this entry. */
+ inline const SfxItemSet& GetItemSet() const { return aItemSet; }
+
+private:
+ bool mbImportAlways; /// true = Always import this entry.
+};
+
+// ============================================================================
+
+/** This struct handles creation of unique table identifiers. */
+struct ScHTMLTableAutoId
+{
+ const ScHTMLTableId mnTableId; /// The created unique table identifier.
+ ScHTMLTableId& mrnUnusedId; /// Reference to global unused identifier variable.
+
+ /** The constructor assigns an unused identifier to member mnTableId. */
+ explicit ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId );
+};
+
+// ----------------------------------------------------------------------------
+
+class ScHTMLTableMap;
+
+/** Stores data for one table in an HTML document.
+
+ This class does the main work for importing an HTML document. It manages
+ the correct insertion of parse entries into the correct cells and the
+ creation of nested tables. Recalculation of resulting document size and
+ position is done recursively in all nested tables.
+ */
+class ScHTMLTable
+{
+public:
+ /** Creates a new HTML table without content.
+ @descr Internally handles a current cell position. This position is
+ invalid until first calls of RowOn() and DataOn().
+ @param rParentTable Reference to the parent table that owns this table.
+ @param bPreFormText true = Table is based on preformatted text (<pre> tag). */
+ explicit ScHTMLTable(
+ ScHTMLTable& rParentTable,
+ const ImportInfo& rInfo,
+ bool bPreFormText );
+
+ virtual ~ScHTMLTable();
+
+ /** Returns the name of the table, specified in the TABLE tag. */
+ inline const String& GetTableName() const { return maTableName; }
+ /** Returns the unique identifier of the table. */
+ inline ScHTMLTableId GetTableId() const { return maTableId.mnTableId; }
+ /** Returns the table size. */
+ inline const ScHTMLSize& GetSize() const { return maSize; }
+ /** Returns the cell spanning of the specified cell. */
+ ScHTMLSize GetSpan( const ScHTMLPos& rCellPos ) const;
+
+ /** Searches in all nested tables for the specified table.
+ @param nTableId Unique identifier of the table. */
+ ScHTMLTable* FindNestedTable( ScHTMLTableId nTableId ) const;
+
+ /** Puts the item into the item set of the current entry. */
+ void PutItem( const SfxPoolItem& rItem );
+ /** Inserts a text portion into current entry. */
+ void PutText( const ImportInfo& rInfo );
+ /** Inserts a new line, if in preformatted text, else does nothing. */
+ void InsertPara( const ImportInfo& rInfo );
+
+ /** Inserts a line break (<br> tag).
+ @descr Inserts the current entry regardless if it is empty. */
+ void BreakOn();
+ /** Inserts a heading line (<p> and <h*> tags). */
+ void HeadingOn();
+ /** Processes a hyperlink (<a> tag). */
+ void AnchorOn();
+
+ /** Starts a *new* table nested in this table (<table> tag).
+ @return Pointer to the new table. */
+ ScHTMLTable* TableOn( const ImportInfo& rInfo );
+ /** Closes *this* table (</table> tag).
+ @return Pointer to the parent table. */
+ ScHTMLTable* TableOff( const ImportInfo& rInfo );
+ /** Starts a *new* table based on preformatted text (<pre> tag).
+ @return Pointer to the new table. */
+ ScHTMLTable* PreOn( const ImportInfo& rInfo );
+ /** Closes *this* table based on preformatted text (</pre> tag).
+ @return Pointer to the parent table. */
+ ScHTMLTable* PreOff( const ImportInfo& rInfo );
+
+ /** Starts next row (<tr> tag).
+ @descr Cell address is invalid until first call of DataOn(). */
+ void RowOn( const ImportInfo& rInfo );
+ /** Closes the current row (<tr> tag).
+ @descr Cell address is invalid until call of RowOn() and DataOn(). */
+ void RowOff( const ImportInfo& rInfo );
+ /** Starts the next cell (<td> or <th> tag). */
+ void DataOn( const ImportInfo& rInfo );
+ /** Closes the current cell (</td> or </th> tag).
+ @descr Cell address is invalid until next call of DataOn(). */
+ void DataOff( const ImportInfo& rInfo );
+
+ /** Starts the body of the HTML document (<body> tag). */
+ void BodyOn( const ImportInfo& rInfo );
+ /** Closes the body of the HTML document (</body> tag). */
+ void BodyOff( const ImportInfo& rInfo );
+
+ /** Closes *this* table (</table> tag) or preformatted text (</pre> tag).
+ @descr Used to close this table object regardless on opening tag type.
+ @return Pointer to the parent table, or this, if no parent found. */
+ ScHTMLTable* CloseTable( const ImportInfo& rInfo );
+
+ /** Returns the resulting document row/column count of the specified HTML row/column. */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const;
+ /** Returns the resulting document row/column count in the half-open range [nCellBegin, nCellEnd). */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const;
+ /** Returns the total document row/column count in the specified direction. */
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient ) const;
+ /** Returns the total document row/column count of the specified HTML cell. */
+ ScHTMLSize GetDocSize( const ScHTMLPos& rCellPos ) const;
+
+ /** Returns the resulting Calc position of the top left edge of the table. */
+ inline const ScHTMLPos& GetDocPos() const { return maDocBasePos; }
+ /** Calculates the resulting Calc position of the specified HTML column/row. */
+ SCCOLROW GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos = 0 ) const;
+ /** Calculates the resulting Calc position of the specified HTML cell. */
+ ScHTMLPos GetDocPos( const ScHTMLPos& rCellPos ) const;
+
+ /** Calculates the current Calc document area of this table. */
+ void GetDocRange( ScRange& rRange ) const;
+
+ /** Applies border formatting to the passed document. */
+ void ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const;
+
+protected:
+ /** Creates a new HTML table without parent.
+ @descr This constructor is used to create the "global table". */
+ explicit ScHTMLTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ::std::vector< ScEEParseEntry* >& rEEParseList,
+ ScHTMLTableId& rnUnusedId );
+
+ /** Fills all empty cells in this and nested tables with dummy parse entries. */
+ void FillEmptyCells();
+ /** Recalculates the size of all columns/rows in the table, regarding nested tables. */
+ void RecalcDocSize();
+ /** Recalculates the position of all cell entries and nested tables.
+ @param rBasePos The origin of the table in the Calc document. */
+ void RecalcDocPos( const ScHTMLPos& rBasePos );
+
+private:
+ typedef ::std::auto_ptr< ScHTMLTableMap > ScHTMLTableMapPtr;
+ typedef ::std::auto_ptr< SfxItemSet > SfxItemSetPtr;
+ typedef ::std::vector< SCCOLROW > ScSizeVec;
+ typedef ::std::list< ScHTMLEntry* > ScHTMLEntryList;
+ typedef ::std::map< ScHTMLPos, ScHTMLEntryList > ScHTMLEntryMap;
+ typedef ::std::auto_ptr< ScHTMLEntry > ScHTMLEntryPtr;
+
+ /** Returns true, if the current cell does not contain an entry yet. */
+ bool IsEmptyCell() const;
+ /** Returns the item set from cell, row, or table, depending on current state. */
+ const SfxItemSet& GetCurrItemSet() const;
+
+ /** Returns true, if import info represents a space character. */
+ static bool IsSpaceCharInfo( const ImportInfo& rInfo );
+
+ /** Creates and returns a new empty flying entry at position (0,0). */
+ ScHTMLEntryPtr CreateEntry() const;
+ /** Creates a new flying entry.
+ @param rInfo Contains the initial edit engine selection for the entry. */
+ void CreateNewEntry( const ImportInfo& rInfo );
+
+ /** Inserts an empty line in front of the next entry. */
+ void InsertLeadingEmptyLine();
+
+ /** Pushes the passed entry into the list of the current cell. */
+ void ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry );
+ /** Tries to insert the entry into the current cell.
+ @descr If insertion is not possible (i.e., currently no cell open), the
+ entry will be inserted into the parent table.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushEntry( ScHTMLEntryPtr& rxEntry );
+ /** Puts the current entry into the entry list, if it is not empty.
+ @param rInfo The import info struct containing the end position of the current entry.
+ @param bLastInCell true = If cell is still empty, put this entry always.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushEntry( const ImportInfo& rInfo, bool bLastInCell = false );
+ /** Pushes a new entry into current cell which references a nested table.
+ @return true = Entry as been pushed into the current cell; false = Entry dropped. */
+ bool PushTableEntry( ScHTMLTableId nTableId );
+
+ /** Tries to find a table from the table container.
+ @descr Assumes that the table is located in the current container or
+ that the passed table identifier is 0.
+ @param nTableId Unique identifier of the table or 0. */
+ ScHTMLTable* GetExistingTable( ScHTMLTableId nTableId ) const;
+ /** Inserts a nested table in the current cell at the specified position.
+ @param bPreFormText true = New table is based on preformatted text (<pre> tag). */
+ ScHTMLTable* InsertNestedTable( const ImportInfo& rInfo, bool bPreFormText );
+
+ /** Inserts a new cell in an unused position, starting from current cell position. */
+ void InsertNewCell( const ScHTMLSize& rSpanSize );
+
+ /** Set internal states for a new table row. */
+ void ImplRowOn();
+ /** Set internal states for leaving a table row. */
+ void ImplRowOff();
+ /** Set internal states for entering a new table cell. */
+ void ImplDataOn( const ScHTMLSize& rSpanSize );
+ /** Set internal states for leaving a table cell. */
+ void ImplDataOff();
+
+ /** Inserts additional formatting options from import info into the item set. */
+ void ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo );
+
+ /** Updates the document column/row size of the specified column or row.
+ @descr Only increases the present count, never decreases. */
+ void SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize );
+ /** Calculates and sets the resulting size the cell needs in the document.
+ @descr Reduces the needed size in merged cells.
+ @param nCellPos The first column/row position of the (merged) cell.
+ @param nCellSpan The cell spanning in the specified orientation.
+ @param nRealDocSize The raw document size of all entries of the cell. */
+ void CalcNeededDocSize(
+ ScHTMLOrient eOrient, SCCOLROW nCellPos,
+ SCCOLROW nCellSpan, SCCOLROW nRealDocSize );
+
+private:
+ ScHTMLTable* mpParentTable; /// Pointer to parent table.
+ ScHTMLTableMapPtr mxNestedTables; /// Table of nested HTML tables.
+ String maTableName; /// Table name from <table id> option.
+ ScHTMLTableAutoId maTableId; /// Unique identifier of this table.
+ SfxItemSet maTableItemSet; /// Items for the entire table.
+ SfxItemSetPtr mxRowItemSet; /// Items for the current table row.
+ SfxItemSetPtr mxDataItemSet; /// Items for the current cell.
+ ScRangeList maHMergedCells; /// List of all horizontally merged cells.
+ ScRangeList maVMergedCells; /// List of all vertically merged cells.
+ ScRangeList maUsedCells; /// List of all used cells.
+ EditEngine& mrEditEngine; /// Edit engine (from ScEEParser).
+ ::std::vector< ScEEParseEntry* >& mrEEParseList; /// List that owns the parse entries (from ScEEParser).
+ ScHTMLEntryMap maEntryMap; /// List of entries for each cell.
+ ScHTMLEntryList* mpCurrEntryList; /// Current entry list from map for faster access.
+ ScHTMLEntryPtr mxCurrEntry; /// Working entry, not yet inserted in a list.
+ ScSizeVec maCumSizes[ 2 ]; /// Cumulated cell counts for each HTML table column/row.
+ ScHTMLSize maSize; /// Size of the table.
+ ScHTMLPos maCurrCell; /// Address of current cell to fill.
+ ScHTMLPos maDocBasePos; /// Resulting base address in a Calc document.
+ bool mbBorderOn; /// true = Table borders on.
+ bool mbPreFormText; /// true = Table from preformatted text (<pre> tag).
+ bool mbRowOn; /// true = Inside of <tr> </tr>.
+ bool mbDataOn; /// true = Inside of <td> </td> or <th> </th>.
+ bool mbPushEmptyLine; /// true = Insert empty line before current entry.
+};
+
+// ----------------------------------------------------------------------------
+
+/** The "global table" representing the entire HTML document. */
+class ScHTMLGlobalTable : public ScHTMLTable
+{
+public:
+ explicit ScHTMLGlobalTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ::std::vector< ScEEParseEntry* >& rEEParseList,
+ ScHTMLTableId& rnUnusedId );
+
+ virtual ~ScHTMLGlobalTable();
+
+ /** Recalculates sizes and resulting positions of all document entries. */
+ void Recalc();
+};
+
+// ============================================================================
+
+/** The HTML parser for data queries. Focuses on data import, not on layout.
+
+ Builds the table structure correctly, ignores extended formatting like
+ pictures or column widths.
+ */
+class ScHTMLQueryParser : public ScHTMLParser
+{
+public:
+ explicit ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc );
+ virtual ~ScHTMLQueryParser();
+
+ virtual sal_uLong Read( SvStream& rStrm, const String& rBaseURL );
+
+ /** Returns the "global table" which contains the entire HTML document. */
+ virtual const ScHTMLTable* GetGlobalTable() const;
+
+private:
+ /** Handles all possible tags in the HTML document. */
+ void ProcessToken( const ImportInfo& rInfo );
+ /** Inserts a text portion into current entry. */
+ void InsertText( const ImportInfo& rInfo );
+ /** Processes the <font> tag. */
+ void FontOn( const ImportInfo& rInfo );
+
+ /** Processes the <meta> tag. */
+ void MetaOn( const ImportInfo& rInfo );
+ /** Opens the title of the HTML document (<title> tag). */
+ void TitleOn( const ImportInfo& rInfo );
+ /** Closes the title of the HTML document (</title> tag). */
+ void TitleOff( const ImportInfo& rInfo );
+
+ /** Opens a new table at the current position. */
+ void TableOn( const ImportInfo& rInfo );
+ /** Closes the current table. */
+ void TableOff( const ImportInfo& rInfo );
+ /** Opens a new table based on preformatted text. */
+ void PreOn( const ImportInfo& rInfo );
+ /** Closes the current preformatted text table. */
+ void PreOff( const ImportInfo& rInfo );
+
+ /** Closes the current table, regardless on opening tag. */
+ void CloseTable( const ImportInfo& rInfo );
+
+ DECL_LINK( HTMLImportHdl, const ImportInfo* );
+
+private:
+ typedef ::std::auto_ptr< ScHTMLGlobalTable > ScHTMLGlobalTablePtr;
+
+ String maTitle; /// The title of the document.
+ ScHTMLGlobalTablePtr mxGlobTable; /// Contains the entire imported document.
+ ScHTMLTable* mpCurrTable; /// Pointer to current table (performance).
+ ScHTMLTableId mnUnusedId; /// First unused table identifier.
+ bool mbTitleOn; /// true = Inside of <title> </title>.
+};
+
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
new file mode 100644
index 000000000000..57a3374762a1
--- /dev/null
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_IMP_OP_HXX
+#define SC_IMP_OP_HXX
+
+#include <tools/gen.hxx>
+#include "xiroot.hxx"
+#include "xistream.hxx"
+#include "xistyle.hxx"
+#include "flttypes.hxx"
+#include "namebuff.hxx"
+#include "root.hxx"
+#include "otlnbuff.hxx"
+#include "colrowst.hxx"
+#include "excdefs.hxx"
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+
+class SfxItemSet;
+class SvStream;
+
+class ScFormulaCell;
+class SdrObject;
+class ScDocument;
+class ScToken;
+class _ScRangeListTabs;
+
+class ExcelToSc;
+
+
+class ImportTyp
+{
+protected:
+ CharSet eQuellChar; // Quell-Zeichensatz
+ ScDocument* pD; // Dokument
+
+public:
+ ImportTyp( ScDocument*, CharSet eSrc );
+ virtual ~ImportTyp();
+
+ virtual FltError Read( void );
+};
+
+class XclImpOutlineDataBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab );
+ virtual ~XclImpOutlineDataBuffer();
+
+ inline XclImpColRowSettings* GetColRowBuff() const { return mxColRowBuff.get(); }
+ inline XclImpOutlineBuffer* GetColOutline() const { return mxColOutlineBuff.get(); }
+ inline XclImpOutlineBuffer* GetRowOutline() const { return mxRowOutlineBuff.get(); }
+ void Convert();
+
+private:
+ typedef boost::shared_ptr< XclImpOutlineBuffer > XclImpOutlineBfrRef;
+ typedef boost::shared_ptr< XclImpColRowSettings > XclImpColRowSettRef;
+
+ XclImpOutlineBfrRef mxColOutlineBuff;
+ XclImpOutlineBfrRef mxRowOutlineBuff;
+ XclImpColRowSettRef mxColRowBuff;
+ SCTAB mnScTab;
+};
+
+class ImportExcel : public ImportTyp, protected XclImpRoot
+{
+protected:
+ static const double fExcToTwips; // Umrechnung 1/256 Zeichen -> Twips
+
+ RootData* pExcRoot;
+
+ XclImpStream maStrm; // input stream
+ XclImpStream& aIn; // input stream
+
+ ScfUInt32Vec maSheetOffsets;
+ ScRange maScOleSize; /// Visible range if embedded.
+
+ NameBuffer* pExtNameBuff; // ... externe Namen (Ind.-Basis=1)
+ ExcelToSc* pFormConv; // Formel-Konverter
+
+ XclImpOutlineBuffer* pColOutlineBuff;
+ XclImpOutlineBuffer* pRowOutlineBuff;
+ XclImpColRowSettings* pColRowBuff; // Col/Row-Einstellungen 1 Tabelle
+
+ typedef boost::ptr_vector< XclImpOutlineDataBuffer > XclImpOutlineListBuffer;
+ XclImpOutlineListBuffer* pOutlineListBuffer;
+
+ sal_Int16 mnLastRefIdx;
+ sal_uInt16 nIxfeIndex; // merkt sich Angabe im IXFE-Record
+ sal_uInt16 nLastXF; // letzter XF in Formula-Record
+ SCTAB nBdshtTab; // Counter fuer Boundsheet
+ ScFormulaCell* pLastFormCell; // fuer String-Records
+
+ sal_Bool bTabTruncated; // wenn Bereichsueberschreitung zum
+ // Abschneiden von Zellen fuehrt
+
+ // Record-Funktionen
+ void ReadFileSharing();
+
+ sal_uInt16 ReadXFIndex( bool bBiff2 );
+
+ void ReadDimensions();
+ void ReadBlank();
+ void ReadInteger();
+ void ReadNumber();
+ void ReadLabel();
+ void ReadBoolErr();
+ void ReadRk();
+
+ void Window1();
+ void Formula25( void ); // 0x06 -> excform.cxx
+ void Row25( void ); // 0x08
+ void Bof2( void ); // 0x09
+ void Eof( void ); // 0x0A
+ void DocProtect( void ); // 0x12
+ void SheetProtect( void ); // 0x12 Sheet Protection
+ void DocPasssword( void ); // 0x13 document password
+ void SheetPassword( void ); // 0x13 sheet password
+ void Externsheet( void ); // 0x17
+ void WinProtection( void ); // 0x19
+ void Columndefault( void ); // 0x20
+ void Array25( void ); // 0x21
+ void Rec1904( void ); // 0x22
+ void Externname25( void ); // 0x23
+ void Colwidth( void ); // 0x24
+ void Defrowheight2( void ); // 0x25
+// void Window1( void ); // 0x3D
+ void Codepage( void ); // 0x42
+ void Ixfe( void ); // 0x44
+ void DefColWidth( void ); // 0x55
+ void Builtinfmtcnt( void ); // 0x56
+ void Colinfo( void ); // 0x7D
+ void Wsbool( void ); // 0x81
+ void Boundsheet( void ); // 0x85
+ void Country( void ); // 0x8C
+ void Hideobj( void ); // 0x8D
+ void Bundleheader( void ); // 0x8F
+ void Standardwidth( void ); // 0x99
+ void Shrfmla( void ); // 0xBC
+ void Mulrk( void ); // 0xBD
+ void Mulblank( void ); // 0xBE
+ void Rstring( void ); // 0xD6
+ void Cellmerging( void ); // 0xE5
+ void Olesize( void ); // 0xDE
+ void ReadUsesElfs(); // 0x0160
+ void Formula3( void ); // 0x0206 -> excform.cxx
+ // 0x0207 -> 0x07
+ void Row34( void ); // 0x0208
+ void Bof3( void ); // 0x0209
+ void Array34( void ); // 0x0221
+ void Externname34( void ); // 0x0223
+ void Defrowheight345( void ); // 0x0225
+ void TableOp( void ); // 0x0236
+ //void Rk( void ); // 0x027E -> 0x7E
+ void Formula4( void ); // 0x0406 -> excform.cxx
+ void Bof4( void ); // 0x0409
+ void Bof5( void ); // 0x0809
+
+ // ---------------------------------------------------------------
+ void Formula( const XclAddress& rXclPos,
+ sal_uInt16 nXF, sal_uInt16 nFormLen, double &rCurVal, sal_Bool bShrFmla );
+ // -> excform.cxx
+
+ virtual void EndSheet( void );
+ void NeueTabelle( void );
+ const ScTokenArray* ErrorToFormula( sal_uInt8 bErrOrVal, sal_uInt8 nError,
+ double& rVal );
+
+ virtual void AdjustRowHeight();
+ virtual void PostDocLoad( void );
+
+public:
+ ImportExcel( XclImpRootData& rImpData, SvStream& rStrm );
+
+ virtual ~ImportExcel( void );
+
+ virtual FltError Read( void );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/lotattr.hxx b/sc/source/filter/inc/lotattr.hxx
new file mode 100644
index 000000000000..3279efc5fa30
--- /dev/null
+++ b/sc/source/filter/inc/lotattr.hxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTATTR_HXX
+#define SC_LOTATTR_HXX
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <tools/solar.h>
+
+#include "address.hxx"
+#include "scitems.hxx"
+
+class ScDocument;
+class ScDocumentPool;
+class ScPatternAttr;
+class SvxColorItem;
+class Color;
+class LotAttrTable;
+
+namespace editeng { class SvxBorderLine; }
+
+struct LotAttrWK3
+{
+ sal_uInt8 nFont;
+ sal_uInt8 nLineStyle;
+ sal_uInt8 nFontCol;
+ sal_uInt8 nBack;
+
+ inline bool HasStyles () const
+ {
+ return ( nFont || nLineStyle || nFontCol || ( nBack & 0x7F ) );
+ // !! ohne Center-Bit!!
+ }
+
+ inline bool IsCentered () const
+ {
+ return ( nBack & 0x80 );
+ }
+};
+
+class LotAttrCache
+{
+public:
+
+ LotAttrCache ();
+
+ ~LotAttrCache();
+
+ const ScPatternAttr& GetPattAttr( const LotAttrWK3& );
+
+private:
+
+ friend class LotAttrTable;
+
+ struct ENTRY
+ {
+ ScPatternAttr* pPattAttr;
+ sal_uInt32 nHash0;
+
+ ENTRY (const ScPatternAttr &r);
+
+ ENTRY (ScPatternAttr* p);
+
+ ~ENTRY ();
+
+ inline bool operator == (const ENTRY &r) const { return nHash0 == r.nHash0; }
+
+ inline bool operator == (const sal_uInt32 &r) const { return nHash0 == r; }
+ };
+
+ inline static void MakeHash( const LotAttrWK3& rAttr, sal_uInt32& rOut )
+ {
+ ( ( sal_uInt8* ) &rOut )[ 0 ] = rAttr.nFont & 0x7F;
+ ( ( sal_uInt8* ) &rOut )[ 1 ] = rAttr.nLineStyle;
+ ( ( sal_uInt8* ) &rOut )[ 2 ] = rAttr.nFontCol;
+ ( ( sal_uInt8* ) &rOut )[ 3 ] = rAttr.nBack;
+ }
+
+ static void LotusToScBorderLine( sal_uInt8 nLine, ::editeng::SvxBorderLine& );
+
+ const SvxColorItem& GetColorItem( const sal_uInt8 nLotIndex ) const;
+
+ const Color& GetColor( const sal_uInt8 nLotIndex ) const;
+
+ ScDocumentPool* pDocPool;
+ SvxColorItem* ppColorItems[6]; // 0 und 7 fehlen!
+ SvxColorItem* pBlack;
+ SvxColorItem* pWhite;
+ Color* pColTab;
+ boost::ptr_vector<ENTRY> aEntries;
+};
+
+
+class LotAttrCol
+{
+public:
+
+ void SetAttr (const SCROW nRow, const ScPatternAttr&);
+
+ void Apply (const SCCOL nCol, const SCTAB nTab, const sal_Bool bClear = true);
+
+ void Clear ();
+
+private:
+
+ struct ENTRY
+ {
+ const ScPatternAttr* pPattAttr;
+ SCROW nFirstRow;
+ SCROW nLastRow;
+ };
+
+ boost::ptr_vector<ENTRY> aEntries;
+};
+
+
+class LotAttrTable
+{
+public:
+
+ void SetAttr( const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow, const LotAttrWK3& );
+
+ void Apply( const SCTAB nTabNum );
+
+private:
+
+ LotAttrCol pCols[ MAXCOLCOUNT ];
+ LotAttrCache aAttrCache;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/lotfntbf.hxx b/sc/source/filter/inc/lotfntbf.hxx
new file mode 100644
index 000000000000..cb90efc3fc3d
--- /dev/null
+++ b/sc/source/filter/inc/lotfntbf.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTFNTBF_HXX
+#define SC_LOTFNTBF_HXX
+
+#include <tools/solar.h>
+
+#include "scitems.hxx"
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+
+// ---------------------------------------------------- class LotusFontBuffer -
+
+// Code in fontbuff.cxx (excel)
+
+class LotusFontBuffer
+{
+private:
+ struct ENTRY
+ {
+ String* pTmpName;
+ SvxFontItem* pFont;
+ SvxFontHeightItem* pHeight;
+ SvxColorItem* pColor;
+ sal_Int32 nType; // < 0 -> undefiniert
+ inline ENTRY( void )
+ {
+ pTmpName = NULL;
+ pFont = NULL;
+ pHeight = NULL;
+ pColor = NULL;
+ nType = -1;
+ }
+ inline ~ENTRY()
+ {
+ if( pTmpName )
+ delete pTmpName;
+ if( pFont )
+ delete pFont;
+ if( pHeight )
+ delete pHeight;
+ if( pColor )
+ delete pColor;
+ }
+ inline void TmpName( const String &rNew )
+ {
+ if( pTmpName )
+ *pTmpName = rNew;
+ else
+ pTmpName = new String( rNew );
+ }
+ inline void Font( SvxFontItem& rNew )
+ {
+ if( pFont )
+ delete pFont;
+ pFont = &rNew;
+ }
+ inline void Height( SvxFontHeightItem& rNew )
+ {
+ if( pHeight )
+ delete pHeight;
+ pHeight = &rNew;
+ }
+ inline void Color( SvxColorItem& rNew )
+ {
+ if( pColor )
+ delete pColor;
+ pColor = &rNew;
+ }
+ inline void Type( const sal_uInt16 nNew ) { nType = nNew; }
+ };
+
+ ENTRY pData[ 8 ];
+ const static sal_uInt16 nSize;
+ void MakeFont( ENTRY* pEntry );
+public:
+ void Fill( const sal_uInt8 nIndex, SfxItemSet& rItemSet );
+ void SetName( const sal_uInt16 nIndex, const String& rName );
+ void SetHeight( const sal_uInt16 nIndex, const sal_uInt16 nHeight );
+ void SetType( const sal_uInt16 nIndex, const sal_uInt16 nType );
+};
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/lotform.hxx b/sc/source/filter/inc/lotform.hxx
new file mode 100644
index 000000000000..9d23abfaf887
--- /dev/null
+++ b/sc/source/filter/inc/lotform.hxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTFORM_HXX
+#define SC_LOTFORM_HXX
+
+#include "formel.hxx"
+#include <tools/string.hxx>
+
+
+
+
+enum FUNC_TYPE
+{
+ FT_Return = 0, // End Formula
+ FT_FuncFix0, // Funktion, 0 Parameter
+ FT_FuncFix1, // Funktion, 0 Parameter
+ FT_FuncFix2, // Funktion, 0 Parameter
+ FT_FuncFix3, // Funktion, 0 Parameter
+ FT_FuncFix4, // Funktion, 0 Parameter
+ FT_FuncVar, // ~, var. P.
+ FT_Neg, // Negierung
+ FT_Op, // Operator
+ FT_NotImpl, // nicht implementiert
+ FT_ConstFloat, // Double (8-Byte)
+ FT_Variable, // Single Ref
+ FT_Range, // Double Ref
+ FT_Braces, // Klammmern
+ FT_ConstInt, // Integer
+ FT_ConstString, // String
+ FT_NOP, // nichts
+ // zusaetzlich ab WK3
+ FT_Cref, // Cell Reference
+ FT_Rref, // Range Reference
+ FT_Nrref, // Named range reference
+ FT_Absnref, // Absolut named range
+ FT_Erref, // Err range reference
+ FT_Ecref, // Err cell reference
+ FT_Econstant, // Err constant
+ FT_Splfunc, // SPLfunction
+ FT_Const10Float,// Float (10-Byte)
+ FT_Snum // Const Short Num
+ // fuer 'Problemfaelle' beim Import
+};
+
+
+
+
+class LotusToSc : public LotusConverterBase
+{
+private:
+ CharSet eSrcChar;
+ TokenId nAddToken; // ')+1.0'
+ TokenId nSubToken; // ~
+ TokenId n0Token; // '0.0';
+ // ---------------------------------------------------------------
+ static FUNC_TYPE IndexToType( sal_uInt8 );
+ static DefTokenId IndexToToken( sal_uInt8 );
+ static FUNC_TYPE IndexToTypeWK123( sal_uInt8 );
+ static DefTokenId IndexToTokenWK123( sal_uInt8 );
+ void DoFunc( DefTokenId eOc, sal_uInt8 nAnz, const sal_Char* pExtName );
+ void LotusRelToScRel( sal_uInt16 nCol, sal_uInt16 nRow,
+ ScSingleRefData& rSRD );
+ sal_Bool bWK3; // alternative Codeumsetzung statt fuer < WK1
+ sal_Bool bWK123; // alternative for 123
+ // -------------------------------------------------------------------
+ void ReadSRD( ScSingleRefData& rSRD, sal_uInt8 nFlags );
+ inline void ReadCRD( ScComplexRefData& rCRD, sal_uInt8 nFlags );
+ void IncToken( TokenId &rParam );
+ // ACHTUNG: hier wird die aktuelle Token-Kette im Pool
+ // mit '(<rParam>)+1' fortgeschrieben und mit
+ // Store() abgeschlossen!
+ void DecToken( TokenId& rParam );
+ // ACHTUNG: ~
+ void NegToken( TokenId& rParam );
+ // ACHTUNG: wie ~, nur wird '-(<rParam>)' gebildet
+public:
+ LotusToSc( SvStream& aStr, CharSet eSrc, sal_Bool b );
+ virtual ConvErr Convert( const ScTokenArray*& rpErg, sal_Int32& nRest,
+ const FORMULA_TYPE eFT = FT_CellFormula );
+
+ void Reset( const ScAddress& rEingPos );
+ inline void SetWK3( void );
+
+private:
+ using LotusConverterBase::Reset;
+};
+
+
+inline void LotusToSc::ReadCRD( ScComplexRefData& rCRD, sal_uInt8 nRelBit )
+{
+ // erster Teil
+ ReadSRD( rCRD.Ref1, nRelBit );
+
+ // zweiter Teil
+ ReadSRD( rCRD.Ref2, nRelBit >> 3 );
+}
+
+
+inline void LotusToSc::SetWK3( void )
+{
+ bWK3 = sal_True;
+}
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/lotimpop.hxx b/sc/source/filter/inc/lotimpop.hxx
new file mode 100644
index 000000000000..d714611e03bd
--- /dev/null
+++ b/sc/source/filter/inc/lotimpop.hxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTIMPOP_HXX
+#define SC_LOTIMPOP_HXX
+
+#include <tools/string.hxx>
+
+#include "imp_op.hxx"
+#include "flttypes.hxx"
+#include "ftools.hxx"
+#include "lotform.hxx"
+#include "lotattr.hxx"
+
+class ScFormulaCell;
+class LotusFontBuffer;
+
+
+class ImportLotus : public ImportTyp
+{
+private:
+ SvStream* pIn; // benoetigt wegen multiplem Read()!
+ LotusFontBuffer* pFontBuff;
+ LotusToSc aConv;
+ sal_uInt16 nTab; // z.Zt. bearbeitete Tabelle
+ sal_Int32 nExtTab;
+ // -------------------------------------------------------------------
+ // in WK?-Datei
+ void Bof( void ); // 0x0000 00
+ sal_Bool BofFm3( void ); // 0x0000 00
+ void Columnwidth( sal_uInt16 nRecLen ); // 0x0007 07
+ void Hiddencolumn( sal_uInt16 nRecLen ); // 0x0008 08
+ void Userrange( void ); // 0x0009 09
+ void Errcell( void ); // 0x0014 20
+ void Nacell( void ); // 0x0015 21
+ void Labelcell( void ); // 0x0016 22
+ void Numbercell( void ); // 0x0017 23
+ void Smallnumcell( void ); // 0x0018 24
+ ScFormulaCell* Formulacell( sal_uInt16 nRecLen ); // 0x0019 25
+ void Formulastring( ScFormulaCell& ); // 0x001a 26
+ // 0x001b 27 special
+ void NamedSheet( void ); // 14000
+ void RowPresentation( sal_uInt16 nRecLen ); // 2007
+
+ // -------------------------------------------------------------------
+ // in FM?-Datei
+ void Font_Face( void ); // 174
+ void Font_Type( void ); // 176
+ void Font_Ysize( void ); // 177
+ void _Row( const sal_uInt16 nRecLen ); // 197 ?
+ // -------------------------------------------------------------------
+ inline void Read( ScAddress& );
+ inline void Read( ScRange& );
+ // fuer Addresses/Ranges im Format Row(16)/Tab(8)/Col(8)
+ inline void Read( sal_Char& );
+ inline void Read( sal_uInt8& );
+ inline void Read( sal_uInt16& );
+ inline void Read( sal_Int16& );
+ inline void Read( sal_uInt32& );
+ inline void Read( double& ); // 10-Byte-IEEE lesen
+ inline void Read( LotAttrWK3& );
+ void Read( String& ); // 0-terminierten String einlesen
+ inline void Skip( const sal_uInt16 nNumBytes );
+ // -------------------------------------------------------------------
+public:
+ ImportLotus( SvStream&, ScDocument*, CharSet eSrc );
+
+ virtual ~ImportLotus();
+
+ FltError Read();
+ FltError Read( SvStream& ); // special for *.fm3-Dateien
+};
+
+
+inline void ImportLotus::Read( ScAddress& rAddr )
+{
+ sal_uInt16 nRow;
+ *pIn >> nRow;
+ rAddr.SetRow( static_cast<SCROW>(nRow) );
+ sal_uInt8 nByte;
+ *pIn >> nByte;
+ rAddr.SetTab( static_cast<SCTAB>(nByte) );
+ *pIn >> nByte;
+ rAddr.SetCol( static_cast<SCCOL>(nByte) );
+}
+
+
+inline void ImportLotus::Read( ScRange& rRange )
+{
+ Read( rRange.aStart );
+ Read( rRange.aEnd );
+}
+
+
+inline void ImportLotus::Read( sal_Char& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( sal_uInt8& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( sal_uInt16& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( sal_Int16& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( sal_uInt32& r )
+{
+ *pIn >> r;
+}
+
+
+inline void ImportLotus::Read( double& r )
+{
+ r = ScfTools::ReadLongDouble( *pIn );
+}
+
+
+inline void ImportLotus::Read( LotAttrWK3& r )
+{
+ *pIn >> r.nFont >> r.nFontCol >> r.nBack >> r.nLineStyle;
+}
+
+
+inline void ImportLotus::Skip( const sal_uInt16 n )
+{
+ pIn->SeekRel( n );
+}
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/lotrange.hxx b/sc/source/filter/inc/lotrange.hxx
new file mode 100644
index 000000000000..2456a28f3a8b
--- /dev/null
+++ b/sc/source/filter/inc/lotrange.hxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_LOTRANGE_HXX
+#define SC_LOTRANGE_HXX
+
+#include <tools/solar.h>
+#include <compiler.hxx>
+
+// --------------------------------------------------------- class LotusRange -
+
+class LotusRangeList;
+
+typedef sal_uInt16 LR_ID;
+#define ID_FAIL 0xFFFF
+
+class LotusRange
+{
+ friend class LotusRangeList;
+private:
+ sal_uInt32 nHash;
+ SCCOL nColStart;
+ SCROW nRowStart;
+ SCCOL nColEnd;
+ SCROW nRowEnd;
+ LR_ID nId;
+ void MakeHash( void );
+ inline void Copy( const LotusRange& );
+ inline void SetId( LR_ID nId );
+public:
+ LotusRange( SCCOL nCol, SCROW nRow );
+ LotusRange( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE );
+ LotusRange( const LotusRange& );
+ inline LotusRange &operator =( const LotusRange& );
+ inline sal_Bool operator ==( const LotusRange& ) const;
+ inline sal_Bool operator !=( const LotusRange& ) const;
+ inline sal_Bool IsSingle( void ) const;
+};
+
+
+inline void LotusRange::Copy( const LotusRange& rCpy )
+{
+ nColStart = rCpy.nColStart;
+ nRowStart = rCpy.nRowStart;
+ nColEnd = rCpy.nColEnd;
+ nRowEnd = rCpy.nRowEnd;
+}
+
+
+inline void LotusRange::SetId( LR_ID nNewId )
+{
+ nId = nNewId;
+}
+
+
+inline LotusRange &LotusRange::operator =( const LotusRange& rCpy )
+{
+ Copy( rCpy );
+ return *this;
+}
+
+
+inline sal_Bool LotusRange::operator ==( const LotusRange& rRef ) const
+{
+ return ( nHash == rRef.nHash && nColStart == rRef.nColStart &&
+ nRowStart == rRef.nRowStart && nColEnd == rRef.nColEnd &&
+ nRowEnd == rRef.nRowEnd );
+}
+
+
+inline sal_Bool LotusRange::operator !=( const LotusRange& rRef ) const
+{
+ return ( nHash != rRef.nHash || nColStart != rRef.nColStart ||
+ nRowStart != rRef.nRowStart || nColEnd != rRef.nColEnd ||
+ nRowEnd != rRef.nRowEnd );
+}
+
+
+inline sal_Bool LotusRange::IsSingle( void ) const
+{
+ return ( nColStart == nColEnd && nRowStart == nRowEnd );
+}
+
+
+
+// ----------------------------------------------------- class LotusRangeList -
+
+class LotusRangeList : private List
+{
+private:
+ LR_ID nIdCnt;
+ ScComplexRefData aComplRef;
+ static SCCOL nEingCol;
+ static SCROW nEingRow;
+public:
+ LotusRangeList( void );
+ ~LotusRangeList( void );
+ inline sal_uInt16 GetIndex( SCCOL nCol, SCROW nRow );
+ inline sal_uInt16 GetIndex( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE );
+ sal_uInt16 GetIndex( const LotusRange& );
+ inline void Append( SCCOL nCol, SCROW nRow, const String& );
+ inline void Append( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE, const String& );
+ void Append( LotusRange* pLR, const String& rName );
+ inline static void SetEing( const SCCOL nCol, const SCROW nRow );
+};
+
+
+inline LR_ID LotusRangeList::GetIndex( SCCOL nCol, SCROW nRow )
+{
+ LotusRange aRef( nCol, nRow );
+ return GetIndex( aRef );
+}
+
+
+inline LR_ID LotusRangeList::GetIndex( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE )
+{
+ LotusRange aRef( nColS, nRowS, nColE, nRowE );
+ return GetIndex( aRef );
+}
+
+
+inline void LotusRangeList::Append( SCCOL nCol, SCROW nRow, const String& rName )
+{
+ Append( new LotusRange( nCol, nRow ), rName );
+}
+
+
+inline void LotusRangeList::Append( SCCOL nColS, SCROW nRowS, SCCOL nColE, SCROW nRowE, const String& r )
+{
+ Append( new LotusRange( nColS, nRowS, nColE, nRowE ), r );
+}
+
+
+inline void LotusRangeList::SetEing( const SCCOL nCol, const SCROW nRow )
+{
+ nEingCol = nCol;
+ nEingRow = nRow;
+}
+
+#endif
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/namebuff.hxx b/sc/source/filter/inc/namebuff.hxx
new file mode 100644
index 000000000000..1a6619c73f9f
--- /dev/null
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_NAMEBUFF_HXX
+#define SC_NAMEBUFF_HXX
+
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include "compiler.hxx"
+#include "root.hxx"
+#include "xiroot.hxx"
+
+#include "rangenam.hxx"
+#include <boost/unordered_map.hpp>
+#include <list>
+
+class ScDocument;
+class ScTokenArray;
+class NameBuffer;
+
+
+
+
+class StringHashEntry
+{
+private:
+ friend class NameBuffer;
+ String aString;
+ sal_uInt32 nHash;
+
+ static sal_uInt32 MakeHashCode( const String& );
+public:
+ inline StringHashEntry( const String& );
+ inline StringHashEntry( void );
+ inline void operator =( const sal_Char* );
+ inline void operator =( const String& );
+ inline void operator =( const StringHashEntry& );
+ inline sal_Bool operator ==( const StringHashEntry& ) const;
+};
+
+
+inline StringHashEntry::StringHashEntry( void )
+{
+}
+
+
+inline StringHashEntry::StringHashEntry( const String& r ) : aString( r )
+{
+ nHash = MakeHashCode( r );
+}
+
+
+inline void StringHashEntry::operator =( const sal_Char* p )
+{
+ aString.AssignAscii( p );
+ nHash = MakeHashCode( aString );
+}
+
+
+inline void StringHashEntry::operator =( const String& r )
+{
+ aString = r;
+ nHash = MakeHashCode( r );
+}
+
+
+inline void StringHashEntry::operator =( const StringHashEntry& r )
+{
+ nHash = r.nHash;
+ aString = r.aString;
+}
+
+
+inline sal_Bool StringHashEntry::operator ==( const StringHashEntry& r ) const
+{
+ return ( nHash == r.nHash && aString == r.aString );
+}
+
+
+
+class NameBuffer : private List, public ExcRoot
+{
+private:
+ sal_uInt16 nBase; // Index-Basis
+public:
+// inline NameBuffer( void ); //prevent empty rootdata
+ inline NameBuffer( RootData* );
+ inline NameBuffer( RootData*, sal_uInt16 nNewBase );
+
+ virtual ~NameBuffer();
+ inline const String* Get( sal_uInt16 nIndex );
+ inline sal_uInt16 GetLastIndex( void );
+ inline void SetBase( sal_uInt16 nNewBase = 0 );
+ void operator <<( const String& rNewString );
+};
+
+//prevent empty rootdata
+//inline NameBuffer::NameBuffer( void )
+//{
+// nBase = 0;
+//}
+
+
+inline NameBuffer::NameBuffer( RootData* p ) : ExcRoot( p )
+{
+ nBase = 0;
+}
+
+
+inline NameBuffer::NameBuffer( RootData* p, sal_uInt16 nNewBase ) : ExcRoot( p )
+{
+ nBase = nNewBase;
+}
+
+
+inline const String* NameBuffer::Get( sal_uInt16 n )
+{
+ if( n < nBase )
+ return NULL;
+ else
+ {
+ StringHashEntry* pObj = ( StringHashEntry* ) List::GetObject( n );
+
+ if( pObj )
+ return &pObj->aString;
+ else
+ return NULL;
+ }
+}
+
+
+inline sal_uInt16 NameBuffer::GetLastIndex( void )
+{
+ DBG_ASSERT( Count() + nBase <= 0xFFFF, "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );
+
+ return ( sal_uInt16 ) ( Count() + nBase );
+}
+
+
+inline void NameBuffer::SetBase( sal_uInt16 nNewBase )
+{
+ nBase = nNewBase;
+}
+
+
+
+
+class ShrfmlaBuffer : public ExcRoot
+{
+ struct ScAddressHashFunc : public std::unary_function< const ScAddress &, size_t >
+ {
+ size_t operator() (const ScAddress &addr) const;
+ };
+ typedef boost::unordered_map <ScAddress, sal_uInt16, ScAddressHashFunc> ShrfmlaHash;
+ typedef std::list <ScRange> ShrfmlaList;
+
+ ShrfmlaHash index_hash;
+ ShrfmlaList index_list;
+ size_t mnCurrIdx;
+
+public:
+ ShrfmlaBuffer( RootData* pRD );
+ virtual ~ShrfmlaBuffer();
+ void Clear();
+ void Store( const ScRange& rRange, const ScTokenArray& );
+ sal_uInt16 Find (const ScAddress & rAddress ) const;
+
+ static String CreateName( const ScRange& );
+ };
+
+
+
+
+class RangeNameBufferWK3 : private List
+{
+private:
+ struct ENTRY
+ {
+ StringHashEntry aStrHashEntry;
+ ScComplexRefData aScComplexRefDataRel;
+ String aScAbsName;
+ sal_uInt16 nAbsInd; // == 0 -> noch keine Abs-Name!
+ sal_uInt16 nRelInd;
+ sal_Bool bSingleRef;
+ ENTRY( const String& rName, const String& rScName, const ScComplexRefData& rCRD ) :
+ aStrHashEntry( rName ),
+ aScComplexRefDataRel( rCRD ),
+ aScAbsName( rScName )
+ {
+ nAbsInd = 0;
+ aScAbsName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_ABS" ) );
+ }
+ };
+
+ ScTokenArray* pScTokenArray;
+ sal_uInt16 nIntCount;
+public:
+ RangeNameBufferWK3( void );
+ virtual ~RangeNameBufferWK3();
+ void Add( const String& rName, const ScComplexRefData& rCRD );
+ inline void Add( const String& rName, const ScRange& aScRange );
+ sal_Bool FindRel( const String& rRef, sal_uInt16& rIndex );
+ sal_Bool FindAbs( const String& rRef, sal_uInt16& rIndex );
+};
+
+
+inline void RangeNameBufferWK3::Add( const String& rName, const ScRange& aScRange )
+{
+ ScComplexRefData aCRD;
+ ScSingleRefData* pSRD;
+ const ScAddress* pScAddr;
+
+ pSRD = &aCRD.Ref1;
+ pScAddr = &aScRange.aStart;
+ pSRD->SetFlag3D( sal_True );
+ pSRD->nCol = pScAddr->Col();
+ pSRD->nRow = pScAddr->Row();
+ pSRD->nTab = pScAddr->Tab();
+
+ // zunaechst ALLE Refs nur absolut
+ pSRD->SetColRel( false );
+ pSRD->SetRowRel( false );
+ pSRD->SetTabRel( false );
+
+ pSRD = &aCRD.Ref2;
+ pScAddr = &aScRange.aEnd;
+ pSRD->SetFlag3D( sal_True );
+ pSRD->nCol = pScAddr->Col();
+ pSRD->nRow = pScAddr->Row();
+ pSRD->nTab = pScAddr->Tab();
+
+ // zunaechst ALLE Refs nur absolut
+ pSRD->SetColRel( false );
+ pSRD->SetRowRel( false );
+ pSRD->SetTabRel( false );
+
+ Add( rName, aCRD );
+}
+
+
+
+
+class ExtSheetBuffer : private List, public ExcRoot
+{
+private:
+ struct Cont
+ {
+ String aFile;
+ String aTab;
+ sal_uInt16 nTabNum; // 0xFFFF -> noch nicht angelegt
+ // 0xFFFE -> versucht anzulegen, ging aber schief
+ // 0xFFFD -> soll im selben Workbook sein, findet's aber nicht
+ sal_Bool bSWB;
+ sal_Bool bLink;
+ Cont( const String& rFilePathAndName, const String& rTabName ) :
+ aFile( rFilePathAndName ),
+ aTab( rTabName )
+ {
+ nTabNum = 0xFFFF; // -> Tabelle noch nicht erzeugt
+ bSWB = bLink = false;
+ }
+ Cont( const String& rFilePathAndName, const String& rTabName,
+ const sal_Bool bSameWB ) :
+ aFile( rFilePathAndName ),
+ aTab( rTabName )
+ {
+ nTabNum = 0xFFFF; // -> Tabelle noch nicht erzeugt
+ bSWB = bSameWB;
+ bLink = false;
+ }
+ };
+public:
+ inline ExtSheetBuffer( RootData* );
+ virtual ~ExtSheetBuffer();
+
+ sal_Int16 Add( const String& rFilePathAndName,
+ const String& rTabName, const sal_Bool bSameWorkbook = false );
+
+ sal_Bool GetScTabIndex( sal_uInt16 nExcSheetIndex, sal_uInt16& rIn_LastTab_Out_ScIndex );
+ sal_Bool IsLink( const sal_uInt16 nExcSheetIndex ) const;
+ sal_Bool GetLink( const sal_uInt16 nExcSheetIndex, String &rAppl, String &rDoc ) const;
+
+ void Reset( void );
+};
+
+
+inline ExtSheetBuffer::ExtSheetBuffer( RootData* p ) : ExcRoot( p )
+{
+}
+
+
+
+
+struct ExtName
+{
+ String aName;
+ sal_uInt32 nStorageId;
+ sal_uInt16 nFlags;
+
+ inline ExtName( const String& r, sal_uInt16 n ) : aName( r ), nStorageId( 0 ), nFlags( n ) {}
+
+ sal_Bool IsDDE( void ) const;
+ sal_Bool IsOLE( void ) const;
+};
+
+
+
+
+class ExtNameBuff : protected XclImpRoot
+{
+public:
+ explicit ExtNameBuff( const XclImpRoot& rRoot );
+
+ void AddDDE( const String& rName, sal_Int16 nRefIdx );
+ void AddOLE( const String& rName, sal_Int16 nRefIdx, sal_uInt32 nStorageId );
+ void AddName( const String& rName, sal_Int16 nRefIdx );
+
+ const ExtName* GetNameByIndex( sal_Int16 nRefIdx, sal_uInt16 nNameIdx ) const;
+
+ void Reset();
+
+private:
+ typedef ::std::vector< ExtName > ExtNameVec;
+ typedef ::std::map< sal_Int16, ExtNameVec > ExtNameMap;
+
+ ExtNameMap maExtNames;
+};
+
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/op.h b/sc/source/filter/inc/op.h
new file mode 100644
index 000000000000..42d3d747153d
--- /dev/null
+++ b/sc/source/filter/inc/op.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OP_H
+#define SC_OP_H
+
+#include <tools/solar.h>
+#include <patattr.hxx>
+
+// OP-Code-Funktionen
+class SvStream;
+void NI( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_BOF( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_EOF( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Integer( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Number( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Label( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Integer3( SvStream &aStream, sal_uInt16 nLaenge ); // WK3
+void OP_Number3( SvStream &aStream, sal_uInt16 nLaenge ); // WK3
+void OP_Formula( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Formula3( SvStream &aStream, sal_uInt16 nLaenge ); // WK3
+void OP_ColumnWidth( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_NamedRange( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_SymphNamedRange( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Footer( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Header( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Margins( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_HiddenCols( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Window1( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Blank( SvStream &aStream, sal_uInt16 nLaenge );
+// Lotus 123 bits.
+void OP_BOF123( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_EOF123( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Number123( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Label123( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_Formula123( SvStream &aStream, sal_uInt16 nLaenge );
+void OP_IEEENumber123(SvStream& r, sal_uInt16 n);
+void OP_Note123(SvStream &aStream, sal_uInt16 nLaenge);
+void OP_CreatePattern123(SvStream &aStream, sal_uInt16 nLaenge);
+void OP_SheetName123( SvStream &rStream, sal_uInt16 nLength );
+void OP_HorAlign123(sal_uInt8 nAlignPattern, SfxItemSet& rPattern /* const ScPatternAttr& rPattern*/ );
+void OP_VerAlign123(sal_uInt8 nAlignPattern, SfxItemSet& rPattern /* const ScPatternAttr& rPattern*/ );
+void OP_ApplyPatternArea123(SvStream& r);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/optab.h b/sc/source/filter/inc/optab.h
new file mode 100644
index 000000000000..f40065214270
--- /dev/null
+++ b/sc/source/filter/inc/optab.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OPTAB_H
+#define SC_OPTAB_H
+
+typedef void ( *OPCODE_FKT )( SvStream &aStream, sal_uInt16 nLaenge );
+
+#define FKT_LIMIT 101
+
+#define FKT_LIMIT123 101
+
+#define LOTUS_EOF 0x01
+
+#define LOTUS_FILEPASSWD 0x4b
+
+#define LOTUS_PATTERN 0x284
+
+#define LOTUS_FORMAT_INDEX 0x800
+
+#define LOTUS_FORMAT_INFO 0x801
+
+#define ROW_FORMAT_MARKER 0x106
+
+#define COL_FORMAT_MARKER 0x107
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/otlnbuff.hxx b/sc/source/filter/inc/otlnbuff.hxx
new file mode 100644
index 000000000000..9ed84056f182
--- /dev/null
+++ b/sc/source/filter/inc/otlnbuff.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_OTLNBUFF_HXX
+#define SC_OTLNBUFF_HXX
+
+#include <tools/solar.h>
+#include <mdds/flat_segment_tree.hpp>
+#include <set>
+
+class ScOutlineArray;
+
+class XclImpOutlineBuffer
+{
+public:
+ XclImpOutlineBuffer( SCSIZE nNewSize );
+ ~XclImpOutlineBuffer();
+
+ void SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed );
+ void SetOutlineArray( ScOutlineArray* pOArray );
+ void MakeScOutline();
+ void SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed );
+ void SetButtonMode( bool bRightOrUnder );
+
+private:
+ typedef ::mdds::flat_segment_tree<SCSIZE, sal_uInt8> OutlineLevels;
+ OutlineLevels maLevels;
+ ::std::set<SCSIZE> maCollapsedPosSet;
+ ScOutlineArray* mpOutlineArray;
+ SCSIZE mnEndPos;
+ sal_uInt8 mnMaxLevel;
+ bool mbButtonAfter:1;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/qpro.hxx b/sc/source/filter/inc/qpro.hxx
new file mode 100644
index 000000000000..460e0a83ba8c
--- /dev/null
+++ b/sc/source/filter/inc/qpro.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_QPRO_HXX
+#define SC_QPRO_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+#include "qprostyle.hxx"
+#include "biff.hxx"
+
+// Stream wrapper class
+class ScQProReader : public ScBiffReader
+{
+ public:
+ bool recordsLeft();
+ void SetEof( bool bValue ){ mbEndOfFile = bValue; }
+ bool nextRecord();
+ sal_uInt16 getId() { return mnId; }
+ sal_uInt16 getLength() { return mnLength; }
+ void readString( String &rString, sal_uInt16 nLength );
+ ScQProReader( SfxMedium &rMedium );
+ ~ScQProReader(){ };
+ FltError import( ScDocument *pDoc );
+ FltError readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pStyle );
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/qproform.hxx b/sc/source/filter/inc/qproform.hxx
new file mode 100644
index 000000000000..6e06827ad958
--- /dev/null
+++ b/sc/source/filter/inc/qproform.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_QPROFORM_HXX
+#define SC_QPROFORM_HXX
+
+#include <sal/config.h>
+#include "formel.hxx"
+#include <tools/string.hxx>
+#include "qpro.hxx"
+
+#include <compiler.hxx>
+typedef OpCode DefTokenId;
+
+enum FUNC_TYPE
+{
+ FT_Return,
+ FT_FuncFix0,
+ FT_FuncFix1,
+ FT_FuncFix2,
+ FT_FuncFix3,
+ FT_FuncFix4,
+ FT_FuncFix5,
+ FT_FuncFix6,
+ FT_FuncVar,
+ FT_DLL,
+ FT_Neg,
+ FT_Op,
+ FT_NotImpl,
+ FT_ConstFloat,
+ FT_Range,
+ FT_Braces,
+ FT_ConstInt,
+ FT_ConstString,
+ FT_NOP,
+ FT_Cref
+};
+
+class QProToSc : public ConverterBase
+{
+ private:
+ TokenId mnAddToken;
+ TokenId mnSubToken;
+ TokenId mn0Token;
+ SvStream& maIn;
+
+ public:
+ static const size_t nBufSize = 256;
+ QProToSc( SvStream &aStr, const ScAddress& rRefPos );
+ ~QProToSc(){ };
+ ConvErr Convert( const ScTokenArray*& pArray, sal_uInt16 nLen,
+ const FORMULA_TYPE eFT = FT_CellFormula );
+ void DoFunc( DefTokenId eOc, sal_uInt16 nArgs, const sal_Char* pExtString );
+ void ReadSRD( ScSingleRefData& rR, sal_Int8 nPage, sal_Int8 nCol, sal_uInt16 rRel );
+ void IncToken( TokenId &aParam );
+ DefTokenId IndexToToken( sal_uInt16 nToken );
+ FUNC_TYPE IndexToType( sal_uInt8 nToken );
+ DefTokenId IndexToDLLId( sal_uInt16 nIndex );
+ const sal_Char* getString( sal_uInt8 nIndex );
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/qprostyle.hxx b/sc/source/filter/inc/qprostyle.hxx
new file mode 100644
index 000000000000..f52ce655d4bf
--- /dev/null
+++ b/sc/source/filter/inc/qprostyle.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef SC_QPROSTYLE_HXX
+#define SC_QPROSTYLE_HXX
+
+#include <sal/config.h>
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include <tools/string.hxx>
+
+#include <tools/color.hxx>
+#include "flttypes.hxx"
+#include "ftools.hxx"
+
+class ScQProStyle
+{
+ enum limits { maxsize = 256 };
+ sal_uInt8 maAlign[ maxsize ];
+ sal_uInt8 maFont[ maxsize ];
+ sal_uInt16 maFontRecord[ maxsize ];
+ sal_uInt16 maFontHeight[ maxsize ];
+ String maFontType[ maxsize ];
+
+ public:
+ ScQProStyle();
+ void SetFormat( ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle );
+ void setFontRecord(sal_uInt16 nIndex, sal_uInt16 nData, sal_uInt16 nPtSize)
+ {
+ if (nIndex < maxsize)
+ {
+ maFontRecord[ nIndex ] = nData;
+ maFontHeight[ nIndex ] = nPtSize;
+ }
+ }
+ void setFontType( sal_uInt16 nIndex, String &aLabel )
+ { if (nIndex < maxsize) maFontType[ nIndex ] = aLabel; }
+ void setAlign( sal_uInt16 nIndex, sal_uInt8 nData )
+ { if (nIndex < maxsize) maAlign[ nIndex ] = nData; }
+ void setFont( sal_uInt16 nIndex, sal_uInt8 nData )
+ { if (nIndex < maxsize) maFont[ nIndex ] = nData; }
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx
new file mode 100644
index 000000000000..4c9800216a0f
--- /dev/null
+++ b/sc/source/filter/inc/root.hxx
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_ROOT_HXX
+#define SC_ROOT_HXX
+
+#include <tools/solar.h>
+#include "global.hxx"
+#include "address.hxx"
+#include "flttypes.hxx"
+#include "filter.hxx"
+#include "excdefs.hxx"
+
+class ScRangeName;
+
+class NameBuffer;
+class RangeNameBufferWK3;
+class ShrfmlaBuffer;
+class ExtNameBuff;
+class ExtSheetBuffer;
+class ExcelToSc;
+
+class XclImpColRowSettings;
+class XclImpAutoFilterBuffer;
+class XclImpPivotCacheList;
+class _ScRangeListTabs;
+
+class XclExpChTrTabId;
+class XclExpUserBViewList;
+
+class XclImpRoot;
+class XclExpRoot;
+
+// ---------------------------------------------------------- Excel Imp~/Exp~ -
+
+struct RootData // -> Inkarnation jeweils im ImportExcel-Objekt!
+{
+ BiffTyp eDateiTyp; // feine Differenzierung
+ ExtSheetBuffer* pExtSheetBuff;
+ ShrfmlaBuffer* pShrfmlaBuff;
+ ExtNameBuff* pExtNameBuff;
+ ExcelToSc* pFmlaConverter;
+ XclImpColRowSettings* pColRowBuff; // Col/Row-Einstellungen 1 Tabelle
+
+ // Biff8
+ XclImpAutoFilterBuffer* pAutoFilterBuffer; // ranges for autofilter and advanced filter
+ _ScRangeListTabs* pPrintRanges;
+ _ScRangeListTabs* pPrintTitles;
+
+ // Erweiterungen fuer Export
+ XclExpChTrTabId* pTabId; // pointer to rec list, do not destroy
+ XclExpUserBViewList* pUserBViewList; // pointer to rec list, do not destroy
+
+ XclImpRoot* pIR;
+ XclExpRoot* pER;
+
+ RootData( void ); // -> exctools.cxx
+ ~RootData(); // -> exctools.cxx
+};
+
+class ExcRoot
+{
+protected:
+ RootData* pExcRoot;
+ inline ExcRoot( RootData* pNexExcRoot ) : pExcRoot( pNexExcRoot ) {}
+ inline ExcRoot( const ExcRoot& rCopy ) : pExcRoot( rCopy.pExcRoot ) {}
+};
+
+// ---------------------------------------------------------- Lotus Imp~/Exp~ -
+
+class LotusRangeList;
+class LotusFontBuffer;
+class LotAttrTable;
+
+
+struct LOTUS_ROOT
+{
+ ScDocument* pDoc;
+ LotusRangeList* pRangeNames;
+ ScRangeName* pScRangeName;
+ CharSet eCharsetQ;
+ Lotus123Typ eFirstType;
+ Lotus123Typ eActType;
+ ScRange aActRange;
+ RangeNameBufferWK3* pRngNmBffWK3;
+ LotusFontBuffer* pFontBuff;
+ LotAttrTable* pAttrTable;
+};
+
+extern LOTUS_ROOT* pLotusRoot; // -> Inkarn. in filter.cxx
+
+// ----------------------------------------------------------------------------
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/rtfexp.hxx b/sc/source/filter/inc/rtfexp.hxx
new file mode 100644
index 000000000000..e058afea4586
--- /dev/null
+++ b/sc/source/filter/inc/rtfexp.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFEXP_HXX
+#define SC_RTFEXP_HXX
+
+#include "expbase.hxx"
+
+
+class ScRTFExport : public ScExportBase
+{
+ sal_uLong* pCellX; // kumulierte Zellbreiten einer Tabelle
+
+ void WriteTab( SCTAB nTab );
+ void WriteRow( SCTAB nTab, SCROW nRow );
+ void WriteCell( SCTAB nTab, SCROW nRow, SCCOL nCol );
+
+public:
+
+ ScRTFExport( SvStream&, ScDocument*, const ScRange& );
+ virtual ~ScRTFExport();
+
+ sal_uLong Write();
+};
+
+
+#endif // SC_RTFEXP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/rtfimp.hxx b/sc/source/filter/inc/rtfimp.hxx
new file mode 100644
index 000000000000..8278c497f6af
--- /dev/null
+++ b/sc/source/filter/inc/rtfimp.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFIMP_HXX
+#define SC_RTFIMP_HXX
+
+#include "eeimport.hxx"
+
+class ScRTFImport : public ScEEImport
+{
+public:
+ ScRTFImport( ScDocument* pDoc, const ScRange& rRange );
+ ~ScRTFImport();
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/rtfparse.hxx b/sc/source/filter/inc/rtfparse.hxx
new file mode 100644
index 000000000000..021a0b585262
--- /dev/null
+++ b/sc/source/filter/inc/rtfparse.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_RTFPARSE_HXX
+#define SC_RTFPARSE_HXX
+
+#include "eeparser.hxx"
+
+#ifdef SC_RTFPARSE_CXX
+#include <boost/ptr_container/ptr_vector.hpp>
+
+struct ScRTFCellDefault
+{
+ SfxItemSet aItemSet;
+ SCCOL nCol;
+ sal_uInt16 nTwips; // rechter Rand der Zelle
+ SCCOL nColOverlap; // MergeCell wenn >1, merged cells wenn 0
+
+ ScRTFCellDefault( SfxItemPool* pPool ) :
+ aItemSet( *pPool ), nColOverlap(1) {}
+};
+typedef boost::ptr_vector< ScRTFCellDefault > ScRTFDefaultList;
+
+// deswegen ULONG, typedef bringt's auch nicht :-(
+SV_DECL_VARARR_SORT( ScRTFColTwips, sal_uLong, 16, 4)
+
+#else // SC_RTFPARSE_CXX
+
+struct ScRTFCellDefault;
+class ScRTFDefaultList;
+class ScRTFColTwips;
+
+#endif // SC_RTFPARSE_CXX
+
+
+class EditEngine;
+
+class ScRTFParser : public ScEEParser
+{
+private:
+ ScRTFDefaultList* pDefaultList;
+ ScRTFColTwips* pColTwips;
+ ScRTFCellDefault* pInsDefault;
+ ScRTFCellDefault* pActDefault;
+ ScRTFCellDefault* pDefMerge;
+ sal_uLong nStartAdjust;
+ sal_uInt16 nLastWidth;
+ sal_Bool bNewDef;
+
+ DECL_LINK( RTFImportHdl, ImportInfo* );
+ inline void NextRow();
+ void EntryEnd( ScEEParseEntry*, const ESelection& );
+ void ProcToken( ImportInfo* );
+ void ColAdjust();
+ sal_Bool SeekTwips( sal_uInt16 nTwips, SCCOL* pCol );
+ void NewCellRow( ImportInfo* );
+
+public:
+ ScRTFParser( EditEngine* );
+ virtual ~ScRTFParser();
+ virtual sal_uLong Read( SvStream&, const String& rBaseURL );
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/scflt.hxx b/sc/source/filter/inc/scflt.hxx
new file mode 100644
index 000000000000..e66ba12e0c00
--- /dev/null
+++ b/sc/source/filter/inc/scflt.hxx
@@ -0,0 +1,766 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCFLT_HXX
+#define SC_SCFLT_HXX
+
+#include "viewopti.hxx"
+#include "collect.hxx"
+#include <tools/solar.h>
+
+// FehlerNummern
+#define errUnknownFormat 1
+#define errUnknownID 2
+#define errOutOfMemory 3
+
+// Identifiers im FileFormat
+#define ColWidthID 1
+#define ColAttrID 2
+#define RowHeightID 3
+#define RowAttrID 4
+#define FontID 5
+#define NameID 6
+#define TableID 7
+#define ObjectID 8
+#define PatternID 9
+#define DataBaseID 10
+
+// Zeilen/Spalten Flags
+#define crfSoftBreak 1
+#define crfHardBreak 2
+#define crfHidden 4
+
+// Zelltypen
+#define ctValue 1
+#define ctString 2
+#define ctFormula 3
+#define ctNote 4
+
+// FontStyles
+#define ffDontCare 0x00
+#define ffRoman 0x10
+#define ffSwiss 0x20
+#define ffModern 0x30
+#define ffScript 0x40
+#define ffDecorative 0x50
+
+// FontWeight
+#define fwNormal 400
+
+// FontAttribute
+#define atNone 0
+#define atBold 1
+#define atItalic 2
+#define atUnderline 4
+#define atStrikeOut 8
+
+// Horizontale Ausrichtung
+#define hjNone 0
+#define hjLeft 1
+#define hjCenter 2
+#define hjRight 3
+
+// Vertikale Ausrichtung
+#define vjNone 0
+#define vjTop 1
+#define vjCenter 2
+#define vjBottom 3
+
+// AusrichtungsFlags
+#define ojWordBreak 0x01
+#define ojBottomTop 0x02
+#define ojTopBottom 0x04
+
+// ZellRaster
+#define raNone 0
+#define raGray12 1
+#define raGray25 2
+#define raGray50 3
+#define raGray75 4
+#define raGray100 5
+
+// Zellschutz
+#define paProtect 1
+#define paHideFormula 2
+#define paHideAll 4
+#define paHidePrint 8
+
+// ZahlenFormatFlags
+#define vfStandard 0
+#define vfMoney 1
+#define vfThousend 2
+#define vfPercent 3
+#define vfExponent 4
+#define vfZerro 5
+#define vfDate 6
+#define vfTime 7
+#define vfBoolean 8
+#define vfStandardRed 9
+#define vfMoneyRed 10
+#define vfThousendRed 11
+#define vfPercentRed 12
+#define vfExponentRed 13
+#define vfFormula 14
+#define vfString 15
+#define vfNone 16
+
+// DatumsFormatFlags
+#define df_NDMY_Long 0
+#define df_DMY_Long 1
+#define df_MY_Long 2
+#define df_NDM_Long 3
+#define df_DM_Long 4
+#define df_M_Long 5
+#define df_NDMY_Short 6
+#define df_DMY_Short 7
+#define df_MY_Short 8
+#define df_NDM_Short 9
+#define df_DM_Short 10
+#define df_M_Short 11
+#define df_Q_Long 12
+#define df_Q_Short 13
+
+// ZeitFormatFlags
+#define tf_HMS_Long 0
+#define tf_HM_Long 1
+#define tf_HMS_Short 2
+#define tf_HM_Short 3
+
+// Attribute fuer FormatVorlage
+#define pfValue 0x01
+#define pfFont 0x02
+#define pfJustify 0x04
+#define pfFrame 0x08
+#define pfRaster 0x10
+#define pfProtection 0x20
+
+// Displayflags fuer die Tabelle
+#define dfFormula 0x0001 // Formeln
+#define dfZerro 0x0002 // Nullwerte
+#define dfGrid 0x0004 // Gitternetz
+#define dfPageBreak 0x0008 // Seitenumbruch
+#define dfColRowBar 0x0010 // Zeilen/Spalten Koepfe (Dummy)
+#define dfSyntax 0x0020 // Syntax Highlighting
+#define dfPrintPage 0x0040 // Druckbildansicht (Dummy)
+#define dfObjectAll 0x0080 // Objekte anzeigen
+#define dfObjectFrame 0x0100 // Objekte als Platzhalter
+#define dfObjectNone 0x0200 // Objekte nicht anzeigen
+#define dfNoteMark 0x0400 // Notizanzeiger
+#define dfProtectMark 0x0800 // Schutzanzeiger
+
+// Objekt Typen
+#define otNone 0 // s.u.
+#define otOle 1
+#define otImage 2
+#define otChart 3
+
+// Grafik Typen
+#define gtNone 0 // Kann nicht vorkommen
+#define gtOle 1 // Ole 1.0 Objekt
+#define gtImage 2 // Image (Bitmap oder Metafile)
+#define gtChart 3 // Chart
+
+// Datum/Uhrzeit
+struct Sc10DateTime
+{
+ sal_uInt16 Year;
+ sal_uInt16 Month;
+ sal_uInt16 Day;
+ sal_uInt16 Hour;
+ sal_uInt16 Min;
+ sal_uInt16 Sec;
+};
+
+// ZahlenFormate
+struct Sc10ValueFormat
+{
+ sal_uInt8 Format; // Zahl, Waehrung, Prozent etc.
+ sal_uInt8 Info; // Anzahl Nachkommastellen, Anzahl Stellen, bzw. Datums/Zeitformat
+};
+
+// Fontbeschreibung
+struct Sc10LogFont
+{
+ sal_Int16 lfHeight;
+ sal_Int16 lfWidth;
+ sal_Int16 lfEscapement;
+ sal_Int16 lfOrientation;
+ sal_Int16 lfWeight;
+ sal_uInt8 lfItalic;
+ sal_uInt8 lfUnderline;
+ sal_uInt8 lfStrikeOut;
+ sal_uInt8 lfCharSet;
+ sal_uInt8 lfOutPrecision;
+ sal_uInt8 lfClipPrecision;
+ sal_uInt8 lfQuality;
+ sal_uInt8 lfPitchAndFamily;
+ sal_Char lfFaceName[32];
+
+ int operator==( const Sc10LogFont& rData ) const;
+};
+
+// RGB-Frabwerte
+struct Sc10Color
+{
+ sal_uInt8 Dummy;
+ sal_uInt8 Blue;
+ sal_uInt8 Green;
+ sal_uInt8 Red;
+ int operator==( const Sc10Color& rColor ) const;
+};
+
+// Blockbeschreibung
+struct Sc10BlockRect
+{
+ sal_Int16 x1;
+ sal_Int16 y1;
+ sal_Int16 x2;
+ sal_Int16 y2;
+};
+
+// Datenbank-Bereich
+struct Sc10DataBaseRec
+{
+ sal_Char Name[32];
+ sal_Int16 Tab;
+ Sc10BlockRect Block;
+ sal_uInt8 RowHeader;
+ sal_Int16 SortField0;
+ sal_uInt8 SortUpOrder0;
+ sal_Int16 SortField1;
+ sal_uInt8 SortUpOrder1;
+ sal_Int16 SortField2;
+ sal_uInt8 SortUpOrder2;
+ sal_uInt8 IncludeFormat;
+ sal_Int16 QueryField0;
+ sal_Int16 QueryOp0;
+ sal_uInt8 QueryByString0;
+ sal_Char QueryString0[64];
+ double QueryValue0;
+ sal_Int16 QueryConnect1;
+ sal_Int16 QueryField1;
+ sal_Int16 QueryOp1;
+ sal_uInt8 QueryByString1;
+ sal_Char QueryString1[64];
+ double QueryValue1;
+ sal_Int16 QueryConnect2;
+ sal_Int16 QueryField2;
+ sal_Int16 QueryOp2;
+ sal_uInt8 QueryByString2;
+ sal_Char QueryString2[64];
+ double QueryValue2;
+};
+
+// Kopf/Fusszeilen-Beschreibung
+struct Sc10HeadFootLine
+{
+ sal_Char Title[128];
+ Sc10LogFont LogFont;
+ sal_uInt8 HorJustify;
+ sal_uInt8 VerJustify;
+ sal_uInt16 Raster;
+ sal_uInt16 Frame;
+ Sc10Color TextColor;
+ Sc10Color BackColor;
+ Sc10Color RasterColor;
+ sal_uInt16 FrameColor; // Nibble Codierte Farben link oben rechts unten
+ sal_uInt16 Reserved;
+
+ int operator==( const Sc10HeadFootLine& rData ) const;
+};
+
+// Seitenformat
+struct Sc10PageFormat
+{
+ Sc10HeadFootLine HeadLine;
+ Sc10HeadFootLine FootLine;
+ sal_Int16 Orientation;
+ sal_Int16 Width;
+ sal_Int16 Height;
+ sal_Int16 NonPrintableX;
+ sal_Int16 NonPrintableY;
+ sal_Int16 Left;
+ sal_Int16 Top;
+ sal_Int16 Right;
+ sal_Int16 Bottom;
+ sal_Int16 Head;
+ sal_Int16 Foot;
+ sal_uInt8 HorCenter;
+ sal_uInt8 VerCenter;
+ sal_uInt8 PrintGrid;
+ sal_uInt8 PrintColRow;
+ sal_uInt8 PrintNote;
+ sal_uInt8 TopBottomDir;
+ sal_Char PrintAreaName[32];
+ Sc10BlockRect PrintArea;
+ sal_Char PrnZoom[6]; // Pascal 6 Byte Realzahl
+ sal_uInt16 FirstPageNo;
+ sal_Int16 RowRepeatStart;
+ sal_Int16 RowRepeatEnd;
+ sal_Int16 ColRepeatStart;
+ sal_Int16 ColRepeatEnd;
+ sal_Char Reserved[26];
+
+ int operator==( const Sc10PageFormat& rData ) const;
+};
+
+// Tabellenschutz
+struct Sc10TableProtect
+{
+ sal_Char PassWord[16];
+ sal_uInt16 Flags;
+ sal_uInt8 Protect;
+};
+
+// Documentschutz
+struct Sc10SheetProtect
+{
+ sal_Char PassWord[16];
+ sal_uInt16 Flags;
+ sal_uInt8 Protect;
+};
+
+// Dateikopf StarCalc 1.0 Datei
+struct Sc10FileHeader
+{
+ sal_Char CopyRight[30];
+ sal_uInt16 Version;
+ sal_Char Reserved[32];
+};
+
+// Benutzer-Definierte Datei-Beschreibung
+struct Sc10FileInfo
+{
+ sal_Char Title[64];
+ sal_Char Thema[64];
+ sal_Char Keys[64];
+ sal_Char Note[256];
+ sal_Char InfoLabel0[16];
+ sal_Char InfoLabel1[16];
+ sal_Char InfoLabel2[16];
+ sal_Char InfoLabel3[16];
+ sal_Char Info0[32];
+ sal_Char Info1[32];
+ sal_Char Info2[32];
+ sal_Char Info3[32];
+ sal_Char CreateAuthor[64];
+ sal_Char ChangeAuthor[64];
+ sal_Char PrintAuthor[64];
+ Sc10DateTime CreateDate;
+ Sc10DateTime ChangeDate;
+ Sc10DateTime PrintDate;
+ sal_uInt32 PageCount;
+ sal_uInt32 ChartCount;
+ sal_uInt32 PictureCount;
+ sal_uInt32 GraphCount;
+ sal_uInt32 OleCount;
+ sal_uInt32 NoteCount;
+ sal_uInt32 TextCellCount;
+ sal_uInt32 ValueCellCount;
+ sal_uInt32 FormulaCellCount;
+ sal_uInt32 CellCount;
+ sal_Char Reserved[52];
+};
+
+// Letze Cursorposition
+struct Sc10EditStateInfo
+{
+ // Cursor Position
+ sal_uInt16 CarretX;
+ sal_uInt16 CarretY;
+ sal_uInt16 CarretZ;
+ // Linke obere Ecke der Tabelle im Fenster
+ sal_uInt16 DeltaX;
+ sal_uInt16 DeltaY;
+ sal_uInt16 DeltaZ;
+ // Ueberfluessig in StarCalc 3.0
+ sal_uInt8 DataBaseMode;
+ sal_Char Reserved[51];
+};
+
+// Attribut-Eintrag
+struct Sc10ColData
+{
+ sal_uInt16 Row;
+ sal_uInt16 Value;
+};
+
+// ZellAttribut-Beschreibung
+struct Sc10ColAttr
+{
+ sal_uInt16 Count;
+ Sc10ColData* pData;
+
+ Sc10ColAttr() : pData(NULL) {}
+};
+
+// GraphHeader
+struct Sc10GraphHeader
+{
+ sal_uInt8 Typ; // Typ der Grafik (Ole-Objekt, Image (Bitmap oder MetaFile), Chart-Object)
+ sal_Int16 CarretX; // ZellPosition der Grafik
+ sal_Int16 CarretY;
+ sal_Int16 CarretZ;
+ sal_Int32 x; // x,y Abstand zum Zellrand in Pixel (Pixel weil ich Grafiken in Fenstern ablege)
+ sal_Int32 y;
+ sal_Int32 w; // w,h Breite und Hoehe in Pixel
+ sal_Int32 h;
+ sal_uInt8 IsRelPos; // Ist die Position relativ zur Zelle oder absolute in der Tabelle
+ sal_uInt8 DoPrint; // Soll die Grafik ausgedruckt werden
+ sal_uInt16 FrameType; // Art der Umrandung um die Grafik (Keine, Einfach, Doppelt, Einfach Dick, Doppelt Dick)
+ sal_uInt8 IsTransparent; // Soll der Hintergrund gezeichnet werden
+ Sc10Color FrameColor; // Umrandungsfarbe als RGB-Wert
+ Sc10Color BackColor; // Hintergrundfarbe als RGB-Wert
+ sal_Char Reserved[32]; // Na was wohl
+};
+
+// ImageHeader
+struct Sc10ImageHeader
+{
+ sal_Char FileName[128]; // Dateiname des urspruenglich eingefuegten Bildes
+ sal_Int16 Typ; // Typ der Grafik (Bitmap oder Metafile)
+ sal_uInt8 Linked; // Kann nicht vorkommen
+ sal_Int16 x1; // Urspruengliche Groesse der Grafik (nur fuer Metafiles)
+ sal_Int16 y1;
+ sal_Int16 x2;
+ sal_Int16 y2;
+ sal_uInt32 Size; // Groesse der Grafik in BYTES
+};
+
+// ChartHeader
+struct Sc10ChartHeader
+{
+ sal_Int16 MM; // Meatfile Struktur MapMode, Breite, Hoehe
+ sal_Int16 xExt;
+ sal_Int16 yExt;
+ sal_uInt32 Size; // Groesse der Grafik in BYTES
+};
+
+// ChartSheetData
+struct Sc10ChartSheetData
+{
+ sal_uInt8 HasTitle; // Hat das Chart Daten aus der Tabell fuer einen Titel
+ sal_Int16 TitleX; // Zellposition des Titels
+ sal_Int16 TitleY;
+ sal_uInt8 HasSubTitle; // Hat das Chart Daten aus der Tabell fuer einen Untertitel
+ sal_Int16 SubTitleX; // Zellposition des Untertitels
+ sal_Int16 SubTitleY;
+ sal_uInt8 HasLeftTitle; // Hat das Chart Daten aus der Tabelle fuer einen Linken-Titel
+ sal_Int16 LeftTitleX; // Zellposition des Linken-Titels
+ sal_Int16 LeftTitleY;
+ sal_uInt8 HasLegend; // Hat das Chart Daten aus der Tabelle fuer eine Legende
+ sal_Int16 LegendX1; // Zellen der Legende
+ sal_Int16 LegendY1;
+ sal_Int16 LegendX2;
+ sal_Int16 LegendY2;
+ sal_uInt8 HasLabel; // Hat das Chart Daten aus der Tabelle fuer die Achsbeschriftung
+ sal_Int16 LabelX1; // Zellen der Achsbeschriftung
+ sal_Int16 LabelY1;
+ sal_Int16 LabelX2;
+ sal_Int16 LabelY2;
+ sal_Int16 DataX1; // Zellen der Daten
+ sal_Int16 DataY1;
+ sal_Int16 DataX2;
+ sal_Int16 DataY2;
+ sal_Char Reserved[64];
+};
+
+#define AGPie2D 1 // Pie Chart 2D
+#define AGPie3D 2 // Pie Chart 3D
+#define AGBar2D 3 // Bar Chart 2D
+#define AGBar3D 4 // Bar Chart 3D
+#define AGGantt 5 // Gantt Diagramm
+#define AGLine 6 // Line Chart
+#define AGLogLine 7 // Logarythmic-Coordinate Chart
+#define AGArea 8 // Area Chart
+#define AGHLC 11 // High-Low-Close Chart
+#define AGPolar 10 // Polar-Coordinate Chart
+
+typedef sal_Char Sc10ChartText[30];
+
+struct Sc10ChartTypeData
+{
+ sal_Int16 NumSets;
+ sal_Int16 NumPoints;
+ sal_Int16 DrawMode;
+ sal_Int16 GraphType;
+ sal_Int16 GraphStyle;
+ sal_Char GraphTitle[80];
+ sal_Char BottomTitle[80];
+ sal_Int16 SymbolData[256];
+ sal_Int16 ColorData[256];
+ sal_Int16 ThickLines[256];
+ sal_Int16 PatternData[256];
+ sal_Int16 LinePatternData[256];
+ sal_Int16 NumGraphStyles[11];
+ sal_Int16 ShowLegend;
+ Sc10ChartText LegendText[256];
+ sal_Int16 ExplodePie;
+ sal_Int16 FontUse;
+ sal_Int16 FontFamily[5];
+ sal_Int16 FontStyle[5];
+ sal_Int16 FontSize[5];
+ sal_Int16 GridStyle;
+ sal_Int16 Labels;
+ sal_Int16 LabelEvery;
+ Sc10ChartText LabelText[50];
+ sal_Char LeftTitle[80];
+ sal_Char Reserved[4646];
+};
+
+
+// FontAttribut
+class Sc10FontData : public ScDataObject
+{
+public:
+ sal_Int16 Height;
+ sal_uInt8 CharSet;
+ sal_uInt8 PitchAndFamily;
+ sal_Char FaceName[32];
+
+ Sc10FontData( const Sc10FontData& rData ) :
+ ScDataObject( rData ),
+ Height( rData.Height ),
+ CharSet( rData.CharSet ),
+ PitchAndFamily( rData.PitchAndFamily )
+ {
+ strncpy( FaceName, rData.FaceName, sizeof(FaceName) );
+ FaceName[sizeof(FaceName)-1] = 0;
+ }
+ Sc10FontData( SvStream& rStream );
+ virtual ScDataObject* Clone() const { return new Sc10FontData(*this); }
+};
+
+
+// Font-Collection
+class Sc10FontCollection : public ScCollection
+{
+protected:
+ sal_uLong nError;
+public:
+ Sc10FontCollection( SvStream& rStream );
+ sal_uLong GetError() { return nError; }
+ Sc10FontData* At(sal_uInt16 nIndex) { return (Sc10FontData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+//BereichsDaten
+class Sc10NameData : public ScDataObject
+{
+public :
+ sal_Char Name[32];
+ sal_Char Reference[64];
+ sal_Char Reserved[12];
+
+ Sc10NameData(const Sc10NameData& rData) :
+ ScDataObject( rData )
+ {
+ strncpy(Name, rData.Name, sizeof(Name));
+ Name[sizeof(Name)-1] = 0;
+ strncpy(Reference, rData.Reference, sizeof(Reference));
+ Reference[sizeof(Reference)-1] = 0;
+ memcpy(Reserved, rData.Reserved, sizeof(Reserved));
+ }
+ Sc10NameData(SvStream& rStream);
+ virtual ScDataObject* Clone() const { return new Sc10NameData(*this); }
+};
+
+
+// Bereichs-Collection
+class Sc10NameCollection : public ScCollection
+{
+protected:
+ sal_uLong nError;
+public:
+ Sc10NameCollection(SvStream& rStream);
+sal_uLong GetError() { return nError; }
+Sc10NameData* At(sal_uInt16 nIndex) { return (Sc10NameData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+// Vorlage-Daten
+class Sc10PatternData : public ScDataObject
+{
+public:
+ sal_Char Name[32];
+ Sc10ValueFormat ValueFormat;
+ Sc10LogFont LogFont;
+ sal_uInt16 Attr;
+ sal_uInt16 Justify;
+ sal_uInt16 Frame;
+ sal_uInt16 Raster;
+ sal_uInt16 nColor;
+ sal_uInt16 FrameColor;
+ sal_uInt16 Flags;
+ sal_uInt16 FormatFlags;
+ sal_Char Reserved[8];
+
+ Sc10PatternData(const Sc10PatternData& rData) :
+ ScDataObject( rData )
+ {
+ strncpy(Name, rData.Name, sizeof(Name));
+ Name[sizeof(Name)-1] = 0;
+ memcpy(&ValueFormat, &rData.ValueFormat, sizeof(ValueFormat));
+ memcpy(&LogFont, &rData.LogFont, sizeof(LogFont));
+ Attr = rData.Attr;
+ Justify = rData.Justify;
+ Frame = rData.Frame;
+ Raster = rData.Raster;
+ nColor = rData.nColor;
+ FrameColor = rData.FrameColor;
+ Flags = rData.Flags;
+ FormatFlags = rData.FormatFlags;
+ memcpy(Reserved, rData.Reserved, sizeof(Reserved));
+ }
+ Sc10PatternData(SvStream& rStream);
+virtual ScDataObject* Clone() const { return new Sc10PatternData(*this); }
+};
+
+
+// Vorlage-Collection
+class Sc10PatternCollection : public ScCollection
+{
+protected:
+ sal_uLong nError;
+public:
+ Sc10PatternCollection(SvStream& rStream);
+ sal_uLong GetError() { return nError; }
+ Sc10PatternData* At(sal_uInt16 nIndex) { return (Sc10PatternData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+// DatenBank-Daten
+class Sc10DataBaseData : public ScDataObject
+{
+public:
+ Sc10DataBaseRec DataBaseRec;
+
+ Sc10DataBaseData(const Sc10DataBaseData& rData) :
+ ScDataObject( rData )
+ {
+ memcpy(&DataBaseRec, &rData.DataBaseRec, sizeof(DataBaseRec));
+ }
+ Sc10DataBaseData(SvStream& rStream);
+virtual ScDataObject* Clone() const { return new Sc10DataBaseData(*this); }
+};
+
+
+// DatenBank-Collection
+class Sc10DataBaseCollection : public ScCollection
+{
+protected:
+ sal_uLong nError;
+ sal_Char ActName[32];
+public:
+ Sc10DataBaseCollection(SvStream& rStream);
+ sal_uLong GetError() { return nError; }
+ Sc10DataBaseData* At(sal_uInt16 nIndex) { return (Sc10DataBaseData*)ScCollection::At(nIndex); }
+private:
+ using ScCollection::At;
+};
+
+
+class Sc10PageData : public ScDataObject
+{
+public:
+ Sc10PageFormat aPageFormat;
+ Sc10PageData( const Sc10PageFormat& rFormat ) : aPageFormat(rFormat) {}
+ int operator==( const Sc10PageData& rData ) const
+ { return aPageFormat == rData.aPageFormat; }
+ virtual ScDataObject* Clone() const;
+};
+
+// Seitenformat-Collection
+class Sc10PageCollection : public ScCollection
+{
+public:
+ Sc10PageCollection() : ScCollection(1,1) {};
+ Sc10PageData* At(sal_uInt16 nIndex) { return (Sc10PageData*)ScCollection::At(nIndex); }
+ sal_uInt16 InsertFormat( const Sc10PageFormat& rData );
+ void PutToDoc( ScDocument* pDoc );
+private:
+ using ScCollection::At;
+};
+
+
+class ScfStreamProgressBar;
+
+// Import-Klasse
+class Sc10Import
+{
+ SvStream& rStream;
+ ScDocument* pDoc;
+ Sc10Color TextPalette[16];
+ Sc10Color BackPalette[16];
+ Sc10Color RasterPalette[16];
+ Sc10Color FramePalette[16];
+ Sc10SheetProtect SheetProtect;
+ Sc10FontCollection* pFontCollection;
+ Sc10NameCollection* pNameCollection;
+ Sc10PatternCollection* pPatternCollection;
+ Sc10DataBaseCollection* pDataBaseCollection;
+ sal_uLong nError;
+ sal_Int16 TabCount;
+ SCTAB nShowTab;
+ ScViewOptions aSc30ViewOpt;
+ ScfStreamProgressBar* pPrgrsBar;
+
+public:
+ Sc10Import( SvStream& rStr, ScDocument* pDocument );
+ ~Sc10Import();
+
+ sal_uLong Import();
+ void LoadFileHeader();
+ void LoadFileInfo();
+ void LoadEditStateInfo();
+ void LoadProtect();
+ void LoadViewColRowBar();
+ void LoadScrZoom();
+ void LoadPalette();
+ void LoadFontCollection();
+ void LoadNameCollection();
+ void ImportNameCollection();
+ void LoadPatternCollection();
+ void LoadDataBaseCollection();
+ void LoadTables();
+ void LoadCol(SCCOL Col, SCTAB Tab);
+ void LoadColAttr(SCCOL Col, SCTAB Tab);
+ void LoadAttr(Sc10ColAttr& rAttr);
+ void ChangeFormat(sal_uInt16 nFormat, sal_uInt16 nInfo, sal_uLong& nKey);
+ void LoadObjects();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/scfobj.hxx b/sc/source/filter/inc/scfobj.hxx
new file mode 100644
index 000000000000..c31106f16ebc
--- /dev/null
+++ b/sc/source/filter/inc/scfobj.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCFOBJ_HXX
+#define SC_SCFOBJ_HXX
+
+#include <tools/solar.h>
+
+class ScDocument;
+class Rectangle;
+
+class Sc10InsertObject
+{
+public:
+ static void InsertChart( ScDocument* pDoc, SCTAB nDestTab, const Rectangle& rRect,
+ SCTAB nSrcTab, sal_uInt16 nX1, sal_uInt16 nY1, sal_uInt16 nX2, sal_uInt16 nY2 );
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/scmem.h b/sc/source/filter/inc/scmem.h
new file mode 100644
index 000000000000..99222707b64d
--- /dev/null
+++ b/sc/source/filter/inc/scmem.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SCMEM_H
+#define SC_SCMEM_H
+
+#include <tools/solar.h>
+
+sal_Bool MemNew( void );
+void MemDelete( void );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/tokstack.hxx b/sc/source/filter/inc/tokstack.hxx
new file mode 100644
index 000000000000..56b7c017dcfa
--- /dev/null
+++ b/sc/source/filter/inc/tokstack.hxx
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TOKSTACK_HXX
+#define SC_TOKSTACK_HXX
+
+#include <string.h>
+#include <tools/debug.hxx>
+#include "compiler.hxx"
+#include "tokenarray.hxx"
+
+#include <vector>
+
+typedef OpCode DefTokenId;
+// in PRODUCT version: ambiguity between OpCode (being sal_uInt16) and UINT16
+// Unfortunately a typedef is just a dumb alias and not a real type ...
+//typedef sal_uInt16 TokenId;
+struct TokenId
+{
+ sal_uInt16 nId;
+
+ TokenId() : nId( 0 ) {}
+ TokenId( sal_uInt16 n ) : nId( n ) {}
+ TokenId( const TokenId& r ) : nId( r.nId ) {}
+ inline TokenId& operator =( const TokenId& r ) { nId = r.nId; return *this; }
+ inline TokenId& operator =( sal_uInt16 n ) { nId = n; return *this; }
+ inline operator sal_uInt16&() { return nId; }
+ inline operator const sal_uInt16&() const { return nId; }
+ inline sal_Bool operator <( sal_uInt16 n ) const { return nId < n; }
+ inline sal_Bool operator >( sal_uInt16 n ) const { return nId > n; }
+ inline sal_Bool operator <=( sal_uInt16 n ) const { return nId <= n; }
+ inline sal_Bool operator >=( sal_uInt16 n ) const { return nId >= n; }
+ inline sal_Bool operator ==( sal_uInt16 n ) const { return nId == n; }
+ inline sal_Bool operator !=( sal_uInt16 n ) const { return nId != n; }
+};
+
+
+//------------------------------------------------------------------------
+struct ScComplexRefData;
+class TokenStack;
+class ScToken;
+
+
+enum E_TYPE
+{
+ T_Id, // Id-Folge
+ T_Str, // String
+ T_D, // Double
+ T_Err, // Error code
+ T_RefC, // Cell Reference
+ T_RefA, // Area Reference
+ T_RN, // Range Name
+ T_Ext, // irgendwas Unbekanntes mit Funktionsnamen
+ T_Nlf, // token for natural language formula
+ T_Matrix, // token for inline arrays
+ T_ExtName, // token for external names
+ T_ExtRefC,
+ T_ExtRefA,
+ T_Error // fuer Abfrage im Fehlerfall
+};
+
+
+
+
+class TokenPool
+{
+ // !ACHTUNG!: externe Id-Basis ist 1, interne 0!
+ // Ausgabe Id = 0 -> Fehlerfall
+ private:
+ String** ppP_Str; // Pool fuer Strings
+ sal_uInt16 nP_Str; // ...mit Groesse
+ sal_uInt16 nP_StrAkt; // ...und Schreibmarke
+
+ double* pP_Dbl; // Pool fuer Doubles
+ sal_uInt16 nP_Dbl;
+ sal_uInt16 nP_DblAkt;
+
+ sal_uInt16* pP_Err; // Pool for error codes
+ sal_uInt16 nP_Err;
+ sal_uInt16 nP_ErrAkt;
+
+ ScSingleRefData** ppP_RefTr; // Pool fuer Referenzen
+ sal_uInt16 nP_RefTr;
+ sal_uInt16 nP_RefTrAkt;
+
+ sal_uInt16* pP_Id; // Pool fuer Id-Folgen
+ sal_uInt16 nP_Id;
+ sal_uInt16 nP_IdAkt;
+ sal_uInt16 nP_IdLast; // letzter Folgen-Beginn
+
+ struct EXTCONT
+ {
+ DefTokenId eId;
+ String aText;
+ EXTCONT( const DefTokenId e, const String& r ) :
+ eId( e ), aText( r ){}
+ };
+ EXTCONT** ppP_Ext;
+ sal_uInt16 nP_Ext;
+ sal_uInt16 nP_ExtAkt;
+
+ struct NLFCONT
+ {
+ ScSingleRefData aRef;
+ NLFCONT( const ScSingleRefData& r ) : aRef( r ) {}
+ };
+ NLFCONT** ppP_Nlf;
+ sal_uInt16 nP_Nlf;
+ sal_uInt16 nP_NlfAkt;
+
+ ScMatrix** ppP_Matrix; // Pool fuer Matricies
+ sal_uInt16 nP_Matrix;
+ sal_uInt16 nP_MatrixAkt;
+
+ /** for storage of named ranges */
+ struct RangeName
+ {
+ sal_uInt16 mnIndex;
+ bool mbGlobal;
+ };
+ ::std::vector<RangeName> maRangeNames;
+
+ /** for storage of external names */
+ struct ExtName
+ {
+ sal_uInt16 mnFileId;
+ String maName;
+ };
+ ::std::vector<ExtName> maExtNames;
+
+ /** for storage of external cell references */
+ struct ExtCellRef
+ {
+ sal_uInt16 mnFileId;
+ String maTabName;
+ ScSingleRefData maRef;
+ };
+ ::std::vector<ExtCellRef> maExtCellRefs;
+
+ /** for storage of external area references */
+ struct ExtAreaRef
+ {
+ sal_uInt16 mnFileId;
+ String maTabName;
+ ScComplexRefData maRef;
+ };
+ ::std::vector<ExtAreaRef> maExtAreaRefs;
+
+ sal_uInt16* pElement; // Array mit Indizes fuer Elemente
+ E_TYPE* pType; // ...mit Typ-Info
+ sal_uInt16* pSize; // ...mit Laengenangabe (Anz. sal_uInt16)
+ sal_uInt16 nElement;
+ sal_uInt16 nElementAkt;
+
+ static const sal_uInt16 nScTokenOff;// Offset fuer SC-Token
+#ifdef DBG_UTIL
+ sal_uInt16 nRek; // Rekursionszaehler
+#endif
+ ScTokenArray* pScToken; // Tokenbastler
+
+ void GrowString( void );
+ void GrowDouble( void );
+ void GrowTripel( void );
+ void GrowId( void );
+ void GrowElement( void );
+ void GrowExt( void );
+ void GrowNlf( void );
+ void GrowMatrix( void );
+ void GetElement( const sal_uInt16 nId );
+ void GetElementRek( const sal_uInt16 nId );
+ public:
+ TokenPool( void );
+ ~TokenPool();
+ inline TokenPool& operator <<( const TokenId nId );
+ inline TokenPool& operator <<( const DefTokenId eId );
+ inline TokenPool& operator <<( TokenStack& rStack );
+ void operator >>( TokenId& rId );
+ inline void operator >>( TokenStack& rStack );
+ inline const TokenId Store( void );
+ const TokenId Store( const double& rDouble );
+
+ // nur fuer Range-Names
+ const TokenId Store( const sal_uInt16 nIndex );
+ inline const TokenId Store( const sal_Int16 nWert );
+ const TokenId Store( const String& rString );
+ const TokenId Store( const ScSingleRefData& rTr );
+ const TokenId Store( const ScComplexRefData& rTr );
+
+ const TokenId Store( const DefTokenId eId, const String& rName );
+ // 4 externals (e.g. AddIns, Makros...)
+ const TokenId StoreNlf( const ScSingleRefData& rTr );
+ const TokenId StoreMatrix();
+ const TokenId StoreName( sal_uInt16 nIndex, bool bGlobal );
+ const TokenId StoreExtName( sal_uInt16 nFileId, const String& rName );
+ const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+ const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
+
+ inline const TokenId LastId( void ) const;
+ inline const ScTokenArray* operator []( const TokenId nId );
+ void Reset( void );
+ inline E_TYPE GetType( const TokenId& nId ) const;
+ sal_Bool IsSingleOp( const TokenId& nId, const DefTokenId eId ) const;
+ const String* GetExternal( const TokenId& nId ) const;
+ ScMatrix* GetMatrix( unsigned int n ) const;
+};
+
+
+
+
+class TokenStack
+ // Stack fuer Token-Ids: Id 0 sollte reserviert bleiben als
+ // fehlerhafte Id, da z.B. Get() im Fehlerfall 0 liefert
+{
+ private:
+ TokenId* pStack; // Stack als Array
+ sal_uInt16 nPos; // Schreibmarke
+ sal_uInt16 nSize; // Erster Index ausserhalb des Stacks
+ public:
+ TokenStack( sal_uInt16 nNewSize = 1024 );
+ ~TokenStack();
+ inline TokenStack& operator <<( const TokenId nNewId );
+ inline void operator >>( TokenId &rId );
+
+ inline void Reset( void );
+
+ inline bool HasMoreTokens() const { return nPos > 0; }
+ inline const TokenId Get( void );
+};
+
+
+
+
+inline const TokenId TokenStack::Get( void )
+{
+ DBG_ASSERT( nPos > 0,
+ "*TokenStack::Get(): Leer ist leer, ist leer, ist leer, ist..." );
+
+ TokenId nRet;
+
+ if( nPos == 0 )
+ nRet = 0;
+ else
+ {
+ nPos--;
+ nRet = pStack[ nPos ];
+ }
+
+ return nRet;
+}
+
+
+inline TokenStack &TokenStack::operator <<( const TokenId nNewId )
+{// Element auf Stack
+ DBG_ASSERT( nPos < nSize, "*TokenStack::<<(): Stackueberlauf" );
+ if( nPos < nSize )
+ {
+ pStack[ nPos ] = nNewId;
+ nPos++;
+ }
+
+ return *this;
+}
+
+
+inline void TokenStack::operator >>( TokenId& rId )
+{// Element von Stack
+ DBG_ASSERT( nPos > 0,
+ "*TokenStack::>>(): Leer ist leer, ist leer, ist leer, ..." );
+ if( nPos > 0 )
+ {
+ nPos--;
+ rId = pStack[ nPos ];
+ }
+}
+
+
+inline void TokenStack::Reset( void )
+{
+ nPos = 0;
+}
+
+
+
+
+inline TokenPool& TokenPool::operator <<( const TokenId nId )
+{
+ // POST: nId's werden hintereinander im Pool unter einer neuen Id
+ // abgelegt. Vorgang wird mit >> oder Store() abgeschlossen
+ // nId -> ( sal_uInt16 ) nId - 1;
+ DBG_ASSERT( ( sal_uInt16 ) nId < nScTokenOff,
+ "-TokenPool::operator <<: TokenId im DefToken-Bereich!" );
+
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) nId ) - 1;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline TokenPool& TokenPool::operator <<( const DefTokenId eId )
+{
+ DBG_ASSERT( ( sal_uInt32 ) eId + nScTokenOff < 0xFFFF,
+ "-TokenPool::operator<<: enmum zu gross!" );
+
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) eId ) + nScTokenOff;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline TokenPool& TokenPool::operator <<( TokenStack& rStack )
+{
+ if( nP_IdAkt >= nP_Id )
+ GrowId();
+
+ pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) rStack.Get() ) - 1;
+ nP_IdAkt++;
+
+ return *this;
+}
+
+
+inline void TokenPool::operator >>( TokenStack& rStack )
+{
+ TokenId nId;
+ *this >> nId;
+ rStack << nId;
+}
+
+
+inline const TokenId TokenPool::Store( void )
+{
+ TokenId nId;
+ *this >> nId;
+ return nId;
+}
+
+
+inline const TokenId TokenPool::Store( const sal_Int16 nWert )
+{
+ return Store( ( double ) nWert );
+}
+
+
+inline const TokenId TokenPool::LastId( void ) const
+{
+ return ( TokenId ) nElementAkt; // stimmt, da Ausgabe mit Offset 1!
+}
+
+
+const inline ScTokenArray* TokenPool::operator []( const TokenId nId )
+{
+ pScToken->Clear();
+
+ if( nId )
+ {//...nur wenn nId > 0!
+#ifdef DBG_UTIL
+ nRek = 0;
+#endif
+ GetElement( ( sal_uInt16 ) nId - 1 );
+ }
+
+ return pScToken;
+}
+
+
+inline E_TYPE TokenPool::GetType( const TokenId& rId ) const
+{
+ E_TYPE nRet;
+
+ sal_uInt16 nId = (sal_uInt16) rId - 1;
+
+ if( nId < nElementAkt )
+ nRet = pType[ nId ] ;
+ else
+ nRet = T_Error;
+
+ return nRet;
+}
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/tool.h b/sc/source/filter/inc/tool.h
new file mode 100644
index 000000000000..8b0aac6a05d8
--- /dev/null
+++ b/sc/source/filter/inc/tool.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TOOL_H
+#define SC_TOOL_H
+
+#include <attrib.hxx> //!!! noch noetig?????
+#include <document.hxx>
+
+// Defaultwerte
+const sal_uInt8 nDezStd = 0; // Dezimalstellen fuer Standard-Zellen
+const sal_uInt8 nDezFloat = 2; // " " Float-Zellen
+
+void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char *pString );
+
+void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt );
+
+void InitPage( void );
+
+String DosToSystem( sal_Char *pSource );
+
+double SnumToDouble( sal_Int16 nVal );
+
+double Snum32ToDouble( sal_uInt32 nValue );
+
+typedef sal_uInt16 StampTyp;
+
+#define MAKE_STAMP(nF,nS) ((nS&0x0F)+((nF&0x7F)*16))
+ // Bit 0...3 = Bit 0...3 von Stellenzahl
+ // Bit 4...10 = Bit 0...6 von Formatbyte
+
+class FormIdent
+{
+private:
+ StampTyp nStamp; // Identifikations-Schluessel
+ SfxUInt32Item* pAttr; // zugehoeriges Attribut
+public:
+ FormIdent( void )
+ {
+ nStamp = 0;
+ pAttr = NULL;
+ }
+
+ FormIdent( sal_uInt8 nFormat, sal_uInt8 nSt, SfxUInt32Item& rAttr )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ pAttr = &rAttr;
+ }
+
+ FormIdent( sal_uInt8 nFormat, sal_uInt8 nSt )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ pAttr = NULL;
+ }
+
+ sal_Bool operator ==( const FormIdent& rComp ) const
+ {
+ return ( nStamp == rComp.nStamp );
+ }
+
+ sal_Bool operator ==( const StampTyp& rStamp ) const
+ {
+ return ( nStamp == rStamp );
+ }
+
+ StampTyp GetStamp( void ) const
+ {
+ return nStamp;
+ }
+
+ SfxUInt32Item* GetAttr( void )
+ {
+ return pAttr;
+ }
+
+ void SetStamp( sal_uInt8 nFormat, sal_uInt8 nSt )
+ {
+ nStamp = MAKE_STAMP( nFormat, nSt );
+ }
+};
+
+
+#define __nSize 2048
+
+
+
+
+class FormCache
+{
+private:
+ FormIdent aIdents[ __nSize ]; //gepufferte Formate
+ sal_Bool bValid[ __nSize ];
+ FormIdent aCompareIdent; // zum Vergleichen
+ sal_uInt8 nDefaultFormat; // Defaultformat der Datei
+ SvNumberFormatter* pFormTable; // Value-Format-Table-Anker
+ StampTyp nIndex;
+ LanguageType eLanguage; // Systemsprache
+
+ SfxUInt32Item* NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt );
+public:
+ FormCache( ScDocument*, sal_uInt8 nNewDefaultFormat = 0xFF );
+ ~FormCache();
+
+ inline const SfxUInt32Item* GetAttr( sal_uInt8 nFormat, sal_uInt8 nSt );
+ void SetDefaultFormat( sal_uInt8 nD = 0xFF )
+ {
+ nDefaultFormat = nD;
+ }
+};
+
+
+inline const SfxUInt32Item* FormCache::GetAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
+{
+ // PREC: nFormat = Lotus-Format-Byte
+ // nSt = Stellenzahl
+ // POST: return = zu nFormat und nSt passendes SC-Format
+ SfxUInt32Item* pAttr;
+ SfxUInt32Item* pRet;
+
+ aCompareIdent.SetStamp( nFormat, nSt );
+ nIndex = aCompareIdent.GetStamp();
+ DBG_ASSERT( nIndex < __nSize, "FormCache::GetAttr(): Uuuuuuups... so nicht!" );
+ if( bValid[ nIndex ] )
+ pRet = aIdents[ nIndex ].GetAttr();
+ else
+ {
+ // neues Attribut anlegen
+ pAttr = NewAttr( nFormat, nSt );
+ DBG_ASSERT( pAttr, "FormCache::GetAttr(): Nix Speicherus" );
+
+ aIdents[ nIndex ] = FormIdent( nFormat, nSt, *pAttr );
+ bValid[ nIndex ] = sal_True;
+
+ pRet = pAttr;
+ }
+ return pRet;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xcl97dum.hxx b/sc/source/filter/inc/xcl97dum.hxx
new file mode 100644
index 000000000000..cc7acd23bd8a
--- /dev/null
+++ b/sc/source/filter/inc/xcl97dum.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97DUM_HXX
+#define SC_XCL97DUM_HXX
+
+#include "excrecds.hxx"
+
+// --- class ExcDummy8_xx --------------------------------------------
+
+class ExcDummy8_00a : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const sal_uInt8* GetData() const;
+};
+
+
+class ExcDummy8_00b : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const sal_uInt8* GetData() const;
+};
+
+
+class ExcDummy8_040 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const sal_uInt8* GetData() const;
+};
+
+
+class ExcDummy8_041 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const sal_uInt8* GetData() const;
+};
+
+
+class ExcDummy8_02 : public ExcDummyRec
+{
+private:
+ static const sal_uInt8 pMyData[];
+ static const sal_Size nMyLen;
+public:
+ virtual sal_Size GetLen() const;
+ virtual const sal_uInt8* GetData() const;
+};
+
+
+#endif // _XCL97DUM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xcl97esc.hxx b/sc/source/filter/inc/xcl97esc.hxx
new file mode 100644
index 000000000000..55f33b6033e4
--- /dev/null
+++ b/sc/source/filter/inc/xcl97esc.hxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97ESC_HXX
+#define SC_XCL97ESC_HXX
+
+#include <memory>
+#include <tools/table.hxx>
+#include <tools/stack.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include "xlescher.hxx"
+#include "xeroot.hxx"
+#include <vector>
+
+// 0 = Export TBX form controls, 1 = Export OCX form controls.
+#define EXC_EXP_OCX_CTRL 0
+
+namespace utl { class TempFile; }
+
+// ============================================================================
+
+class SvStream;
+
+class XclEscherExGlobal : public EscherExGlobal, protected XclExpRoot
+{
+public:
+ explicit XclEscherExGlobal( const XclExpRoot& rRoot );
+
+private:
+ /** Overloaded to create a new temporary file and return its stream. */
+ virtual SvStream* ImplQueryPictureStream();
+
+private:
+ ::std::auto_ptr< ::utl::TempFile > mxPicTempFile;
+ ::std::auto_ptr< SvStream > mxPicStrm;
+};
+
+// ============================================================================
+
+class XclObj;
+class XclExpDffAnchorBase;
+class XclEscherHostAppData;
+class XclEscherClientData;
+class XclEscherClientTextbox;
+#if EXC_EXP_OCX_CTRL
+class XclExpOcxControlObj;
+#else
+class XclExpTbxControlObj;
+#endif
+class XclExpShapeObj;
+class EscherExHostAppData;
+class ShapeInteractionHelper
+{
+public:
+ static XclExpShapeObj* CreateShapeObj( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference<
+ ::com::sun::star::drawing::XShape >& xShape );
+ static void PopulateShapeInteractionInfo( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, EscherExHostAppData& rHostAppData );
+};
+
+class XclEscherEx : public EscherEx, protected XclExpRoot
+{
+public:
+ explicit XclEscherEx(
+ const XclExpRoot& rRoot,
+ XclExpObjectManager& rObjMgr,
+ SvStream& rStrm,
+ const XclEscherEx* pParent = 0 );
+ virtual ~XclEscherEx();
+
+ /** Called by MSODRAWING record constructors to initialize the DFF stream
+ fragment they will own. returns the DFF fragment identifier. */
+ sal_uInt32 InitNextDffFragment();
+ /** Called after some data has been written to the DFF stream, to update
+ the end position of the DFF fragment owned by an MSODRAWING record. */
+ void UpdateDffFragmentEnd();
+
+ /** Returns the position of the specified DFF stream fragment. */
+ sal_uInt32 GetDffFragmentPos( sal_uInt32 nFragmentKey );
+ /** Returns the size of the specified DFF stream fragment. */
+ sal_uInt32 GetDffFragmentSize( sal_uInt32 nFragmentKey );
+ /** Returns true, if there is more data left in the DFF stream than owned
+ by the last MSODRAWING record. */
+ bool HasPendingDffData();
+
+ /** Creates a new DFF client anchor object and calculates the anchor
+ position of the passed object. Caller takes ownership! */
+ XclExpDffAnchorBase* CreateDffAnchor( const SdrObject& rSdrObj ) const;
+
+ virtual EscherExHostAppData* StartShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape,
+ const Rectangle* pChildAnchor );
+ virtual void EndShape( sal_uInt16 nShapeType, sal_uInt32 nShapeID );
+ virtual EscherExHostAppData* EnterAdditionalTextGroup();
+
+ /// Flush and merge PicStream into EscherStream
+ void EndDocument();
+
+#if EXC_EXP_OCX_CTRL
+ /** Creates an OCX form control OBJ record from the passed form control.
+ @descr Writes the form control data to the 'Ctls' stream. */
+ XclExpOcxControlObj* CreateCtrlObj(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+private:
+ SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream.
+#else
+ /** Creates a TBX form control OBJ record from the passed form control. */
+ XclExpTbxControlObj* CreateCtrlObj(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+private:
+ /** Tries to get the name of a Basic macro from a control. */
+ void ConvertTbxMacro(
+ XclExpTbxControlObj& rTbxCtrlObj,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::awt::XControlModel > xCtrlModel );
+#endif
+
+ void DeleteCurrAppData();
+
+private:
+ XclExpObjectManager& mrObjMgr;
+ Stack aStack;
+ XclObj* pCurrXclObj;
+ XclEscherHostAppData* pCurrAppData;
+ XclEscherClientData* pTheClientData; // always the same
+ XclEscherClientTextbox* pAdditionalText;
+ sal_uInt16 nAdditionalText;
+ sal_uInt32 mnNextKey;
+ bool mbIsRootDff;
+};
+
+// --- class XclEscherHostAppData ------------------------------------
+
+class XclEscherHostAppData : public EscherExHostAppData
+{
+private:
+ sal_Bool bStackedGroup;
+
+public:
+ XclEscherHostAppData() : bStackedGroup( false )
+ {}
+ inline void SetStackedGroup( sal_Bool b ) { bStackedGroup = b; }
+ inline sal_Bool IsStackedGroup() const { return bStackedGroup; }
+};
+
+
+
+// ============================================================================
+
+// --- class XclEscherClientData -------------------------------------
+
+class XclEscherClientData : public EscherExClientRecord_Base
+{
+public:
+ XclEscherClientData() {}
+ virtual void WriteData( EscherEx& rEx ) const;
+};
+
+
+// --- class XclEscherClientTextbox ----------------------------------
+
+class SdrTextObj;
+
+class XclEscherClientTextbox : public EscherExClientRecord_Base, protected XclExpRoot
+{
+private:
+ const SdrTextObj& rTextObj;
+ XclObj* pXclObj;
+
+public:
+ XclEscherClientTextbox(
+ const XclExpRoot& rRoot,
+ const SdrTextObj& rObj,
+ XclObj* pObj );
+
+ //! ONLY for the AdditionalText mimic
+ inline void SetXclObj( XclObj* p ) { pXclObj = p; }
+
+ virtual void WriteData( EscherEx& rEx ) const;
+};
+
+
+
+#endif // _XCL97ESC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx
new file mode 100644
index 000000000000..6b08ffa0e2ca
--- /dev/null
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -0,0 +1,627 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XCL97REC_HXX
+#define SC_XCL97REC_HXX
+
+#include "excrecds.hxx"
+#include "xcl97esc.hxx"
+#include "xlstyle.hxx"
+
+// ============================================================================
+
+class XclObj;
+class XclExpMsoDrawing;
+class SdrCaptionObj;
+
+class XclExpObjList : public List, public ExcEmptyRec, protected XclExpRoot
+{
+public:
+ explicit XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx );
+ virtual ~XclExpObjList();
+
+ XclObj* First() { return (XclObj*) List::First(); }
+ XclObj* Next() { return (XclObj*) List::Next(); }
+
+ /// return: 1-based ObjId
+ ///! count>=0xFFFF: Obj will be deleted, return 0
+ sal_uInt16 Add( XclObj* );
+
+ inline XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; }
+
+ /// close groups and DgContainer opened in ctor
+ void EndSheet();
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ static void ResetCounters();
+
+private:
+ static sal_Int32 mnDrawingMLCount, mnVmlCount;
+ SCTAB mnScTab;
+
+ XclEscherEx& mrEscherEx;
+ XclExpMsoDrawing* pMsodrawingPerSheet;
+ XclExpMsoDrawing* pSolverContainer;
+};
+
+
+// --- class XclObj --------------------------------------------------
+
+class XclTxo;
+class SdrTextObj;
+
+class XclObj : public XclExpRecord
+{
+protected:
+ XclEscherEx& mrEscherEx;
+ XclExpMsoDrawing* pMsodrawing;
+ XclExpMsoDrawing* pClientTextbox;
+ XclTxo* pTxo;
+ sal_uInt16 mnObjType;
+ sal_uInt16 nObjId;
+ sal_uInt16 nGrbit;
+ SCTAB mnScTab;
+ sal_Bool bFirstOnSheet;
+
+ bool mbOwnEscher; /// true = Escher part created on the fly.
+
+ /** @param bOwnEscher If set to true, this object will create its escher data.
+ See SetOwnEscher() for details. */
+ explicit XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher = false );
+
+ void ImplWriteAnchor( const XclExpRoot& rRoot, const SdrObject* pSdrObj, const Rectangle* pChildAnchor );
+
+ // overwritten for writing MSODRAWING record
+ virtual void WriteBody( XclExpStream& rStrm );
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+ void SaveTextRecs( XclExpStream& rStrm );
+
+public:
+ virtual ~XclObj();
+
+ inline sal_uInt16 GetObjType() const { return mnObjType; }
+
+ inline void SetId( sal_uInt16 nId ) { nObjId = nId; }
+ inline sal_uInt16 GetId() const { return nObjId; }
+
+ inline void SetTab( SCTAB nScTab ) { mnScTab = nScTab; }
+ inline SCTAB GetTab() const { return mnScTab; }
+
+ inline void SetLocked( sal_Bool b )
+ { b ? nGrbit |= 0x0001 : nGrbit &= ~0x0001; }
+ inline void SetPrintable( sal_Bool b )
+ { b ? nGrbit |= 0x0010 : nGrbit &= ~0x0010; }
+ inline void SetAutoFill( sal_Bool b )
+ { b ? nGrbit |= 0x2000 : nGrbit &= ~0x2000; }
+ inline void SetAutoLine( sal_Bool b )
+ { b ? nGrbit |= 0x4000 : nGrbit &= ~0x4000; }
+
+ // set corresponding Excel object type in OBJ/ftCmo
+ void SetEscherShapeType( sal_uInt16 nType );
+ inline void SetEscherShapeTypeGroup() { mnObjType = EXC_OBJTYPE_GROUP; }
+
+ /** If set to true, this object has created its own escher data.
+ @descr This causes the function EscherEx::EndShape() to not post process
+ this object. This is used i.e. for form controls. They are not handled in
+ the svx base code, so the XclExpEscherOcxCtrl c'tor creates the escher data
+ itself. The svx base code does not receive the correct shape ID after the
+ EscherEx::StartShape() call, which would result in deleting the object in
+ EscherEx::EndShape(). */
+ inline void SetOwnEscher( bool bOwnEscher = true ) { mbOwnEscher = bOwnEscher; }
+ /** Returns true, if the object has created the escher data itself.
+ @descr See SetOwnEscher() for details. */
+ inline bool IsOwnEscher() const { return mbOwnEscher; }
+
+ //! actually writes ESCHER_ClientTextbox
+ void SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj );
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// --- class XclObjComment -------------------------------------------
+
+class XclObjComment : public XclObj
+{
+ ScAddress maScPos;
+ std::auto_ptr< SdrCaptionObj >
+ mpCaption;
+ bool mbVisible;
+ Rectangle maFrom;
+ Rectangle maTo;
+
+public:
+ XclObjComment( XclExpObjectManager& rObjMgr,
+ const Rectangle& rRect, const EditTextObject& rEditObj, SdrCaptionObj* pCaption, bool bVisible, const ScAddress& rAddress, Rectangle &rFrom, Rectangle &To );
+ virtual ~XclObjComment();
+
+ /** c'tor process for formatted text objects above .
+ @descr used to construct the MSODRAWING Escher object properties. */
+ void ProcessEscherObj( const XclExpRoot& rRoot,
+ const Rectangle& rRect, SdrObject* pCaption, bool bVisible );
+
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+// --- class XclObjDropDown ------------------------------------------
+
+class XclObjDropDown : public XclObj
+{
+private:
+ sal_Bool bIsFiltered;
+
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+protected:
+public:
+ XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, sal_Bool bFilt );
+ virtual ~XclObjDropDown();
+};
+
+
+// --- class XclTxo --------------------------------------------------
+
+class SdrTextObj;
+
+class XclTxo : public ExcRecord
+{
+public:
+ XclTxo( const String& rString, sal_uInt16 nFontIx = EXC_FONT_APP );
+ XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rEditObj );
+ XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption );
+
+ inline void SetHorAlign( sal_uInt8 nHorAlign ) { mnHorAlign = nHorAlign; }
+ inline void SetVerAlign( sal_uInt8 nVerAlign ) { mnVerAlign = nVerAlign; }
+
+ virtual void Save( XclExpStream& rStrm );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+private:
+ virtual void SaveCont( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mpString; /// Text and formatting data.
+ sal_uInt16 mnRotation; /// Text rotation.
+ sal_uInt8 mnHorAlign; /// Horizontal alignment.
+ sal_uInt8 mnVerAlign; /// Vertical alignment.
+};
+
+
+// --- class XclObjOle -----------------------------------------------
+
+class XclObjOle : public XclObj
+{
+private:
+
+ const SdrObject& rOleObj;
+ SotStorage* pRootStorage;
+
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+public:
+ XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj );
+ virtual ~XclObjOle();
+
+ virtual void Save( XclExpStream& rStrm );
+};
+
+
+// --- class XclObjAny -----------------------------------------------
+
+class XclObjAny : public XclObj
+{
+protected:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+public:
+ XclObjAny( XclExpObjectManager& rObjMgr,
+ const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape );
+ virtual ~XclObjAny();
+
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
+ GetShape() const { return mxShape; }
+
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+ static void WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj );
+ static void WriteFromTo( XclExpXmlStream& rStrm, const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape, SCTAB nTab );
+
+private:
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
+ mxShape;
+};
+
+
+// --- class ExcBof8_Base --------------------------------------------
+
+class ExcBof8_Base : public ExcBof_Base
+{
+protected:
+ sal_uInt32 nFileHistory; // bfh
+ sal_uInt32 nLowestBiffVer; // sfo
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBof8_Base();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// --- class ExcBofW8 ------------------------------------------------
+// Header Record fuer WORKBOOKS
+
+class ExcBofW8 : public ExcBof8_Base
+{
+public:
+ ExcBofW8();
+};
+
+
+// --- class ExcBof8 -------------------------------------------------
+// Header Record fuer WORKSHEETS
+
+class ExcBof8 : public ExcBof8_Base
+{
+public:
+ ExcBof8();
+};
+
+
+// --- class ExcBundlesheet8 -----------------------------------------
+
+class ExcBundlesheet8 : public ExcBundlesheetBase
+{
+private:
+ String sUnicodeName;
+ XclExpString GetName() const;
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+public:
+ ExcBundlesheet8( RootData& rRootData, SCTAB nTab );
+ ExcBundlesheet8( const String& rString );
+
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+// --- class XclObproj -----------------------------------------------
+
+class XclObproj : public ExcRecord
+{
+public:
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// ---- class XclCodename --------------------------------------------
+
+class XclCodename : public ExcRecord
+{
+private:
+ XclExpString aName;
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclCodename( const String& );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+
+// ---- Scenarios ----------------------------------------------------
+// - ExcEScenarioCell a cell of a scenario range
+// - ExcEScenario all ranges of a scenario table
+// - ExcEScenarioManager list of scenario tables
+
+class ExcEScenarioCell
+{
+private:
+ sal_uInt16 nCol;
+ sal_uInt16 nRow;
+ XclExpString sText;
+
+protected:
+public:
+ ExcEScenarioCell( sal_uInt16 nC, sal_uInt16 nR, const String& rTxt );
+
+ inline sal_Size GetStringBytes()
+ { return sText.GetSize(); }
+
+ void WriteAddress( XclExpStream& rStrm );
+ void WriteText( XclExpStream& rStrm );
+
+ void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+class ExcEScenario : public ExcRecord, private List
+{
+private:
+ sal_Size nRecLen;
+ XclExpString sName;
+ XclExpString sComment;
+ XclExpString sUserName;
+ sal_uInt8 nProtected;
+
+ inline ExcEScenarioCell* _First() { return (ExcEScenarioCell*) List::First(); }
+ inline ExcEScenarioCell* _Next() { return (ExcEScenarioCell*) List::Next(); }
+
+ sal_Bool Append( sal_uInt16 nCol, sal_uInt16 nRow, const String& rTxt );
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+public:
+ ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcEScenario();
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+class ExcEScenarioManager : public ExcRecord, private List
+{
+private:
+ sal_uInt16 nActive;
+
+ inline ExcEScenario* _First() { return (ExcEScenario*) List::First(); }
+ inline ExcEScenario* _Next() { return (ExcEScenario*) List::Next(); }
+
+ inline void Append( ExcEScenario* pScen )
+ { List::Insert( pScen, LIST_APPEND ); }
+
+ virtual void SaveCont( XclExpStream& rStrm );
+
+protected:
+public:
+ ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab );
+ virtual ~ExcEScenarioManager();
+
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+};
+
+// ============================================================================
+
+/** Represents a SHEETPROTECTION record that stores sheet protection
+ options. Note that a sheet still needs to save its sheet protection
+ options even when it's not protected. */
+class XclExpSheetProtectOptions : public XclExpRecord
+{
+public:
+ explicit XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnOptions; /// Encoded sheet protection options.
+};
+
+// ============================================================================
+
+class XclCalccount : public ExcRecord
+{
+private:
+ sal_uInt16 nCount;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclCalccount( const ScDocument& );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclIteration : public ExcRecord
+{
+private:
+ sal_uInt16 nIter;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclIteration( const ScDocument& );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclDelta : public ExcRecord
+{
+private:
+ double fDelta;
+protected:
+ virtual void SaveCont( XclExpStream& rStrm );
+public:
+ XclDelta( const ScDocument& );
+
+ virtual sal_uInt16 GetNum() const;
+ virtual sal_Size GetLen() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+
+
+
+class XclRefmode : public XclExpBoolRecord
+{
+public:
+ XclRefmode( const ScDocument& );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpFileEncryption : public XclExpRecord
+{
+public:
+ explicit XclExpFileEncryption( const XclExpRoot& rRoot );
+ virtual ~XclExpFileEncryption();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpRoot& mrRoot;
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceHdr : public XclExpUInt16Record
+{
+public:
+ explicit XclExpInterfaceHdr( sal_uInt16 nCodePage );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** End of User Interface Records */
+class XclExpInterfaceEnd : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceEnd();
+ virtual ~XclExpInterfaceEnd();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Write Access User Name - This record contains the user name, which is
+ the name you type when you install Excel. */
+class XclExpWriteAccess : public XclExpRecord
+{
+public:
+ explicit XclExpWriteAccess();
+ virtual ~XclExpWriteAccess();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpFileSharing : public XclExpRecord
+{
+public:
+ explicit XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly );
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maUserName;
+ sal_uInt16 mnPasswordHash;
+ bool mbRecommendReadOnly;
+};
+
+// ============================================================================
+
+class XclExpProt4Rev : public XclExpRecord
+{
+public:
+ explicit XclExpProt4Rev();
+ virtual ~XclExpProt4Rev();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpProt4RevPass : public XclExpRecord
+{
+public:
+ explicit XclExpProt4RevPass();
+ virtual ~XclExpProt4RevPass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpRecalcId : public XclExpDummyRecord
+{
+public:
+ explicit XclExpRecalcId();
+};
+
+// ============================================================================
+
+class XclExpBookExt : public XclExpDummyRecord
+{
+public:
+ explicit XclExpBookExt();
+};
+
+
+#endif // _XCL97REC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xechart.hxx b/sc/source/filter/inc/xechart.hxx
new file mode 100644
index 000000000000..373181f6c321
--- /dev/null
+++ b/sc/source/filter/inc/xechart.hxx
@@ -0,0 +1,1287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XECHART_HXX
+#define SC_XECHART_HXX
+
+#include <tools/gen.hxx>
+#include "xerecord.hxx"
+#include "xlchart.hxx"
+#include "xlformula.hxx"
+#include "xlstyle.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+class Size;
+
+namespace com { namespace sun { namespace star {
+ namespace awt
+ {
+ struct Rectangle;
+ }
+ namespace frame
+ {
+ class XModel;
+ }
+ namespace chart
+ {
+ class XAxis;
+ }
+ namespace chart2
+ {
+ struct ScaleData;
+ class XChartDocument;
+ class XDiagram;
+ class XCoordinateSystem;
+ class XChartType;
+ class XDataSeries;
+ class XAxis;
+ class XTitle;
+ class XFormattedString;
+ class XRegressionCurve;
+ namespace data
+ {
+ class XDataSequence;
+ class XLabeledDataSequence;
+ }
+ }
+} } }
+
+// Common =====================================================================
+
+struct XclExpChRootData;
+class XclExpChChart;
+
+/** Base class for complex chart classes, provides access to other components
+ of the chart.
+
+ Keeps also track of future record levels and writes the needed future
+ records on demand.
+ */
+class XclExpChRoot : public XclExpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData );
+ virtual ~XclExpChRoot();
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclExpChRoot& GetChRoot() const { return *this; }
+ /** Returns the API Chart document model. */
+ XChartDocRef GetChartDocument() const;
+ /** Returns a reference to the parent chart data object. */
+ XclExpChChart& GetChartData() const;
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for the passed service name. */
+ const XclChTypeInfo& GetChartTypeInfo( const ::rtl::OUString& rServiceName ) const;
+
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+ /** Starts the API chart document conversion. Must be called once before all API conversion. */
+ void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
+ /** Finishes the API chart document conversion. Must be called once after all API conversion. */
+ void FinishConversion() const;
+
+ /** Returns true, if the passed color equals to the specified system color. */
+ bool IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const;
+ /** Sets a system color and the respective color identifier. */
+ void SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const;
+
+ /** Converts the passed horizontal coordinate from 1/100 mm to Excel chart units. */
+ sal_Int32 CalcChartXFromHmm( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from 1/100 mm to Excel chart units. */
+ sal_Int32 CalcChartYFromHmm( sal_Int32 nPosY ) const;
+ /** Converts the passed rectangle from 1/100 mm to Excel chart units. */
+ XclChRectangle CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const;
+
+ /** Reads all line properties from the passed property set. */
+ void ConvertLineFormat(
+ XclChLineFormat& rLineFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads solid area properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool ConvertAreaFormat(
+ XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads gradient or bitmap area properties from the passed property set. */
+ void ConvertEscherFormat(
+ XclChEscherFormat& rEscherFmt,
+ XclChPicFormat& rPicFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode ) const;
+ /** Reads font properties from the passed property set. */
+ sal_uInt16 ConvertFont(
+ const ScfPropertySet& rPropSet,
+ sal_Int16 nScript ) const;
+
+ /** Reads the pie rotation property and returns the converted angle. */
+ static sal_uInt16 ConvertPieRotation( const ScfPropertySet& rPropSet );
+
+protected:
+ /** Called from XclExpChGroupBase::Save, registers a new future record level. */
+ void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
+ /** Called from XclExpChFutureRecordBase::Save, Initializes the current future record level. */
+ void InitializeFutureRecBlock( XclExpStream& rStrm );
+ /** Called from XclExpChGroupBase::Save, finalizes the current future record level. */
+ void FinalizeFutureRecBlock( XclExpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpChRootData > XclExpChRootDataRef;
+ XclExpChRootDataRef mxChData; /// Reference to the root data object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart record groups. Provides helper functions to write sub records.
+
+ A chart record group consists of a header record, followed by a CHBEGIN
+ record, followed by group sub records, and finished with a CHEND record.
+ */
+class XclExpChGroupBase : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChGroupBase(
+ const XclExpChRoot& rRoot, sal_uInt16 nFrType,
+ sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+ virtual ~XclExpChGroupBase();
+
+ /** Saves the header record. Calls WriteSubRecords() to let derived classes write sub records. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Derived classes return whether there are any records embedded in this group. */
+ virtual bool HasSubRecords() const;
+ /** Derived classes implement writing any records embedded in this group. */
+ virtual void WriteSubRecords( XclExpStream& rStrm ) = 0;
+
+protected:
+ /** Sets context information for future record blocks. */
+ void SetFutureRecordContext( sal_uInt16 nFrContext,
+ sal_uInt16 nFrValue1 = 0, sal_uInt16 nFrValue2 = 0 );
+
+private:
+ XclChFrBlock maFrBlock; /// Future records block settings.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart future records. On saving, the record writes missing
+ CHFRBLOCKBEGIN records automatically.
+ */
+class XclExpChFutureRecordBase : public XclExpFutureRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
+ XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+
+ /** Writes missing CHFRBLOCKBEGIN records and this record. */
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// Frame formatting ===========================================================
+
+class XclExpChFramePos : public XclExpRecord
+{
+public:
+ explicit XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode );
+
+ /** Returns read/write access to the frame position data. */
+ inline XclChFramePos& GetFramePosData() { return maData; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFramePos maData; /// Position of the frame.
+};
+
+typedef boost::shared_ptr< XclExpChFramePos > XclExpChFramePosRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChLineFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChLineFormat( const XclExpChRoot& rRoot );
+
+ /** Converts line formatting properties from the passed property set. */
+ void Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets or clears the automatic flag. */
+ inline void SetAuto( bool bAuto ) { ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto ); }
+ /** Sets flag to show or hide an axis. */
+ inline void SetShowAxis( bool bShowAxis )
+ { ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS, bShowAxis ); }
+ /** Sets the line format to the specified default type. */
+ void SetDefault( XclChFrameType eDefFrameType );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO ); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return maData.mnPattern != EXC_CHLINEFORMAT_NONE; }
+ /** Returns true, if the line contains default formatting according to the passed frame type. */
+ bool IsDefault( XclChFrameType eDefFrameType ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLineFormat maData; /// Contents of the CHLINEFORMAT record.
+ sal_uInt32 mnColorId; /// Line color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChLineFormat > XclExpChLineFormatRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChAreaFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChAreaFormat( const XclExpChRoot& rRoot );
+
+ /** Converts area formatting properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets or clears the automatic flag. */
+ inline void SetAuto( bool bAuto ) { ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bAuto ); }
+ /** Sets the area format to the specified default type. */
+ void SetDefault( XclChFrameType eDefFrameType );
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO ); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return maData.mnPattern != EXC_PATT_NONE; }
+ /** Returns true, if the area contains default formatting according to the passed frame type. */
+ bool IsDefault( XclChFrameType eDefFrameType ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChAreaFormat maData; /// Contents of the CHAREAFORMAT record.
+ sal_uInt32 mnPattColorId; /// Pattern color identifier.
+ sal_uInt32 mnBackColorId; /// Pattern background color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChAreaFormat > XclExpChAreaFormatRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChEscherFormat : public XclExpChGroupBase
+{
+public:
+ explicit XclExpChEscherFormat( const XclExpChRoot& rRoot );
+
+ /** Converts complex area formatting from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+
+ /** Returns true, if the object contains valid formatting data. */
+ bool IsValid() const;
+
+ /** Writes the CHESCHERFORMAT record group to the stream, if complex formatting is extant. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Returns true, if this record group contains a CHPICFORMAT record. */
+ virtual bool HasSubRecords() const;
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Inserts a color from the contained Escher property set into the color palette. */
+ sal_uInt32 RegisterColor( sal_uInt16 nPropId );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChEscherFormat maData; /// Fill properties for complex areas (CHESCHERFORMAT record).
+ XclChPicFormat maPicFmt; /// Image options, e.g. stretched, stacked (CHPICFORMAT record).
+ sal_uInt32 mnColor1Id; /// First fill color identifier.
+ sal_uInt32 mnColor2Id; /// Second fill color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChEscherFormat > XclExpChEscherFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for record groups containing frame formatting.
+
+ Frame formatting can be part of several record groups, e.g. CHFRAME,
+ CHDATAFORMAT, CHDROPBAR. It consists of CHLINEFORMAT, CHAREAFORMAT, and
+ CHESCHERFORMAT group.
+ */
+class XclExpChFrameBase
+{
+public:
+ explicit XclExpChFrameBase();
+ virtual ~XclExpChFrameBase();
+
+protected:
+ /** Converts frame formatting properties from the passed property set. */
+ void ConvertFrameBase( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+ /** Sets the frame formatting to the specified default type. */
+ void SetDefaultFrameBase( const XclExpChRoot& rRoot,
+ XclChFrameType eDefFrameType, bool bIsFrame );
+
+ /** Returns true, if the frame contains default formatting (as if the frame is missing). */
+ bool IsDefaultFrameBase( XclChFrameType eDefFrameType ) const;
+
+ /** Writes all contained frame records to the passed stream. */
+ void WriteFrameRecords( XclExpStream& rStrm );
+
+private:
+ XclExpChLineFormatRef mxLineFmt; /// Line format (CHLINEFORMAT record).
+ XclExpChAreaFormatRef mxAreaFmt; /// Area format (CHAREAFORMAT record).
+ XclExpChEscherFormatRef mxEscherFmt; /// Complex area format (CHESCHERFORMAT record).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHFRAME record group containing object frame properties.
+
+ The CHFRAME group consists of: CHFRAME, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclExpChFrame : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType );
+
+ /** Converts frame formatting properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+ /** Sets the specified automatic flags. */
+ void SetAutoFlags( bool bAutoPos, bool bAutoSize );
+
+ /** Returns true, if the frame object contains default formats. */
+ bool IsDefault() const;
+ /** Returns true, if the frame object can be deleted because it contains default formats. */
+ bool IsDeleteable() const;
+
+ /** Writes the entire record group. */
+ virtual void Save( XclExpStream& rStrm );
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFrame maData; /// Contents of the CHFRAME record.
+ XclChObjectType meObjType; /// Type of the represented object.
+};
+
+typedef boost::shared_ptr< XclExpChFrame > XclExpChFrameRef;
+
+// Source links ===============================================================
+
+class XclExpChSourceLink : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > XDataSequenceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > XFormattedStringRef;
+ typedef ::com::sun::star::uno::Sequence< XFormattedStringRef > XFormattedStringSeq;
+
+public:
+ explicit XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType );
+
+ /** Converts the passed source link, returns the number of linked values. */
+ sal_uInt16 ConvertDataSequence( XDataSequenceRef xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount = 0 );
+ /** Converts the passed sequence of formatted string objects, returns leading font index. */
+ sal_uInt16 ConvertStringSequence( const XFormattedStringSeq& rStringSeq );
+ /** Converts the number format from the passed property set. */
+ void ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent );
+
+ void AppendString( const String& rStr );
+
+ /** Returns true, if this source link contains explicit string data. */
+ inline bool HasString() const { return mxString && !mxString->IsEmpty(); }
+
+ /** Writes the CHSOURCELINK record and optionally a CHSTRING record with explicit string data. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSourceLink maData; /// Contents of the CHSOURCELINK record.
+ XclTokenArrayRef mxLinkFmla; /// Formula with link to source data.
+ XclExpStringRef mxString; /// Text data (CHSTRING record).
+};
+
+typedef boost::shared_ptr< XclExpChSourceLink > XclExpChSourceLinkRef;
+
+// Text =======================================================================
+
+/** The CHFONT record containing a font index for text objects. */
+class XclExpChFont : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChFont( sal_uInt16 nFontIdx );
+};
+
+typedef boost::shared_ptr< XclExpChFont > XclExpChFontRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHOBJECTLINK record linking a text object to a specific chart object. */
+class XclExpChObjectLink : public XclExpRecord
+{
+public:
+ explicit XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChObjectLink maData; /// Contents of the CHOBJECTLINK record.
+};
+
+typedef boost::shared_ptr< XclExpChObjectLink > XclExpChObjectLinkRef;
+
+// ----------------------------------------------------------------------------
+
+/** Additional data label settings in the future record CHFRLABELPROPS. */
+class XclExpChFrLabelProps : public XclExpChFutureRecordBase
+{
+public:
+ explicit XclExpChFrLabelProps( const XclExpChRoot& rRoot );
+
+ /** Converts separator and the passed data label flags. */
+ void Convert(
+ const ScfPropertySet& rPropSet, bool bShowSeries,
+ bool bShowCateg, bool bShowValue,
+ bool bShowPercent, bool bShowBubble );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChFrLabelProps maData; /// Contents of the CHFRLABELPROPS record.
+};
+
+typedef boost::shared_ptr< XclExpChFrLabelProps > XclExpChFrLabelPropsRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for objects with font settings. Provides font conversion helper functions. */
+class XclExpChFontBase
+{
+public:
+ virtual ~XclExpChFontBase();
+
+ /** Derived classes set font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId ) = 0;
+ /** Derived classes set text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation ) = 0;
+
+ /** Creates a CHFONT record from the passed font index, calls virtual function SetFont(). */
+ void ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx );
+ /** Creates a CHFONT record from the passed font index, calls virtual function SetFont(). */
+ void ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet );
+ /** Converts rotation settings, calls virtual function SetRotation(). */
+ void ConvertRotationBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTEXT record group containing text object properties.
+
+ The CHTEXT group consists of: CHTEXT, CHBEGIN, CHFRAMEPOS, CHFONT,
+ CHFORMATRUNS, CHSOURCELINK, CHSTRING, CHFRAME group, CHOBJECTLINK, and CHEND.
+ */
+class XclExpChText : public XclExpChGroupBase, public XclExpChFontBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > XTitleRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChText( const XclExpChRoot& rRoot );
+
+ /** Sets font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation );
+
+ /** Converts all text settings of the passed title text object. */
+ void ConvertTitle( XTitleRef xTitle, sal_uInt16 nTarget, const String* pSubTitle = NULL );
+ /** Converts all text settings of the passed legend. */
+ void ConvertLegend( const ScfPropertySet& rPropSet );
+ /** Converts all settings of the passed data point caption text object. */
+ bool ConvertDataLabel( const ScfPropertySet& rPropSet,
+ const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos );
+ /** Converts all settings of the passed trend line equation box. */
+ void ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos );
+
+ /** Returns true, if the string object does not contain any text data. */
+ inline bool HasString() const { return mxSrcLink && mxSrcLink->HasString(); }
+ /** Returns the flags needed for the CHATTACHEDLABEL record. */
+ sal_uInt16 GetAttLabelFlags() const;
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChText maData; /// Contents of the CHTEXT record.
+ XclExpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
+ XclExpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
+ XclExpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
+ XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclExpChObjectLinkRef mxObjLink; /// Link target for this text object.
+ XclExpChFrLabelPropsRef mxLabelProps; /// Extended data label properties (CHFRLABELPROPS record).
+ sal_uInt32 mnTextColorId; /// Text color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChText > XclExpChTextRef;
+
+// Data series ================================================================
+
+/** The CHMARKERFORMAT record containing data point marker formatting data. */
+class XclExpChMarkerFormat : public XclExpRecord
+{
+public:
+ explicit XclExpChMarkerFormat( const XclExpChRoot& rRoot );
+
+ /** Converts symbol properties from the passed property set. */
+ void Convert( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx );
+ /** Converts symbol properties for stock charts from the passed property set. */
+ void ConvertStockSymbol( const XclExpChRoot& rRoot,
+ const ScfPropertySet& rPropSet, bool bCloseSymbol );
+
+ /** Returns true, if markers are enabled. */
+ inline bool HasMarker() const { return maData.mnMarkerType != EXC_CHMARKERFORMAT_NOSYMBOL; }
+ /** Returns true, if border line of markers is visible. */
+ inline bool HasLineColor() const { return !::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_NOLINE ); }
+ /** Returns true, if fill area of markers is visible. */
+ inline bool HasFillColor() const { return !::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_NOFILL ); }
+
+private:
+ /** Registers marker colors in palette and stores color identifiers. */
+ void RegisterColors( const XclExpChRoot& rRoot );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChMarkerFormat maData; /// Contents of the CHMARKERFORMAT record.
+ sal_uInt32 mnLineColorId; /// Border line color identifier.
+ sal_uInt32 mnFillColorId; /// Fill color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChMarkerFormat > XclExpChMarkerFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHPIEFORMAT record containing data point formatting data for pie segments. */
+class XclExpChPieFormat : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChPieFormat();
+
+ /** Sets pie segment properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+};
+
+typedef boost::shared_ptr< XclExpChPieFormat > XclExpChPieFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CH3DDATAFORMAT record containing the bar type in 3D bar charts. */
+class XclExpCh3dDataFormat : public XclExpRecord
+{
+public:
+ explicit XclExpCh3dDataFormat();
+
+ /** Sets 3d bar properties from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclCh3dDataFormat maData; /// Contents of the CH3DDATAFORMAT record.
+};
+
+typedef boost::shared_ptr< XclExpCh3dDataFormat > XclExpCh3dDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHATTACHEDLABEL record that contains the type of a data point label. */
+class XclExpChAttachedLabel : public XclExpUInt16Record
+{
+public:
+ explicit XclExpChAttachedLabel( sal_uInt16 nFlags );
+};
+
+typedef boost::shared_ptr< XclExpChAttachedLabel > XclExpChAttLabelRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDATAFORMAT record group containing data point properties.
+
+ The CHDATAFORMAT group consists of: CHDATAFORMAT, CHBEGIN, CHFRAME group,
+ CHMARKERFORMAT, CHPIEFORMAT, CH3DDATAFORMAT, CHSERIESFORMAT,
+ CHATTACHEDLABEL, CHEND.
+ */
+class XclExpChDataFormat : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChDataFormat( const XclExpChRoot& rRoot,
+ const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx );
+
+ /** Converts the passed data series or data point formatting. */
+ void ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo );
+ /** Sets default formatting for a series in a stock chart. */
+ void ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol );
+ /** Converts line formatting for the specified object (e.g. trend lines, error bars). */
+ void ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType );
+
+ /** Returns true, if this objects describes the formatting of an entire series. */
+ inline bool IsSeriesFormat() const { return maData.maPointPos.mnPointIdx == EXC_CHDATAFORMAT_ALLPOINTS; }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChDataFormat maData; /// Contents of the CHDATAFORMAT record.
+ XclExpChMarkerFormatRef mxMarkerFmt; /// Data point marker (CHMARKERFORMAT record).
+ XclExpChPieFormatRef mxPieFmt; /// Pie segment format (CHPIEFORMAT record).
+ XclExpRecordRef mxSeriesFmt; /// Series properties (CHSERIESFORMAT record).
+ XclExpCh3dDataFormatRef mx3dDataFmt; /// 3D bar format (CH3DDATAFORMAT record).
+ XclExpChAttLabelRef mxAttLabel; /// Data point label type (CHATTACHEDLABEL record).
+};
+
+typedef boost::shared_ptr< XclExpChDataFormat > XclExpChDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERTRENDLINE record containing settings for a trend line. */
+class XclExpChSerTrendLine : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChSerTrendLine( const XclExpChRoot& rRoot );
+
+ /** Converts the passed trend line, returns true if trend line type is supported. */
+ bool Convert( XRegressionCurveRef xRegCurve, sal_uInt16 nSeriesIdx );
+
+ /** Returns formatting information of the trend line, created in Convert(). */
+ inline XclExpChDataFormatRef GetDataFormat() const { return mxDataFmt; }
+ /** Returns formatting of the equation text box, created in Convert(). */
+ inline XclExpChTextRef GetDataLabel() const { return mxLabel; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSerTrendLine maData; /// Contents of the CHSERTRENDLINE record.
+ XclExpChDataFormatRef mxDataFmt; /// Formatting settings of the trend line.
+ XclExpChTextRef mxLabel; /// Formatting of the equation text box.
+};
+
+typedef boost::shared_ptr< XclExpChSerTrendLine > XclExpChSerTrendLineRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERERRORBAR record containing settings for error bars. */
+class XclExpChSerErrorBar : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType );
+
+ /** Converts the passed error bar settings, returns true if error bar type is supported. */
+ bool Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChSerErrorBar maData; /// Contents of the CHSERERRORBAR record.
+};
+
+typedef boost::shared_ptr< XclExpChSerErrorBar > XclExpChSerErrorBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERIES record group describing a data series in a chart.
+
+ The CHSERIES group consists of: CHSERIES, CHBEGIN, CHSOURCELINK groups,
+ CHDATAFORMAT groups, CHSERGROUP, CHSERPARENT, CHSERERRORBAR,
+ CHSERTRENDLINE, CHEND.
+ */
+class XclExpChSeries : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx );
+
+ /** Converts the passed data series (source links and formatting). */
+ bool ConvertDataSeries(
+ XDiagramRef xDiagram, XDataSeriesRef xDataSeries,
+ const XclChExtTypeInfo& rTypeInfo,
+ sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx );
+ /** Converts the passed data series for stock charts. */
+ bool ConvertStockSeries(
+ XDataSeriesRef xDataSeries,
+ const ::rtl::OUString& rValueRole,
+ sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol );
+ /** Converts the passed error bar settings (called at trend line child series). */
+ bool ConvertTrendLine( const XclExpChSeries& rParent, XRegressionCurveRef xRegCurve );
+ /** Converts the passed error bar settings (called at error bar child series). */
+ bool ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId );
+ /** Converts and inserts category ranges for all inserted series. */
+ void ConvertCategSequence( XLabeledDataSeqRef xCategSeq );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Initializes members of this series to represent a child of the passed series. */
+ void InitFromParent( const XclExpChSeries& rParent );
+ /** Tries to create trend line series objects (called at parent series). */
+ void CreateTrendLines( XDataSeriesRef xDataSeries );
+ /** Tries to create positive and negative error bar series objects (called at parent series). */
+ void CreateErrorBars( const ScfPropertySet& rPropSet,
+ const ::rtl::OUString& rBarPropName,
+ sal_uInt8 nPosBarId, sal_uInt8 nNegBarId );
+ /** Tries to create an error bar series object (called at parent series). */
+ void CreateErrorBar( const ScfPropertySet& rPropSet,
+ const ::rtl::OUString& rShowPropName, sal_uInt8 nBarId );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChDataFormat > XclExpChDataFormatList;
+
+private:
+ XclChSeries maData; /// Contents of the CHSERIES record.
+ XclExpChSourceLinkRef mxTitleLink; /// Link data for series title.
+ XclExpChSourceLinkRef mxValueLink; /// Link data for series values.
+ XclExpChSourceLinkRef mxCategLink; /// Link data for series category names.
+ XclExpChSourceLinkRef mxBubbleLink; /// Link data for series bubble sizes.
+ XclExpChDataFormatRef mxSeriesFmt; /// CHDATAFORMAT group for series format.
+ XclExpChDataFormatList maPointFmts; /// CHDATAFORMAT groups for data point formats.
+ XclExpChSerTrendLineRef mxTrendLine; /// Trend line settings (CHSERTRENDLINE record).
+ XclExpChSerErrorBarRef mxErrorBar; /// Error bar settings (CHSERERRORBAR record).
+ sal_uInt16 mnGroupIdx; /// Chart type group (CHTYPEGROUP group) this series is assigned to.
+ sal_uInt16 mnSeriesIdx; /// 0-based series index.
+ sal_uInt16 mnParentIdx; /// 0-based index of parent series (trend lines and error bars).
+};
+
+typedef boost::shared_ptr< XclExpChSeries > XclExpChSeriesRef;
+
+// Chart type groups ==========================================================
+
+/** Represents the chart type record for all supported chart types. */
+class XclExpChType : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+
+public:
+ explicit XclExpChType( const XclExpChRoot& rRoot );
+
+ /** Converts the passed chart type and the contained data series. */
+ void Convert( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels );
+ /** Sets stacking mode (standard or percent) for the series in this chart type group. */
+ void SetStacked( bool bPercent );
+
+ /** Returns true, if this is object represents a valid chart type. */
+ inline bool IsValidType() const { return maTypeInfo.meTypeId != EXC_CHTYPEID_UNKNOWN; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChType maData; /// Contents of the chart type record.
+ XclChTypeInfo maTypeInfo; /// Chart type info for the contained type.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHCHART3D record that contains 3D view settings. */
+class XclExpChChart3d : public XclExpRecord
+{
+public:
+ explicit XclExpChChart3d();
+
+ /** Converts 3d settings for the passed chart type. */
+ void Convert( const ScfPropertySet& rPropSet, bool b3dWallChart );
+ /** Sets flag that the data points are clustered on the X axis. */
+ inline void SetClustered() { ::set_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+
+ /** Returns true, if the data points are clustered on the X axis. */
+ inline bool IsClustered() const { return ::get_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChChart3d maData; /// Contents of the CHCHART3D record.
+};
+
+typedef boost::shared_ptr< XclExpChChart3d > XclExpChChart3dRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHLEGEND record group describing the chart legend.
+
+ The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
+ group, CHTEXT group, CHEND.
+ */
+class XclExpChLegend : public XclExpChGroupBase
+{
+public:
+ explicit XclExpChLegend( const XclExpChRoot& rRoot );
+
+ /** Converts all legend settings from the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLegend maData; /// Contents of the CHLEGEND record.
+ XclExpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
+ XclExpChTextRef mxText; /// Legend text format (CHTEXT group).
+ XclExpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
+};
+
+typedef boost::shared_ptr< XclExpChLegend > XclExpChLegendRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDROPBAR record group describing pos/neg bars in line charts.
+
+ The CHDROPBAR group consists of: CHDROPBAR, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclExpChDropBar : public XclExpChGroupBase, public XclExpChFrameBase
+{
+public:
+ explicit XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType );
+
+ /** Converts and writes the contained frame data to the passed property set. */
+ void Convert( const ScfPropertySet& rPropSet );
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChObjectType meObjType; /// Type of the dropbar.
+ sal_uInt16 mnBarDist; /// Distance between bars (CHDROPBAR record).
+};
+
+typedef boost::shared_ptr< XclExpChDropBar > XclExpChDropBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTYPEGROUP record group describing a group of series.
+
+ The CHTYPEGROUP group consists of: CHTYPEGROUP, CHBEGIN, a chart type
+ record (e.g. CHBAR, CHLINE, CHAREA, CHPIE, ...), CHCHART3D, CHLEGEND group,
+ CHDROPBAR groups, CHCHARTLINE groups (CHCHARTLINE with CHLINEFORMAT),
+ CHDATAFORMAT group, CHEND.
+ */
+class XclExpChTypeGroup : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+
+public:
+ explicit XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx );
+
+ /** Converts the passed chart type to Excel type settings. */
+ void ConvertType( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels );
+ /** Converts and inserts all series from the passed chart type. */
+ void ConvertSeries( XDiagramRef xDiagram, XChartTypeRef xChartType,
+ sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectorLines );
+ /** Converts and inserts category ranges for all inserted series. */
+ void ConvertCategSequence( XLabeledDataSeqRef xCategSeq );
+ /** Creates a legend object and converts all legend settings. */
+ void ConvertLegend( const ScfPropertySet& rPropSet );
+
+ /** Returns true, if this chart type group contains at least one valid series. */
+ inline bool IsValidGroup() const { return !maSeries.IsEmpty() && maType.IsValidType(); }
+ /** Returns the index of this chart type group format. */
+ inline sal_uInt16 GetGroupIdx() const { return maData.mnGroupIdx; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChExtTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool Is3dChart() const { return maTypeInfo.mb3dChart; }
+ /** Returns true, if chart type supports wall and floor format. */
+ inline bool Is3dWallChart() const { return Is3dChart() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE); }
+ /** Returns true, if the series in this chart type group are ordered on the Z axis. */
+ inline bool Is3dDeepChart() const { return Is3dWallChart() && mxChart3d && !mxChart3d->IsClustered(); }
+ /** Returns true, if this chart type can be combined with other types. */
+ inline bool IsCombinable2d() const { return !Is3dChart() && maTypeInfo.mbCombinable2d; }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Returns an unused format index to be used for the next created series. */
+ sal_uInt16 GetFreeFormatIdx() const;
+ /** Creates all data series of any chart type except stock charts. */
+ void CreateDataSeries( XDiagramRef xDiagram,
+ XDataSeriesRef xDataSeries );
+ /** Creates all data series of a stock chart. */
+ void CreateAllStockSeries( XChartTypeRef xChartType,
+ XDataSeriesRef xDataSeries );
+ /** Creates a single data series of a stock chart. */
+ bool CreateStockSeries( XDataSeriesRef xDataSeries,
+ const ::rtl::OUString& rValueRole, bool bCloseSymbol );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChSeries > XclExpChSeriesList;
+ typedef ::boost::ptr_map<sal_uInt16, XclExpChLineFormat> XclExpChLineFormatMap;
+
+ XclChTypeGroup maData; /// Contents of the CHTYPEGROUP record.
+ XclExpChType maType; /// Chart type (e.g. CHBAR, CHLINE, ...).
+ XclChExtTypeInfo maTypeInfo; /// Extended chart type info.
+ XclExpChSeriesList maSeries; /// List of series data (CHSERIES groups).
+ XclExpChChart3dRef mxChart3d; /// 3D settings (CHCHART3D record).
+ XclExpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+ XclExpChDropBarRef mxUpBar; /// White dropbars (CHDROPBAR group).
+ XclExpChDropBarRef mxDownBar; /// Black dropbars (CHDROPBAR group).
+ XclExpChLineFormatMap maChartLines; /// Global line formats (CHCHARTLINE group).
+};
+
+typedef boost::shared_ptr< XclExpChTypeGroup > XclExpChTypeGroupRef;
+
+// Axes =======================================================================
+
+class XclExpChLabelRange : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChLabelRange( const XclExpChRoot& rRoot );
+
+ /** Converts category axis scaling settings. */
+ void Convert( const ::com::sun::star::chart2::ScaleData& rScaleData,
+ const ScfPropertySet& rChart1Axis, bool bMirrorOrient );
+ /** Converts position settings of a crossing axis at this axis. */
+ void ConvertAxisPosition( const ScfPropertySet& rPropSet );
+ /** Sets flag for tickmark position between categories or on categories. */
+ inline void SetTicksBetweenCateg( bool bTicksBetween )
+ { ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_BETWEEN, bTicksBetween ); }
+
+private:
+ virtual void Save( XclExpStream& rStrm );
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChLabelRange maLabelData; /// Contents of the CHLABELRANGE record.
+ XclChDateRange maDateData; /// Contents of the CHDATERANGE record.
+};
+
+typedef boost::shared_ptr< XclExpChLabelRange > XclExpChLabelRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChValueRange : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChValueRange( const XclExpChRoot& rRoot );
+
+ /** Converts value axis scaling settings. */
+ void Convert( const ::com::sun::star::chart2::ScaleData& rScaleData );
+ /** Converts position settings of a crossing axis at this axis. */
+ void ConvertAxisPosition( const ScfPropertySet& rPropSet );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChValueRange maData; /// Contents of the CHVALUERANGE record.
+};
+
+typedef boost::shared_ptr< XclExpChValueRange > XclExpChValueRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclExpChTick : public XclExpRecord, protected XclExpChRoot
+{
+public:
+ explicit XclExpChTick( const XclExpChRoot& rRoot );
+
+ /** Converts axis tick mark settings. */
+ void Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType );
+ /** Sets font color and color identifier to internal data structures. */
+ void SetFontColor( const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ void SetRotation( sal_uInt16 nRotation );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChTick maData; /// Contents of the CHTICK record.
+ sal_uInt32 mnTextColorId; /// Axis labels text color identifier.
+};
+
+typedef boost::shared_ptr< XclExpChTick > XclExpChTickRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXIS record group describing an entire chart axis.
+
+ The CHAXIS group consists of: CHAXIS, CHBEGIN, CHLABELRANGE, CHEXTRANGE,
+ CHVALUERANGE, CHFORMAT, CHTICK, CHFONT, CHAXISLINE groups (CHAXISLINE with
+ CHLINEFORMAT, CHAREAFORMAT, and CHESCHERFORMAT group), CHEND.
+ */
+class XclExpChAxis : public XclExpChGroupBase, public XclExpChFontBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart::XAxis > XChart1AxisRef;
+
+public:
+ explicit XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType );
+
+ /** Sets font color and color identifier to internal data structures. */
+ virtual void SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId );
+ /** Sets text rotation to internal data structures. */
+ virtual void SetRotation( sal_uInt16 nRotation );
+
+ /** Converts formatting and scaling settings from the passed axis. */
+ void Convert( XAxisRef xAxis, XAxisRef xCrossingAxis,
+ XChart1AxisRef xChart1Axis, const XclChExtTypeInfo& rTypeInfo );
+ /** Converts and writes 3D wall/floor properties from the passed diagram. */
+ void ConvertWall( XDiagramRef xDiagram );
+
+ /** Returns the type of this axis. */
+ inline sal_uInt16 GetAxisType() const { return maData.mnType; }
+ /** Returns the axis dimension index used by the chart API. */
+ inline sal_Int32 GetApiAxisDimension() const { return maData.GetApiAxisDimension(); }
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclChAxis maData; /// Contents of the CHAXIS record.
+ XclExpChLabelRangeRef mxLabelRange; /// Category scaling (CHLABELRANGE record).
+ XclExpChValueRangeRef mxValueRange; /// Value scaling (CHVALUERANGE record).
+ XclExpChTickRef mxTick; /// Axis ticks (CHTICK record).
+ XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclExpChLineFormatRef mxAxisLine; /// Axis line format (CHLINEFORMAT record).
+ XclExpChLineFormatRef mxMajorGrid; /// Major grid line format (CHLINEFORMAT record).
+ XclExpChLineFormatRef mxMinorGrid; /// Minor grid line format (CHLINEFORMAT record).
+ XclExpChFrameRef mxWallFrame; /// Wall/floor format (sub records of CHFRAME group).
+ sal_uInt16 mnNumFmtIdx; /// Index into number format buffer (CHFORMAT record).
+};
+
+typedef boost::shared_ptr< XclExpChAxis > XclExpChAxisRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXESSET record group describing an axes set (X/Y/Z axes).
+
+ The CHAXESSET group consists of: CHAXESSET, CHBEGIN, CHFRAMEPOS, CHAXIS
+ groups, CHTEXT groups, CHPLOTFRAME group (CHPLOTFRAME with CHFRAME group),
+ CHTYPEGROUP group, CHEND.
+ */
+class XclExpChAxesSet : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+
+public:
+ explicit XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId );
+
+ /** Converts the passed diagram to chart record data.
+ @return First unused chart type group index. */
+ sal_uInt16 Convert( XDiagramRef xDiagram, sal_uInt16 nFirstGroupIdx );
+
+ /** Returns true, if this axes set exists (returns false if this is a dummy object). */
+ inline bool IsValidAxesSet() const { return !maTypeGroups.IsEmpty(); }
+ /** Returns the index of the axes set (primary/secondary). */
+ inline sal_uInt16 GetAxesSetId() const { return maData.mnAxesSetId; }
+ /** Returns the axes set index used by the chart API. */
+ inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }
+ /** Returns true, if the chart is three-dimensional. */
+ bool Is3dChart() const;
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ /** Returns first inserted chart type group. */
+ XclExpChTypeGroupRef GetFirstTypeGroup() const;
+ /** Returns last inserted chart type group. */
+ XclExpChTypeGroupRef GetLastTypeGroup() const;
+
+ /** Converts a complete axis object including axis title. */
+ void ConvertAxis( XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
+ XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
+ XCoordSystemRef xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
+ sal_Int32 nCrossingAxisDim );
+
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChTypeGroup > XclExpChTypeGroupList;
+
+ XclChAxesSet maData; /// Contents of the CHAXESSET record.
+ XclExpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
+ XclExpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
+ XclExpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
+ XclExpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
+ XclExpChTextRef mxXAxisTitle; /// The X axis title (CHTEXT group).
+ XclExpChTextRef mxYAxisTitle; /// The Y axis title (CHTEXT group).
+ XclExpChTextRef mxZAxisTitle; /// The Z axis title (CHTEXT group).
+ XclExpChFrameRef mxPlotFrame; /// Plot area (CHPLOTFRAME group).
+ XclExpChTypeGroupList maTypeGroups; /// Chart type groups (CHTYPEGROUP group).
+};
+
+typedef boost::shared_ptr< XclExpChAxesSet > XclExpChAxesSetRef;
+
+// The chart object ===========================================================
+
+/** Represents the CHCHART record group describing the chart contents.
+
+ The CHCHART group consists of: CHCHART, CHBEGIN, SCL, CHPLOTGROWTH, CHFRAME
+ group, CHSERIES groups, CHPROPERTIES, CHDEFAULTTEXT groups (CHDEFAULTTEXT
+ with CHTEXT groups), CHUSEDAXESSETS, CHAXESSET groups, CHTEXT groups, CHEND.
+ */
+class XclExpChChart : public XclExpChGroupBase
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclExpChChart( const XclExpRoot& rRoot,
+ XChartDocRef xChartDoc, const Rectangle& rChartRect );
+
+ /** Creates, registers and returns a new data series object. */
+ XclExpChSeriesRef CreateSeries();
+ /** Removes the last created data series object from the series list. */
+ void RemoveLastSeries();
+ /** Stores a CHTEXT group that describes a data point label. */
+ void SetDataLabel( XclExpChTextRef xText );
+ /** Sets the plot area position and size to manual mode. */
+ void SetManualPlotArea();
+
+ /** Writes all embedded records. */
+ virtual void WriteSubRecords( XclExpStream& rStrm );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpChSeries > XclExpChSeriesList;
+ typedef XclExpRecordList< XclExpChText > XclExpChTextList;
+
+ XclChRectangle maRect; /// Position of the chart on the sheet (CHCHART record).
+ XclExpChSeriesList maSeries; /// List of series data (CHSERIES groups).
+ XclExpChFrameRef mxFrame; /// Chart frame format (CHFRAME group).
+ XclChProperties maProps; /// Chart properties (CHPROPERTIES record).
+ XclExpChAxesSetRef mxPrimAxesSet; /// Primary axes set (CHAXESSET group).
+ XclExpChAxesSetRef mxSecnAxesSet; /// Secondary axes set (CHAXESSET group).
+ XclExpChTextRef mxTitle; /// Chart title (CHTEXT group).
+ XclExpChTextList maLabels; /// Data point labels (CHTEXT groups).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the group of DFF and OBJ records containing all drawing shapes
+ embedded in the chart object.
+ */
+class XclExpChartDrawing : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpChartDrawing(
+ const XclExpRoot& rRoot,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel,
+ const Size& rChartSize );
+ virtual ~XclExpChartDrawing();
+
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ boost::shared_ptr< XclExpObjectManager > mxObjMgr;
+ boost::shared_ptr< XclExpRecordBase > mxObjRecs;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the entire chart substream (all records in BOF/EOF block). */
+class XclExpChart : public XclExpSubStream, protected XclExpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > XModelRef;
+
+public:
+ explicit XclExpChart( const XclExpRoot& rRoot,
+ XModelRef xModel, const Rectangle& rChartRect );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xecontent.hxx b/sc/source/filter/inc/xecontent.hxx
new file mode 100644
index 000000000000..1e1b9f39b4a1
--- /dev/null
+++ b/sc/source/filter/inc/xecontent.hxx
@@ -0,0 +1,356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XECONTENT_HXX
+#define SC_XECONTENT_HXX
+
+#include "rangelst.hxx"
+#include "xlcontent.hxx"
+#include "xladdress.hxx"
+#include "xerecord.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+#include "xeformula.hxx"
+
+/* ============================================================================
+Classes to export the big Excel document contents (related to several cells or
+globals for the sheet or document).
+- Shared string table
+- Merged cells
+- Hyperlinks
+- Label ranges
+- Conditional formatting
+- Data validation
+- Web Queries
+============================================================================ */
+
+// Shared string table ========================================================
+
+class XclExpSstImpl;
+
+/** Provides export of the SST (shared string table) record.
+ @descr Contains all strings in the document and writes the SST. */
+class XclExpSst : public XclExpRecordBase
+{
+public:
+ explicit XclExpSst();
+ virtual ~XclExpSst();
+
+ /** Inserts a new string into the table.
+ @return The index of the string in the SST, used in other records. */
+ sal_uInt32 Insert( XclExpStringRef xString );
+
+ /** Writes the complete SST and EXTSST records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< XclExpSstImpl > XclExpSstImplPtr;
+ XclExpSstImplPtr mxImpl;
+};
+
+// Merged cells ===============================================================
+
+/** Represents a MERGEDCELLS record containing all merged cell ranges in a sheet. */
+class XclExpMergedcells : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpMergedcells( const XclExpRoot& rRoot );
+
+ /** Appends a new range to the list of merged cell ranges. */
+ void AppendRange( const ScRange& rRange, sal_uInt32 nBaseXFId );
+ /** Returns the XF identifier of the top-left cell in a merged range. */
+ sal_uInt32 GetBaseXFId( const ScAddress& rPos ) const;
+
+ /** Writes the record, if it contains at least one merged cell range. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ ScRangeList maMergedRanges; /// All merged cell ranges of the sheet.
+ ScfUInt32Vec maBaseXFIds; /// The XF identifiers of the top-left cells.
+};
+
+// Hyperlinks =================================================================
+
+class SvxURLField;
+class INetURLObject;
+
+/** Provides export of hyperlink data. */
+class XclExpHyperlink : public XclExpRecord
+{
+public:
+ /** Constructs the HLINK record from an URL text field. */
+ explicit XclExpHyperlink( const XclExpRoot& rRoot,
+ const SvxURLField& rUrlField, const ScAddress& rScPos );
+ virtual ~XclExpHyperlink();
+
+ /** Returns the cell representation text or 0, if not available. */
+ inline const String* GetRepr() const { return mxRepr.get(); }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ virtual void WriteEmbeddedData( XclExpStream& rStrm );
+private:
+ /** Builds file name from the passed file URL. Tries to convert to relative file name.
+ @param rnLevel (out-param) The parent directory level.
+ @param rbRel (out-param) true = path is relative. */
+ String BuildFileName(
+ sal_uInt16& rnLevel, bool& rbRel,
+ const String& rUrl, const XclExpRoot& rRoot ) const;
+
+ /** Writes the body of the HLINK record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< String > StringPtr;
+ typedef ::std::auto_ptr< SvStream > SvStreamPtr;
+
+ ScAddress maScPos; /// Position of the hyperlink.
+ StringPtr mxRepr; /// Cell representation text.
+ SvStreamPtr mxVarData; /// Buffer stream with variable data.
+ sal_uInt32 mnFlags; /// Option flags.
+ XclExpStringRef mxTextMark; /// Location within mxRepr
+ ::rtl::OUString msTarget; /// Target URL
+};
+
+typedef XclExpRecordList< XclExpHyperlink > XclExpHyperlinkList;
+
+// Label ranges ===============================================================
+
+/** Provides export of the row/column label range list of a sheet. */
+class XclExpLabelranges : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Fills the cell range lists with all ranges of the current sheet. */
+ explicit XclExpLabelranges( const XclExpRoot& rRoot );
+
+ /** Writes the LABELRANGES record if it contains at least one range. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Fills the specified range list with all label headers of the current sheet.
+ @param rRanges The cell range list to fill.
+ @param xLabelRangesRef The core range list with all ranges.
+ @param nScTab The current Calc sheet index. */
+ void FillRangeList( ScRangeList& rScRanges,
+ ScRangePairListRef xLabelRangesRef, SCTAB nScTab );
+
+private:
+ ScRangeList maRowRanges; /// Cell range list for row labels.
+ ScRangeList maColRanges; /// Cell range list for column labels.
+};
+
+// Conditional formatting =====================================================
+
+class ScCondFormatEntry;
+class XclExpCFImpl;
+
+/** Represents a CF record that contains one condition of a conditional format. */
+class XclExpCF : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry );
+ virtual ~XclExpCF();
+
+private:
+ /** Writes the body of the CF record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef ::std::auto_ptr< XclExpCFImpl > XclExpCFImplPtr;
+ XclExpCFImplPtr mxImpl;
+};
+
+// ----------------------------------------------------------------------------
+
+class ScConditionalFormat;
+
+/** Represents a CONDFMT record that contains all conditions of a conditional format.
+ @descr Contains the conditions which are stored in CF records. */
+class XclExpCondfmt : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat& rCondFormat );
+ virtual ~XclExpCondfmt();
+
+ /** Returns true, if this conditional format contains at least one cell range and CF record. */
+ bool IsValid() const;
+
+ /** Writes the CONDFMT record with following CF records, if there is valid data. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the CONDFMT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCF > XclExpCFList;
+
+ XclExpCFList maCFList; /// List of CF records.
+ XclRangeList maXclRanges; /// Cell ranges for this conditional format.
+ String msSeqRef; /// OOXML Sequence of References
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all conditional formats of a specific sheet. */
+class XclExpCondFormatBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Constructs CONDFMT and CF records containing the conditional formats of the current sheet. */
+ explicit XclExpCondFormatBuffer( const XclExpRoot& rRoot );
+
+ /** Writes all contained CONDFMT records with their CF records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCondfmt > XclExpCondfmtList;
+ XclExpCondfmtList maCondfmtList; /// List of CONDFMT records.
+};
+
+// Data Validation ============================================================
+
+class ScValidationData;
+
+/** Provides export of the data of a DV record.
+ @descr This record contains the settings for a data validation. In detail
+ this is a pointer to the core validation data and a cell range list with all
+ affected cells. The handle index is used to optimize list search algorithm. */
+class XclExpDV : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpDV( const XclExpRoot& rRoot, sal_uLong nScHandle );
+ virtual ~XclExpDV();
+
+ /** Returns the core handle of the validation data. */
+ inline sal_uLong GetScHandle() const { return mnScHandle; }
+
+ /** Inserts a new cell range into the cell range list. */
+ void InsertCellRange( const ScRange& rPos );
+ /** Converts the Calc range list to the Excel range list.
+ @return false = Resulting range list empty - do not write this record. */
+ bool Finalize();
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the DV record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ ScRangeList maScRanges; /// Calc range list with all affected cells.
+ XclRangeList maXclRanges; /// Excel range list with all affected cells.
+ XclExpString maPromptTitle; /// The prompt title.
+ XclExpString maPromptText; /// The prompt text.
+ XclExpString maErrorTitle; /// The error title.
+ XclExpString maErrorText; /// The error text.
+ XclExpStringRef mxString1; /// String for first condition formula.
+ XclTokenArrayRef mxTokArr1; /// Formula for first condition.
+ ::rtl::OUString msFormula1; /// OOXML Formula for first condition.
+ XclTokenArrayRef mxTokArr2; /// Formula for second condition.
+ ::rtl::OUString msFormula2; /// OOXML Formula for second condition.
+ sal_uInt32 mnFlags; /// Miscellaneous flags.
+ sal_uLong mnScHandle; /// The core handle for quick list search.
+};
+
+// ----------------------------------------------------------------------------
+
+/** This class contains the DV record list following the DVAL record. */
+class XclExpDval : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpDval( const XclExpRoot& rRoot );
+ virtual ~XclExpDval();
+
+ /** Inserts the cell range into the range list of the DV record with the specified handle. */
+ void InsertCellRange( const ScRange& rRange, sal_uLong nScHandle );
+
+ /** Writes the DVAL record and the DV record list. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Searches for or creates a XclExpDV record object with the specified handle. */
+ XclExpDV& SearchOrCreateDv( sal_uLong nScHandle );
+
+ /** Writes the body of the DVAL record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpDV > XclExpDVList;
+ typedef XclExpDVList::RecordRefType XclExpDVRef;
+
+ XclExpDVList maDVList; /// List of DV records
+ XclExpDVRef mxLastFoundDV; /// For search optimization.
+};
+
+// Web Queries ================================================================
+
+/** Contains all records for a web query (linked tables in an HTML document).
+ @descr mode 1 (entire document): mpQryTables==0, mbEntireDoc==true;
+ mode 2 (all tables): mpQryTables==0, mbEntireDoc==false;
+ mode 3 (custom range list): mpQryTables!=0, mbEntireDoc==false. */
+class XclExpWebQuery : public XclExpRecordBase
+{
+public:
+ /** Constructs a web query record container with settings from Calc. */
+ explicit XclExpWebQuery(
+ const String& rRangeName,
+ const String& rUrl,
+ const String& rSource,
+ sal_Int32 nRefrSecs );
+ virtual ~XclExpWebQuery();
+
+ /** Writes all needed records for this web query. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclExpString maDestRange; /// Destination range.
+ XclExpString maUrl; /// Source document URL.
+ XclExpStringRef mxQryTables; /// List of source range names.
+ sal_Int16 mnRefresh; /// Refresh time in minutes.
+ bool mbEntireDoc; /// true = entire document.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all web query records for this document. */
+class XclExpWebQueryBuffer : public XclExpRecordList< XclExpWebQuery >
+{
+public:
+ explicit XclExpWebQueryBuffer( const XclExpRoot& rRoot );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx
new file mode 100644
index 000000000000..34c80c4021ea
--- /dev/null
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -0,0 +1,485 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEESCHER_HXX
+#define SC_XEESCHER_HXX
+
+#include <vcl/graph.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include "xcl97rec.hxx"
+#include "xlescher.hxx"
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include "svx/sdtaitm.hxx"
+#include <boost/shared_ptr.hpp>
+
+
+namespace com { namespace sun { namespace star {
+ namespace script { struct ScriptEventDescriptor; }
+} } }
+
+// DFF client anchor ==========================================================
+
+/** Base class for DFF client anchor atoms used in spreadsheets. */
+class XclExpDffAnchorBase : public EscherExClientAnchor_Base, protected XclExpRoot
+{
+public:
+ /** Constructs a dummy client anchor. */
+ explicit XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 );
+
+ /** Sets the flags according to the passed SdrObject. */
+ void SetFlags( const SdrObject& rSdrObj );
+ /** Sets the anchor position and flags according to the passed SdrObject. */
+ void SetSdrObject( const SdrObject& rSdrObj );
+
+ /** Writes the DFF client anchor structure with the current anchor position. */
+ void WriteDffData( EscherEx& rEscherEx ) const;
+
+ /** Called from SVX DFF converter.
+ @param rRect The object anchor rectangle to be exported (in twips). */
+ virtual void WriteData( EscherEx& rEscherEx, const Rectangle& rRect );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+protected: // for access in derived classes
+ XclObjAnchor maAnchor; /// The client anchor data.
+ sal_uInt16 mnFlags; /// Flags for DFF stream export.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of an object in a Calc sheet. */
+class XclExpDffSheetAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffSheetAnchor( const XclExpRoot& rRoot );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+private:
+ SCTAB mnScTab; /// Calc sheet index.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a shape in an embedded draw page. */
+class XclExpDffEmbeddedAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
+ const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY );
+
+private:
+ virtual void ImplSetFlags( const SdrObject& rSdrObj );
+ virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit );
+
+private:
+ Size maPageSize;
+ sal_Int32 mnScaleX;
+ sal_Int32 mnScaleY;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a note object. */
+class XclExpDffNoteAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of a cell dropdown object. */
+class XclExpDffDropDownAnchor : public XclExpDffAnchorBase
+{
+public:
+ explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos );
+};
+
+// MSODRAWING* records ========================================================
+
+/** Base class for records holding DFF stream fragments. */
+class XclExpMsoDrawingBase : public XclExpRecord
+{
+public:
+ explicit XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+protected:
+ XclEscherEx& mrEscherEx; /// Reference to the DFF converter containing the DFF stream.
+ sal_uInt32 mnFragmentKey; /// The key of the DFF stream fragment to be written by this record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data
+ such as the picture container.
+ */
+class XclExpMsoDrawingGroup : public XclExpMsoDrawingBase
+{
+public:
+ explicit XclExpMsoDrawingGroup( XclEscherEx& rEscherEx );
+};
+
+// ----------------------------------------------------------------------------
+
+/** One or more MSODRAWING records contain the DFF stream data for a drawing
+ shape.
+ */
+class XclExpMsoDrawing : public XclExpMsoDrawingBase
+{
+public:
+ explicit XclExpMsoDrawing( XclEscherEx& rEscherEx );
+};
+
+// ============================================================================
+
+/** Provides export of bitmap data to an IMGDATA record. */
+class XclExpImgData : public XclExpRecordBase
+{
+public:
+ explicit XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId );
+
+ /** Writes the BITMAP record. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ Graphic maGraphic; /// The VCL graphic.
+ sal_uInt16 mnRecId; /// Record identifier for the IMGDATA record.
+};
+
+// ============================================================================
+
+/** Helper class for form controils to manage spreadsheet links . */
+class XclExpControlHelper : protected XclExpRoot
+{
+public:
+ explicit XclExpControlHelper( const XclExpRoot& rRoot );
+ virtual ~XclExpControlHelper();
+
+protected:
+ /** Tries to get spreadsheet cell link and source range link from the passed shape. */
+ void ConvertSheetLinks(
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+
+ /** Returns the Excel token array of the cell link, or 0, if no link present. */
+ inline const XclTokenArray* GetCellLinkTokArr() const { return mxCellLink.get(); }
+ /** Returns the Excel token array of the source range, or 0, if no link present. */
+ inline const XclTokenArray* GetSourceRangeTokArr() const { return mxSrcRange.get(); }
+ /** Returns the number of entries in the source range, or 0, if no source set. */
+ inline sal_uInt16 GetSourceEntryCount() const { return mnEntryCount; }
+
+ /** Writes a formula with special style only valid in OBJ records. */
+ void WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr ) const;
+ /** Writes a formula subrecord with special style only valid in OBJ records. */
+ void WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr ) const;
+
+private:
+ XclTokenArrayRef mxCellLink; /// Formula for linked cell.
+ XclTokenArrayRef mxSrcRange; /// Formula for source data range.
+ sal_uInt16 mnEntryCount; /// Number of entries in source range.
+};
+
+class XclMacroHelper : public XclExpControlHelper
+{
+protected:
+ XclTokenArrayRef mxMacroLink; /// Token array containing a link to an attached macro.
+
+public:
+ explicit XclMacroHelper( const XclExpRoot& rRoot );
+ virtual ~XclMacroHelper();
+ /** Writes an ftMacro subrecord containing a macro link, or nothing, if no macro present. */
+ void WriteMacroSubRec( XclExpStream& rStrm );
+ /** Sets the name of a macro for object of passed type
+ @return true = The passed event descriptor was valid, macro name has been found. */
+ bool SetMacroLink( const ::com::sun::star::script::ScriptEventDescriptor& rEvent, const XclTbxEventType& nEventType );
+
+ /** Sets the name of a macro
+ @return true = The passed macro name has been found. */
+ bool SetMacroLink( const String& rMacro );
+};
+
+class XclExpShapeObj : public XclObjAny, public XclMacroHelper
+{
+public:
+ explicit XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ~XclExpShapeObj();
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+#if EXC_EXP_OCX_CTRL
+
+/** Represents an OBJ record for an OCX form control. */
+class XclExpOcxControlObj : public XclObj, public XclExpControlHelper
+{
+public:
+ explicit XclExpOcxControlObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor,
+ const String& rClassName,
+ sal_uInt32 nStrmStart, sal_uInt32 nStrmSize );
+
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+private:
+ String maClassName; /// Class name of the control.
+ sal_uInt32 mnStrmStart; /// Start position in 'Ctls' stream.
+ sal_uInt32 mnStrmSize; /// Size in 'Ctls' stream.
+};
+
+#else
+
+/** Represents an OBJ record for an TBX form control. */
+class XclExpTbxControlObj : public XclObj, public XclMacroHelper
+{
+public:
+ explicit XclExpTbxControlObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+
+ /** Sets the name of a macro attached to this control.
+ @return true = The passed event descriptor was valid, macro name has been found. */
+ bool SetMacroLink( const ::com::sun::star::script::ScriptEventDescriptor& rEvent );
+
+private:
+ virtual void WriteSubRecs( XclExpStream& rStrm );
+
+ /** Writes a subrecord containing a cell link, or nothing, if no link present. */
+ void WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId );
+ /** Writes the ftSbs sub structure containing scrollbar data. */
+ void WriteSbs( XclExpStream& rStrm );
+
+private:
+ ScfInt16Vec maMultiSel; /// Indexes of all selected entries in a multi selection.
+ XclTbxEventType meEventType; /// Type of supported macro event.
+ sal_Int32 mnHeight; /// Height of the control.
+ sal_uInt16 mnState; /// Checked/unchecked state.
+ sal_Int16 mnLineCount; /// Combobox dropdown line count.
+ sal_Int16 mnSelEntry; /// Selected entry in combobox (1-based).
+ sal_uInt16 mnScrollValue; /// Scrollbar: Current value.
+ sal_uInt16 mnScrollMin; /// Scrollbar: Minimum value.
+ sal_uInt16 mnScrollMax; /// Scrollbar: Maximum value.
+ sal_uInt16 mnScrollStep; /// Scrollbar: Single step.
+ sal_uInt16 mnScrollPage; /// Scrollbar: Page step.
+ bool mbFlatButton; /// False = 3D button style; True = Flat button style.
+ bool mbFlatBorder; /// False = 3D border style; True = Flat border style.
+ bool mbMultiSel; /// true = Multi selection in listbox.
+ bool mbScrollHor; /// Scrollbar: true = horizontal.
+};
+
+#endif
+
+// ----------------------------------------------------------------------------
+
+class XclExpChart;
+
+/** A chart object. This is the drawing object wrapper for the chart data. */
+class XclExpChartObj : public XclObj, protected XclExpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument > XChartDocRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > XShapeRef;
+ explicit XclExpChartObj(
+ XclExpObjectManager& rObjMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape,
+ const Rectangle* pChildAnchor );
+ virtual ~XclExpChartObj();
+
+ /** Writes the OBJ record and the entire chart substream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+ virtual void WriteChartObj( sax_fastparser::FSHelperPtr pDrawing, XclExpXmlStream& rStrm );
+ void WriteShapeTransformation( sax_fastparser::FSHelperPtr pFS, const XShapeRef& rXShape, sal_Bool bFlipH = false, sal_Bool bFlipV = false, sal_Int32 nRotation = 0 );
+
+private:
+ typedef boost::shared_ptr< XclExpChart > XclExpChartRef;
+ XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
+ XShapeRef mxShape;
+ XChartDocRef mxChartDoc;
+};
+
+// ============================================================================
+
+/** Represents a NOTE record containing the relevant data of a cell note.
+
+ NOTE records differ significantly in various BIFF versions. This class
+ encapsulates all needed actions for each supported BIFF version.
+ BIFF5/BIFF7: Stores the note text and generates a single or multiple NOTE
+ records on saving.
+ BIFF8: Creates the Escher object containing the drawing information and the
+ note text.
+ */
+class XclExpNote : public XclExpRecord
+{
+public:
+ /** Constructs a NOTE record from the passed note object and/or the text.
+ @descr The additional text will be separated from the note text with
+ an empty line.
+ @param rScPos The Calc cell address of the note.
+ @param pScNote The Calc note object. May be 0 to create a note from rAddText only.
+ @param rAddText Additional text appended to the note text. */
+ explicit XclExpNote(
+ const XclExpRoot& rRoot,
+ const ScAddress& rScPos,
+ const ScPostIt* pScNote,
+ const String& rAddText );
+
+ /** Writes the NOTE record, if the respective Escher object is present. */
+ virtual void Save( XclExpStream& rStrm );
+
+ void WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm );
+
+ const XclExpString& GetAuthor() const { return maAuthor; }
+private:
+ /** Writes the body of the NOTE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpString maAuthor; /// Name of the author.
+ String maOrigNoteText; /// Original main text of the note.
+ ByteString maNoteText; /// Main text of the note (<=BIFF7).
+ XclExpStringRef mpNoteContents; /// Text and formatting data (OOXML)
+ ScAddress maScPos; /// Calc cell address of the note.
+ sal_uInt16 mnObjId; /// Escher object ID (BIFF8).
+ bool mbVisible; /// true = permanently visible.
+ SdrTextHorzAdjust meTHA; /// text horizontal adjust
+ SdrTextVertAdjust meTVA; /// text vertical adjust
+ bool mbAutoScale; /// Auto scale text
+ bool mbLocked; /// Position & Size locked
+ bool mbAutoFill; /// Auto Fill Style
+ bool mbAutoLine; /// Auto Line Style
+ bool mbColHidden; /// Column containing the comment is hidden
+ bool mbRowHidden; /// Row containing the comment is hidden
+ Rectangle maCommentFrom; /// From and From Offset
+ Rectangle maCommentTo; /// To and To Offsets
+};
+
+// ============================================================================
+
+class XclExpComments : public XclExpRecord
+{
+public:
+ typedef XclExpRecordList< XclExpNote >
+ XclExpNoteList;
+
+ XclExpComments( SCTAB nTab, XclExpNoteList& rNotes );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ SCTAB mnTab;
+ XclExpNoteList& mrNotes;
+};
+
+// object manager =============================================================
+
+class XclExpObjectManager : public XclExpRoot
+{
+public:
+ explicit XclExpObjectManager( const XclExpRoot& rRoot );
+ virtual ~XclExpObjectManager();
+
+ /** Creates a new DFF client anchor object. Caller takes ownership! May be
+ overwritten in derived classes. */
+ virtual XclExpDffAnchorBase* CreateDffAnchor() const;
+
+ /** Creates and returns the MSODRAWINGGROUP record containing global DFF
+ data in the DGGCONTAINER. */
+ boost::shared_ptr< XclExpRecordBase > CreateDrawingGroup();
+
+ /** Initializes the object manager for a new sheet. */
+ void StartSheet();
+
+ /** Processes a drawing page and returns the record block containing all
+ related records (MSODRAWING, OBJ, TXO, charts, etc.). */
+ boost::shared_ptr< XclExpRecordBase > ProcessDrawing( SdrPage* pSdrPage );
+ /** Processes a collection of UNO shapes and returns the record block
+ containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */
+ boost::shared_ptr< XclExpRecordBase > ProcessDrawing( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+
+ /** Finalizes the object manager after conversion of all sheets. */
+ void EndDocument();
+
+ inline XclEscherEx& GetEscherEx() { return *mxEscherEx; }
+ XclExpMsoDrawing* GetMsodrawingPerSheet();
+ bool HasObj() const;
+ sal_uInt16 AddObj( XclObj* pObjRec );
+ XclObj* RemoveLastObj();
+
+protected:
+ explicit XclExpObjectManager( const XclExpObjectManager& rParent );
+
+private:
+ void InitStream( bool bTempFile );
+
+private:
+ boost::shared_ptr< ::utl::TempFile > mxTempFile;
+ boost::shared_ptr< SvStream > mxDffStrm;
+ boost::shared_ptr< XclEscherEx > mxEscherEx;
+ boost::shared_ptr< XclExpObjList > mxObjList;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpEmbeddedObjectManager : public XclExpObjectManager
+{
+public:
+ explicit XclExpEmbeddedObjectManager(
+ const XclExpObjectManager& rParent,
+ const Size& rPageSize,
+ sal_Int32 nScaleX, sal_Int32 nScaleY );
+
+ /** Creates a new DFF client anchor object for embedded objects according
+ to the scaling data passed to the constructor. Caller takes ownership! */
+ virtual XclExpDffAnchorBase* CreateDffAnchor() const;
+
+private:
+ Size maPageSize;
+ sal_Int32 mnScaleX;
+ sal_Int32 mnScaleY;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xeformula.hxx b/sc/source/filter/inc/xeformula.hxx
new file mode 100644
index 000000000000..698ca9b0f494
--- /dev/null
+++ b/sc/source/filter/inc/xeformula.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEFORMULA_HXX
+#define SC_XEFORMULA_HXX
+
+#include "xlformula.hxx"
+#include "xeroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+// External reference log =====================================================
+
+/** Log entry for external references in a formula, used i.e. in change tracking. */
+struct XclExpRefLogEntry
+{
+ const XclExpString* mpUrl; /// URL of the document containing the first sheet.
+ const XclExpString* mpFirstTab; /// Name of the first sheet.
+ const XclExpString* mpLastTab; /// Name of the last sheet.
+ sal_uInt16 mnFirstXclTab; /// Calc index of the first sheet.
+ sal_uInt16 mnLastXclTab; /// Calc index of the last sheet.
+
+ explicit XclExpRefLogEntry();
+};
+
+/** Vector containing a log for all external references in a formula, used i.e. in change tracking. */
+typedef ::std::vector< XclExpRefLogEntry > XclExpRefLog;
+
+// Formula compiler ===========================================================
+
+class ScRangeList;
+class XclExpFmlaCompImpl;
+
+/** The formula compiler to create Excel token arrays from Calc token arrays. */
+class XclExpFormulaCompiler : protected XclExpRoot
+{
+public:
+ explicit XclExpFormulaCompiler( const XclExpRoot& rRoot );
+ virtual ~XclExpFormulaCompiler();
+
+ /** Creates and returns the token array of a formula. */
+ XclTokenArrayRef CreateFormula(
+ XclFormulaType eType, const ScTokenArray& rScTokArr,
+ const ScAddress* pScBasePos = 0, XclExpRefLog* pRefLog = 0 );
+
+ /** Creates and returns a token array containing a single cell address. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScAddress& rScPos );
+
+ /** Creates and returns a token array containing a single cell range address. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScRange& rScRange );
+
+ /** Creates and returns the token array for a cell range list. */
+ XclTokenArrayRef CreateFormula( XclFormulaType eType, const ScRangeList& rScRanges );
+
+ /** Creates a single error token containing the passed error code. */
+ XclTokenArrayRef CreateErrorFormula( sal_uInt8 nErrCode );
+
+ /** Creates a single token for a special cell reference.
+ @descr This is used for array formulas and shared formulas (token tExp),
+ and multiple operation tables (token tTbl). */
+ XclTokenArrayRef CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos );
+
+ /** Creates a single tNameXR token for a reference to an external name.
+ @descr This is used i.e. for linked macros in push buttons. */
+ XclTokenArrayRef CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
+
+private:
+ typedef boost::shared_ptr< XclExpFmlaCompImpl > XclExpFmlaCompImplRef;
+ XclExpFmlaCompImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xehelper.hxx b/sc/source/filter/inc/xehelper.hxx
new file mode 100644
index 000000000000..f02e8ad12bc1
--- /dev/null
+++ b/sc/source/filter/inc/xehelper.hxx
@@ -0,0 +1,451 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEHELPER_HXX
+#define SC_XEHELPER_HXX
+
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include "xladdress.hxx"
+#include "xeroot.hxx"
+#include "xestring.hxx"
+
+// Export progress bar ========================================================
+
+class ScfProgressBar;
+
+/** The main progress bar for the export filter.
+
+ This class encapsulates creation and initialization of sub progress
+ segments. The Activate***Segment() functions activate a specific segement
+ of the main progress bar. The implementation of these functions contain the
+ calculation of the needed size of the segment. Following calls of the
+ Progress() function increase the currently activated sub segment.
+ */
+class XclExpProgressBar : protected XclExpRoot
+{
+public:
+ explicit XclExpProgressBar( const XclExpRoot& rRoot );
+ virtual ~XclExpProgressBar();
+
+ /** Initializes all segments and sub progress bars. */
+ void Initialize();
+
+ /** Increases the number of existing ROW records by 1. */
+ void IncRowRecordCount();
+
+ /** Activates the progress segment to create ROW records. */
+ void ActivateCreateRowsSegment();
+ /** Activates the progress segment to finalize ROW records. */
+ void ActivateFinalRowsSegment();
+
+ /** Increases the currently activated (sub) progress bar by 1 step. */
+ void Progress();
+
+private:
+ typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;
+
+ ScfProgressBarPtr mxProgress; /// Progress bar implementation.
+ ScfProgressBar* mpSubProgress; /// Current sub progress bar.
+
+ ScfProgressBar* mpSubRowCreate; /// Sub progress bar for creating table rows.
+ ScfInt32Vec maSubSegRowCreate; /// Segment ID's for all sheets in sub progress bar.
+
+ ScfProgressBar* mpSubRowFinal; /// Sub progress bar for finalizing ROW records.
+ sal_Int32 mnSegRowFinal; /// Progress segment for finalizing ROW records.
+
+ sal_Size mnRowCount; /// Number of created ROW records.
+};
+
+// Calc->Excel cell address/range conversion ==================================
+
+/** Provides functions to convert Calc cell addresses to Excel cell addresses. */
+class XclExpAddressConverter : public XclAddressConverterBase
+{
+public:
+ explicit XclExpAddressConverter( const XclExpRoot& rRoot );
+
+ // cell address -----------------------------------------------------------
+
+ /** Checks if the passed Calc cell address is valid.
+ @param rScPos The Calc cell address to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address in rScPos is valid. */
+ bool CheckAddress( const ScAddress& rScPos, bool bWarn );
+
+ /** Converts the passed Calc cell address to an Excel cell address.
+ @param rXclPos (Out) The converted Excel cell address, if valid.
+ @param rScPos The Calc cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address returned in rXclPos is valid. */
+ bool ConvertAddress( XclAddress& rXclPos,
+ const ScAddress& rScPos, bool bWarn );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+ @param rScPos The Calc cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return The converted Excel cell address. */
+ XclAddress CreateValidAddress( const ScAddress& rScPos, bool bWarn );
+
+ // cell range -------------------------------------------------------------
+
+ /** Checks if the passed cell range is valid (checks start and end position).
+ @param rScRange The Calc cell range to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range is not valid.
+ @return true = Cell range in rScRange is valid. */
+ bool CheckRange( const ScRange& rScRange, bool bWarn );
+
+ /** Checks and eventually crops the cell range to valid dimensions.
+ @descr The start position of the range will not be modified.
+ @param rScRange (In/out) The cell range to validate.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid
+ cells. If the range is partly valid, this function sets the warning
+ flag, corrects the range and returns true.
+ @return true = Cell range in rScRange is valid (original or cropped). */
+ bool ValidateRange( ScRange& rScRange, bool bWarn );
+
+ /** Converts the passed Calc cell range to an Excel cell range.
+ @param rXclRange (Out) The converted Excel cell range, if valid.
+ @param rScRange The Calc cell range to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid cells.
+ @return true = Cell range returned in rXclRange is valid (original or cropped). */
+ bool ConvertRange( XclRange& rXclRange, const ScRange& rScRange, bool bWarn );
+
+ // cell range list --------------------------------------------------------
+
+ /** Checks and eventually crops the cell ranges to valid dimensions.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are removed from
+ the cell range list.
+ @param rScRanges (In/out) The cell range list to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ValidateRangeList( ScRangeList& rScRanges, bool bWarn );
+
+ /** Converts the passed Calc cell range list to an Excel cell range list.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are not inserted
+ into the Excel cell range list.
+ @param rXclRanges (Out) The converted Excel cell range list.
+ @param rScRanges The Calc cell range list to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ConvertRangeList( XclRangeList& rXclRanges,
+ const ScRangeList& rScRanges, bool bWarn );
+};
+
+// EditEngine->String conversion ==============================================
+
+class SvxURLField;
+class XclExpHyperlink;
+
+/** Helper to create HLINK records during creation of formatted cell strings.
+
+ In Excel it is not possible to have more than one hyperlink in a cell. This
+ helper detects multiple occurrences of hyperlinks and fills a string which
+ is used to create a cell note containing all URLs. Only cells containing
+ one hyperlink are exported as hyperlink cells.
+ */
+class XclExpHyperlinkHelper : protected XclExpRoot
+{
+public:
+ typedef boost::shared_ptr< XclExpHyperlink > XclExpHyperlinkRef;
+
+ explicit XclExpHyperlinkHelper( const XclExpRoot& rRoot, const ScAddress& rScPos );
+ ~XclExpHyperlinkHelper();
+
+ /** Processes the passed URL field (tries to create a HLINK record).
+ @return The representation string of the URL field. */
+ String ProcessUrlField( const SvxURLField& rUrlField );
+
+ /** Returns true, if a single HLINK record has been created. */
+ bool HasLinkRecord() const;
+ /** Returns the craeted single HLINk record, or an empty reference. */
+ XclExpHyperlinkRef GetLinkRecord();
+
+ /** Returns true, if multiple URLs have been processed. */
+ inline bool HasMultipleUrls() const { return mbMultipleUrls; }
+ /** Returns a string containing all processed URLs. */
+ inline const String& GetUrlList() { return maUrlList; }
+
+private:
+ XclExpHyperlinkRef mxLinkRec; /// Created HLINK record.
+ ScAddress maScPos; /// Cell position to set at the HLINK record.
+ String maUrlList; /// List with all processed URLs.
+ bool mbMultipleUrls; /// true = Multiple URL fields processed.
+};
+
+// ----------------------------------------------------------------------------
+
+class EditEngine;
+class SdrTextObj;
+class ScStringCell;
+class ScEditCell;
+class ScPatternAttr;
+
+/** This class provides methods to create an XclExpString.
+ @descr The string can be created from an edit engine text object or
+ directly from a Calc edit cell. */
+class XclExpStringHelper : boost::noncopyable
+{
+public:
+ /** Creates a new unformatted string from the passed string.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rString The source string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new unformatted string from the passed character.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param cChar The source character. The NUL character is explicitly allowed.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ sal_Unicode cChar,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Appends an unformatted string to an Excel string object.
+ @descr Selects the correct Append() function depending on the current
+ BIFF version contained in the passed XclExpRoot object.
+ @param rXclString The Excel string object.
+ @param rString The source string. */
+ static void AppendString(
+ XclExpString& rXclString,
+ const XclExpRoot& rRoot,
+ const String& rString );
+
+ /** Appends a character to an Excel string object.
+ @descr Selects the correct Append() function depending on the current
+ BIFF version contained in the passed XclExpRoot object.
+ @param rXclString The Excel string object.
+ @param rString The source string. */
+ static void AppendChar(
+ XclExpString& rXclString,
+ const XclExpRoot& rRoot,
+ sal_Unicode cChar );
+
+ /** Creates a new formatted string from a Calc string cell.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ May create a formatted string object, if the cell text contains
+ different script types.
+ @param rStringCell The Calc string cell object.
+ @param pCellAttr The set item containing the cell formatting.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateCellString(
+ const XclExpRoot& rRoot,
+ const ScStringCell& rStringCell,
+ const ScPatternAttr* pCellAttr,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a Calc edit cell.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rEditCell The Calc edit cell object.
+ @param pCellAttr The set item containing the cell formatting.
+ @param rLinkHelper Helper object for hyperlink conversion.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateCellString(
+ const XclExpRoot& rRoot,
+ const ScEditCell& rEditCell,
+ const ScPatternAttr* pCellAttr,
+ XclExpHyperlinkHelper& rLinkHelper,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a drawing text box.
+ @descr Creates a Unicode string or a byte string, depending on the
+ current BIFF version contained in the passed XclExpRoot object.
+ @param rTextObj The text box object.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object (shared pointer). */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const SdrTextObj& rTextObj,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Creates a new formatted string from a edit text string.
+ @param rEditObj The edittext object.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string.
+ @return The new string object. */
+ static XclExpStringRef CreateString(
+ const XclExpRoot& rRoot,
+ const EditTextObject& rEditObj,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Returns the script type first text portion different to WEAK, or the system
+ default script type, if there is only weak script in the passed string. */
+ static sal_Int16 GetLeadingScriptType( const XclExpRoot& rRoot, const String& rString );
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclExpStringHelper();
+};
+
+// Header/footer conversion ===================================================
+
+class EditEngine;
+
+/** Converts edit engine text objects to an Excel header/footer string.
+ @descr Header/footer content is divided into three parts: Left, center and
+ right portion. All formatting information will be encoded in the Excel string
+ using special character seuences. A control sequence starts with the ampersand
+ character.
+
+ Supported control sequences:
+ &L start of left portion
+ &C start of center portion
+ &R start of right portion
+ &P current page number
+ &N page count
+ &D current date
+ &T current time
+ &A table name
+ &F file name without path
+ &Z file path without file name
+ &Z&F file path and name
+ &U underlining on/off
+ &E double underlining on/off
+ &S strikeout characters on/off
+ &X superscript on/off
+ &Y subscript on/off
+ &"fontname,fontstyle" use font with name 'fontname' and style 'fontstyle'
+ &fontheight set font height in points ('fontheight' is a decimal value)
+
+ Known but unsupported control sequences:
+ &G picture
+ */
+class XclExpHFConverter : protected XclExpRoot, private boost::noncopyable
+{
+public:
+ explicit XclExpHFConverter( const XclExpRoot& rRoot );
+
+ /** Generates the header/footer string from the passed edit engine text objects. */
+ void GenerateString(
+ const EditTextObject* pLeftObj,
+ const EditTextObject* pCenterObj,
+ const EditTextObject* pRightObj );
+
+ /** Returns the last generated header/footer string. */
+ inline const String& GetHFString() const { return maHFString; }
+ /** Returns the total height of the last generated header/footer in twips. */
+ inline sal_Int32 GetTotalHeight() const { return mnTotalHeight; }
+
+private:
+ /** Converts the text object contents and stores it in the passed string. */
+ void AppendPortion(
+ const EditTextObject* pTextObj,
+ sal_Unicode cPortionCode );
+
+private:
+ EditEngine& mrEE; /// The header/footer edit engine.
+ String maHFString; /// The last generated header/footer string.
+ sal_Int32 mnTotalHeight; /// Total height of the last header/footer (twips).
+};
+
+// URL conversion =============================================================
+
+/** This class contains static methods to encode a file URL.
+ @descr Excel stores URLs in a format that contains special control characters,
+ i.e. for directory separators or volume names. */
+class XclExpUrlHelper : boost::noncopyable
+{
+public:
+ /** Encodes and returns the URL passed in rAbsUrl to an Excel like URL.
+ @param pTableName Optional pointer to a table name to be encoded in this URL. */
+ static String EncodeUrl( const XclExpRoot& rRoot, const String& rAbsUrl, const String* pTableName = 0 );
+ /** Encodes and returns the passed DDE link to an Excel like DDE link. */
+ static String EncodeDde( const String& rApplic, const String rTopic );
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclExpUrlHelper();
+};
+
+// ----------------------------------------------------------------------------
+class ScDocument;
+class ScMatrix;
+
+/** Contains cached values in a 2-dimensional array. */
+class XclExpCachedMatrix
+{
+ void GetDimensions( SCSIZE & nCols, SCSIZE & nRows ) const;
+public:
+ /** Constructs and fills a new matrix.
+ @param rMatrix The Calc value matrix. */
+ explicit XclExpCachedMatrix( const ScMatrix& rMatrix );
+ ~XclExpCachedMatrix();
+
+ /** Returns the byte count of all contained data. */
+ sal_Size GetSize() const;
+ /** Writes the complete matrix to stream. */
+ void Save( XclExpStream& rStrm ) const;
+
+private:
+ const ScMatrix& mrMatrix;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xelink.hxx b/sc/source/filter/inc/xelink.hxx
new file mode 100644
index 000000000000..866151df28f5
--- /dev/null
+++ b/sc/source/filter/inc/xelink.hxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XELINK_HXX
+#define SC_XELINK_HXX
+
+#include "markdata.hxx"
+#include "xllink.hxx"
+#include "xerecord.hxx"
+#include "xehelper.hxx"
+#include "xeformula.hxx"
+#include "externalrefmgr.hxx"
+#include <boost/shared_ptr.hpp>
+
+class ScRange;
+struct ScSingleRefData;
+struct ScComplexRefData;
+
+/* ============================================================================
+Classes for export of different kinds of internal/external references.
+- 3D cell and cell range links
+- External cell and cell range links
+- External defined names
+- Macro calls
+- Add-in functions
+- DDE links
+- OLE object links
+============================================================================ */
+
+// Excel sheet indexes ========================================================
+
+/** Stores the correct Excel sheet index for each Calc sheet.
+ @descr The class knows all sheets which will not exported
+ (i.e. external link sheets, scenario sheets). */
+class XclExpTabInfo : protected XclExpRoot
+{
+public:
+ /** Initializes the complete buffer from the current exported document. */
+ explicit XclExpTabInfo( const XclExpRoot& rRoot );
+
+ /** Returns true, if the specified Calc sheet will be exported. */
+ bool IsExportTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is used to store external cell contents. */
+ bool IsExternalTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is visible and will be exported. */
+ bool IsVisibleTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is selected and will be exported. */
+ bool IsSelectedTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is the displayed (active) sheet. */
+ bool IsDisplayedTab( SCTAB nScTab ) const;
+ /** Returns true, if the specified Calc sheet is displayed in right-to-left mode. */
+ bool IsMirroredTab( SCTAB nScTab ) const;
+ /** Returns the Calc name of the specified sheet. */
+ const String& GetScTabName( SCTAB nScTab ) const;
+
+ /** Returns the Excel sheet index for a given Calc sheet. */
+ sal_uInt16 GetXclTab( SCTAB nScTab ) const;
+
+ /** Returns the Calc sheet index of the nSortedTab-th entry in the sorted sheet names list. */
+ SCTAB GetRealScTab( SCTAB nSortedScTab ) const;
+
+ /** Returns the number of Calc sheets. */
+ inline SCTAB GetScTabCount() const { return mnScCnt; }
+
+ /** Returns the number of Excel sheets to be exported. */
+ inline sal_uInt16 GetXclTabCount() const { return mnXclCnt; }
+ /** Returns the number of external linked sheets. */
+ inline sal_uInt16 GetXclExtTabCount() const { return mnXclExtCnt; }
+ /** Returns the number of exported selected sheets. */
+ inline sal_uInt16 GetXclSelectedCount() const { return mnXclSelCnt; }
+
+ /** Returns the Excel index of the active, displayed sheet. */
+ inline sal_uInt16 GetDisplayedXclTab() const { return mnDisplXclTab; }
+ /** Returns the Excel index of the first visible sheet. */
+ inline sal_uInt16 GetFirstVisXclTab() const { return mnFirstVisXclTab; }
+
+private:
+ /** Returns true, if any of the passed flags is set for the specified Calc sheet. */
+ bool GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const;
+ /** Sets or clears (depending on bSet) all passed flags for the specified Calc sheet. */
+ void SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet = true );
+
+ /** Searches for sheets not to be exported. */
+ void CalcXclIndexes();
+ /** Sorts the names of all tables and stores the indexes of the sorted indexes. */
+ void CalcSortedIndexes();
+
+private:
+ /** Data structure with infoemation about one Calc sheet. */
+ struct XclExpTabInfoEntry
+ {
+ String maScName;
+ sal_uInt16 mnXclTab;
+ sal_uInt8 mnFlags;
+ inline explicit XclExpTabInfoEntry() : mnXclTab( 0 ), mnFlags( 0 ) {}
+ };
+
+ typedef ::std::vector< XclExpTabInfoEntry > XclExpTabInfoVec;
+ typedef ::std::vector< SCTAB > ScTabVec;
+
+ XclExpTabInfoVec maTabInfoVec; /// Array of Calc sheet index information.
+
+ SCTAB mnScCnt; /// Count of Calc sheets.
+ sal_uInt16 mnXclCnt; /// Count of Excel sheets to be exported.
+ sal_uInt16 mnXclExtCnt; /// Count of external link sheets.
+ sal_uInt16 mnXclSelCnt; /// Count of selected and exported sheets.
+ sal_uInt16 mnDisplXclTab; /// Displayed (active) sheet.
+ sal_uInt16 mnFirstVisXclTab; /// First visible sheet.
+
+ ScTabVec maFromSortedVec; /// Sorted Calc sheet index -> real Calc sheet index.
+ ScTabVec maToSortedVec; /// Real Calc sheet index -> sorted Calc sheet index.
+};
+
+// Export link manager ========================================================
+
+class XclExpLinkManagerImpl;
+
+/** Stores all data for internal/external references (the link table). */
+class XclExpLinkManager : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpLinkManager( const XclExpRoot& rRoot );
+ virtual ~XclExpLinkManager();
+
+ /** Searches for an EXTERNSHEET index for the given Calc sheet.
+ @descr See above for the meaning of EXTERNSHEET indexes.
+ @param rnExtSheet (out-param) Returns the EXTERNSHEET index.
+ @param rnXclTab (out-param) Returns the Excel sheet index.
+ @param nScTab The Calc sheet index to process.
+ param pRefLogEntry If not 0, data about the external link is stored here. */
+ void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnXclTab, SCTAB nScTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 );
+ /** Searches for an EXTERNSHEET index for the given Calc sheet range.
+ @descr See above for the meaning of EXTERNSHEET indexes.
+ @param rnExtSheet (out-param) Returns the EXTERNSHEET index.
+ @param rnFirstXclTab (out-param) Returns the Excel sheet index of the first sheet.
+ @param rnXclTab (out-param) Returns the Excel sheet index of the last sheet.
+ @param nFirstScTab The first Calc sheet index to process.
+ @param nLastScTab The last Calc sheet index to process.
+ param pRefLogEntry If not 0, data about the external link is stored here. */
+ void FindExtSheet( sal_uInt16& rnExtSheet,
+ sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
+ SCTAB nFirstScTab, SCTAB nLastScTab,
+ XclExpRefLogEntry* pRefLogEntry = 0 );
+ /** Searches for a special EXTERNSHEET index for the own document. */
+ sal_uInt16 FindExtSheet( sal_Unicode cCode );
+
+ void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
+ /** Stores the cell with the given address in a CRN record list. */
+ void StoreCell( const ScSingleRefData& rRef );
+ /** Stores all cells in the given range in a CRN record list. */
+ void StoreCellRange( const ScComplexRefData& rRef );
+
+ void StoreCell( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
+
+ void StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
+
+ /** Finds or inserts an EXTERNNAME record for an add-in function name.
+ @param rnExtSheet (out-param) Returns the index of the EXTSHEET structure for the add-in function name.
+ @param rnExtName (out-param) Returns the 1-based EXTERNNAME record index.
+ @return true = add-in function inserted; false = error (i.e. not supported in current BIFF). */
+ bool InsertAddIn(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** InsertEuroTool */
+ bool InsertEuroTool(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rName );
+ /** Finds or inserts an EXTERNNAME record for DDE links.
+ @param rnExtSheet (out-param) Returns the index of the EXTSHEET structure for the DDE link.
+ @param rnExtName (out-param) Returns the 1-based EXTERNNAME record index.
+ @return true = DDE link inserted; false = error (i.e. not supported in current BIFF). */
+ bool InsertDde(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
+ const String& rApplic, const String& rTopic, const String& rItem );
+
+ bool InsertExtName(
+ sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
+
+ /** Writes the entire Link table. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpLinkManagerImpl > XclExpLinkMgrImplPtr;
+ XclExpLinkMgrImplPtr mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xename.hxx b/sc/source/filter/inc/xename.hxx
new file mode 100644
index 000000000000..15dc0c2ea9d2
--- /dev/null
+++ b/sc/source/filter/inc/xename.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XENAME_HXX
+#define SC_XENAME_HXX
+
+#include "xerecord.hxx"
+#include "xlname.hxx"
+#include "xlformula.hxx"
+#include "xeroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+// ============================================================================
+
+class ScRangeList;
+class XclExpNameManagerImpl;
+
+/** Manager that stores all internal defined names (NAME records) of the document. */
+class XclExpNameManager : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpNameManager( const XclExpRoot& rRoot );
+ virtual ~XclExpNameManager();
+
+ /** Creates NAME records for built-in and user defined names. */
+ void Initialize();
+
+ /** Inserts the Calc name with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertName( SCTAB nTab, sal_uInt16 nScNameIdx );
+ /** Inserts the Calc database range with the passed index and returns the Excel NAME index. */
+ sal_uInt16 InsertDBRange( sal_uInt16 nScDBRangeIdx );
+
+ /** Inserts a new built-in defined name, referring to the passed sheet range. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, const ScRange& rRange );
+ /** Inserts a new built-in defined name, referring to the passed sheet range list. */
+ sal_uInt16 InsertBuiltInName( sal_Unicode cBuiltIn, const ScRangeList& rRangeList );
+
+ /** Inserts a new defined name. Sets another unused name, if rName already exists. */
+ sal_uInt16 InsertUniqueName( const String& rName, XclTokenArrayRef xTokArr, SCTAB nScTab );
+ /** Returns index of an existing name, or creates a name without definition. */
+ sal_uInt16 InsertRawName( const String& rName );
+ /** Searches or inserts a defined name describing a macro name.
+ @param bVBasic true = Visual Basic macro, false = Sheet macro.
+ @param bFunc true = Macro function; false = Macro procedure. */
+ sal_uInt16 InsertMacroCall( const String& rMacroName, bool bVBasic, bool bFunc, bool bHidden = false );
+
+ /** Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names. */
+ const String& GetOrigName( sal_uInt16 nNameIdx ) const;
+ /** Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names. */
+ SCTAB GetScTab( sal_uInt16 nNameIdx ) const;
+ /** Returns true, if the specified defined name is volatile. */
+ bool IsVolatile( sal_uInt16 nNameIdx ) const;
+
+ /** Writes the entire list of NAME records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpNameManagerImpl > XclExpNameMgrImplRef;
+ XclExpNameMgrImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xepage.hxx b/sc/source/filter/inc/xepage.hxx
new file mode 100644
index 000000000000..be8d1a1ac08c
--- /dev/null
+++ b/sc/source/filter/inc/xepage.hxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEPAGE_HXX
+#define SC_XEPAGE_HXX
+
+#include "xerecord.hxx"
+#include "xlpage.hxx"
+#include "xeroot.hxx"
+
+// Page settings records ======================================================
+
+// Header/footer --------------------------------------------------------------
+
+/** Represents a HEADER or FOOTER record. */
+class XclExpHeaderFooter : public XclExpRecord
+{
+public:
+ explicit XclExpHeaderFooter( sal_uInt16 nRecId, const String& rHdrString );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the header or footer string. Writes an empty record, if no header/footer present. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maHdrString; /// Header or footer contents.
+};
+
+// General page settings ------------------------------------------------------
+
+/** Represents a SETUP record that contains common page settings. */
+class XclExpSetup : public XclExpRecord
+{
+public:
+ explicit XclExpSetup( const XclPageData& rPageData );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the SETUP record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclPageData& mrData; /// Page settings data of current sheet.
+};
+
+// Manual page breaks ---------------------------------------------------------
+
+/** Stores an array of manual page breaks for columns or rows. */
+class XclExpPageBreaks : public XclExpRecord
+{
+public:
+ explicit XclExpPageBreaks(
+ sal_uInt16 nRecId,
+ const ScfUInt16Vec& rPageBreaks,
+ sal_uInt16 nMaxPos );
+
+ /** Writes the record, if the list is not empty. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the page break list. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const ScfUInt16Vec& mrPageBreaks; /// Page settings data of current sheet.
+ sal_uInt16 mnMaxPos; /// Maximum row/column for BIFF8 page breaks.
+};
+
+// Page settings ==============================================================
+
+/** Contains all page (print) settings records for a single sheet. */
+class XclExpPageSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the current page settings. */
+ explicit XclExpPageSettings( const XclExpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Writes all page settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ XclPageData maData; /// Page settings data.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all page (print) settings records for a chart object. */
+class XclExpChartPageSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the current page settings. */
+ explicit XclExpChartPageSettings( const XclExpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Writes all page settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclPageData maData; /// Page settings data.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx
new file mode 100644
index 000000000000..3279aa4ff290
--- /dev/null
+++ b/sc/source/filter/inc/xepivot.hxx
@@ -0,0 +1,488 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEPIVOT_HXX
+#define SC_XEPIVOT_HXX
+
+#include <map>
+#include "xerecord.hxx"
+#include "xlpivot.hxx"
+#include "xeroot.hxx"
+
+class ScDPObject;
+class ScDPSaveData;
+class ScDPSaveDimension;
+class ScDPSaveMember;
+class ScDPDimensionSaveData;
+class ScDPSaveGroupDimension;
+class ScDPSaveNumGroupDimension;
+struct ScDPNumGroupInfo;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item in a pivot cache containing data of any type. */
+class XclExpPCItem : public XclExpRecord, public XclPCItem
+{
+public:
+ explicit XclExpPCItem( const String& rText );
+ explicit XclExpPCItem( double fValue );
+ explicit XclExpPCItem( const DateTime& rDateTime );
+ explicit XclExpPCItem( sal_Int16 nValue );
+ explicit XclExpPCItem( bool bValue );
+
+ inline sal_uInt16 GetTypeFlag() const { return mnTypeFlag; }
+
+ bool EqualsText( const String& rText ) const;
+ bool EqualsDouble( double fValue ) const;
+ bool EqualsDateTime( const DateTime& rDateTime ) const;
+ bool EqualsBool( bool bValue ) const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnTypeFlag; /// Data type flag.
+};
+
+// ============================================================================
+
+class XclExpPivotCache;
+
+class XclExpPCField : public XclExpRecord, public XclPCField, protected XclExpRoot
+{
+public:
+ /** Creates a standard pivot cache field, filled from sheet source data. */
+ explicit XclExpPCField( const XclExpRoot& rRoot,
+ const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScRange& rRange );
+ /** Creates a child grouping pivot cache field, filled from the passed grouping info. */
+ explicit XclExpPCField( const XclExpRoot& rRoot,
+ const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx,
+ const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim,
+ const XclExpPCField& rBaseField );
+ virtual ~XclExpPCField();
+
+ /** Sets the passed field as direct grouping child field of this field. */
+ void SetGroupChildField( const XclExpPCField& rChildField );
+ /** Converts this standard field into a numeric grouping field. */
+ void ConvertToNumGroup( const ScDPObject& rDPObj, const ScDPSaveNumGroupDimension& rNumGroupDim );
+
+ /** Returns the name of this cache field. */
+ inline const String& GetFieldName() const { return maFieldInfo.maName; }
+
+ /** Returns the number of visible items of this field. */
+ sal_uInt16 GetItemCount() const;
+ /** Returns the specified pivot cache item (returns visible items in groupings). */
+ const XclExpPCItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the index of a pivot cache item, or EXC_PC_NOITEM on error. */
+ sal_uInt16 GetItemIndex( const String& rItemName ) const;
+
+ /** Returns the size an item index needs to write out. */
+ sal_Size GetIndexSize() const;
+ /** Writes the item index at the passed source row position as part of the SXINDEXLIST record. */
+ void WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const;
+
+ /** Writes the pivot cache field and all items and other related records. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpPCItem > XclExpPCItemList;
+
+ /** Returns the item list that contains the visible items.
+ @descr Visible items are equal to source items in standard fields,
+ but are generated items in grouping and calculated fields. */
+ const XclExpPCItemList& GetVisItemList() const;
+
+ /** Initializes a standard field. Inserts all original source items. */
+ void InitStandardField( const ScRange& rRange );
+ /** Initializes a standard grouping field. Inserts all visible grouping items. */
+ void InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim );
+ /** Initializes a numeric grouping field. Inserts all visible grouping items and the limit settings. */
+ void InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo );
+ /** Initializes a date grouping field. Inserts all visible grouping items and the limit settings. */
+ void InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart );
+
+ /** Inserts the passed index into the item index array of original items. */
+ void InsertItemArrayIndex( size_t nListPos );
+ /** Inserts an original source item. Updates item index array. */
+ void InsertOrigItem( XclExpPCItem* pNewItem );
+ /** Inserts an original text item, if it is not contained already. */
+ void InsertOrigTextItem( const String& rText );
+ /** Inserts an original value item, if it is not contained already. */
+ void InsertOrigDoubleItem( double fValue );
+ /** Inserts an original date/time item, if it is not contained already. */
+ void InsertOrigDateTimeItem( const DateTime& rDateTime );
+ /** Inserts an original boolean item, if it is not contained already. */
+ void InsertOrigBoolItem( bool bValue );
+
+ /** Inserts an item into the grouping item list. Does not change anything else.
+ @return The list index of the new item. */
+ sal_uInt16 InsertGroupItem( XclExpPCItem* pNewItem );
+ /** Generates and inserts all visible items for numeric or date grouping. */
+ void InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart = 0 );
+
+ /** Inserts the SXDOUBLE items that specify the limits for a numeric grouping. */
+ void SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo );
+ /** Inserts the SXDATETIME/SXINTEGER items that specify the limits for a date grouping.
+ @param bUseStep true = Insert the passed step value; false = always insert 1. */
+ void SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep );
+
+ /** Initializes flags and item count fields. */
+ void Finalize();
+
+ /** Writes an SXNUMGROUP record and the additional items for a numeric grouping field. */
+ void WriteSxnumgroup( XclExpStream& rStrm );
+ /** Writes an SXGROUPINFO record describing the item order in grouping fields. */
+ void WriteSxgroupinfo( XclExpStream& rStrm );
+
+ /** Writes the contents of the SXFIELD record for this field. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpPivotCache& mrPCache; /// Parent pivot cache containing this field.
+ XclExpPCItemList maOrigItemList; /// List with original items.
+ XclExpPCItemList maGroupItemList; /// List with grouping items.
+ ScfUInt16Vec maIndexVec; /// Indexes into maItemList.
+ XclExpPCItemList maNumGroupLimits; /// List with limit values for numeric grouping.
+ sal_uInt16 mnTypeFlags; /// Collected item data type flags.
+};
+
+// ============================================================================
+
+class XclExpPivotCache : protected XclExpRoot
+{
+public:
+ explicit XclExpPivotCache( const XclExpRoot& rRoot,
+ const ScDPObject& rDPObj, sal_uInt16 nListIdx );
+
+ /** Returns true, if the cache has been constructed successfully. */
+ inline bool IsValid() const { return mbValid; }
+ /** Returns true, if the item index list will be written. */
+ bool HasItemIndexList() const;
+
+ /** Returns the stream identifier used to create the cache stream. */
+ inline sal_uInt16 GetStreamId() const { return maPCInfo.mnStrmId; }
+ /** Returns the list index of the cache used in pivot table records. */
+ inline sal_uInt16 GetCacheIndex() const { return mnListIdx; }
+
+ /** Returns the number of pivot cache fields. */
+ sal_uInt16 GetFieldCount() const;
+ /** Returns the specified pivot cache field. */
+ const XclExpPCField* GetField( sal_uInt16 nFieldIdx ) const;
+ /** Returns true, if this pivot cache contains non-standard fields (e.g. grouping fields). */
+ bool HasAddFields() const;
+
+ /** Returns true, if the passed DP object has the same data source as this cache. */
+ bool HasEqualDataSource( const ScDPObject& rDPObj ) const;
+
+ /** Writes related records into Workbook stream and creates the pivot cache storage stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Returns read/write access to a pivot cache field. */
+ XclExpPCField* GetFieldAcc( sal_uInt16 nFieldIdx );
+ /** Returns read/write access to a pivot cache field. */
+ XclExpPCField* GetFieldAcc( const String& rFieldName );
+
+ /** Adds all pivot cache fields. */
+ void AddFields( const ScDPObject& rDPObj );
+
+ /** Adds all standard pivot cache fields based on source data. */
+ void AddStdFields( const ScDPObject& rDPObj );
+ /** Adds all grouping pivot cache fields. */
+ void AddGroupFields( const ScDPObject& rDPObj );
+ /** Adds all calculated pivot cache fields. */
+ void AddCalcFields( const ScDPObject& rDPObj );
+
+ /** Writes the DCONREF record containing the source range. */
+ void WriteDconref( XclExpStream& rStrm ) const;
+ /** DCONNAME record contains range name source. */
+ void WriteDConName( XclExpStream& rStrm ) const;
+
+ /** Creates the pivot cache storage stream and writes the cache. */
+ void WriteCacheStream();
+ /** Writes the SXDB record. */
+ void WriteSxdb( XclExpStream& rStrm ) const;
+ /** Writes the SXDBEX record. */
+ void WriteSxdbex( XclExpStream& rStrm ) const;
+ /** Writes the SXINDEXLIST record list containing the item index table. */
+ void WriteSxindexlistList( XclExpStream& rStrm ) const;
+
+private:
+ typedef XclExpRecordList< XclExpPCField > XclExpPCFieldList;
+ typedef XclExpPCFieldList::RecordRefType XclExpPCFieldRef;
+
+ XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record).
+ XclExpPCFieldList maFieldList; /// List of all pivot cache fields.
+ String maTabName; /// Name of source data sheet.
+ ::rtl::OUString maSrcRangeName; /// Range name for source data.
+ ScRange maOrigSrcRange; /// The original sheet source range.
+ ScRange maExpSrcRange; /// The exported sheet source range.
+ ScRange maDocSrcRange; /// The range used to build the cache fields and items.
+ sal_uInt16 mnListIdx; /// List index in pivot cache buffer.
+ bool mbValid; /// true = The cache is valid for export.
+};
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+class XclExpPivotTable;
+
+/** Data field position specifying the pivot table field index (first) and data info index (second). */
+typedef ::std::pair< sal_uInt16, sal_uInt16 > XclPTDataFieldPos;
+
+// ============================================================================
+
+class XclExpPTItem : public XclExpRecord
+{
+public:
+ explicit XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx );
+ explicit XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache );
+
+ /** Returns the internal name of this item. */
+ const String& GetItemName() const;
+
+ /** Fills this item with properties from the passed save member. */
+ void SetPropertiesFromMember( const ScDPSaveMember& rSaveMem );
+
+private:
+ /** Writes the SXVI record body describing the pivot table item. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpPCItem* mpCacheItem; /// The referred pivot cache item.
+ XclPTItemInfo maItemInfo; /// General data for this item.
+};
+
+// ============================================================================
+
+class XclExpPTField : public XclExpRecordBase
+{
+public:
+ explicit XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx );
+
+ // data access ------------------------------------------------------------
+
+ /** Returns the name of this field. */
+ const String& GetFieldName() const;
+ /** Returns the pivot table field list index of this field. */
+ sal_uInt16 GetFieldIndex() const;
+
+ /** Returns the index of the last inserted data info struct. */
+ sal_uInt16 GetLastDataInfoIndex() const;
+
+ /** Returns the list index of an item by its name.
+ @param nDefaultIdx This value will be returned, if the item could not be found. */
+ sal_uInt16 GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const;
+
+ // fill data --------------------------------------------------------------
+
+ /** Fills this field with row/column/page properties from the passed save dimension. */
+ void SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+ /** Fills this field with data field properties from the passed save dimension. */
+ void SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+
+ /** Appends special items describing the field subtotal entries. */
+ void AppendSubtotalItems();
+
+ // records ----------------------------------------------------------------
+
+ /** Writes an entry for an SXPI record containing own page field info. */
+ void WriteSxpiEntry( XclExpStream& rStrm ) const;
+ /** Writes an SXDI records containing info about a data field. */
+ void WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const;
+
+ /** Writes the entire pivot table field. */
+ virtual void Save( XclExpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns an item by its name. */
+ XclExpPTItem* GetItemAcc( const String& rName );
+
+ /** Appends a special item describing a field subtotal entry. */
+ void AppendSubtotalItem( sal_uInt16 nItemType );
+
+ /** Writes the SXVD record introducing the field. */
+ void WriteSxvd( XclExpStream& rStrm ) const;
+ /** Writes the SXVDEX record containing additional settings. */
+ void WriteSxvdex( XclExpStream& rStrm ) const;
+
+private:
+ typedef ::std::vector< XclPTDataFieldInfo > XclPTDataFieldInfoVec;
+ typedef XclExpRecordList< XclExpPTItem > XclExpPTItemList;
+
+ const XclExpPivotTable& mrPTable; /// Parent pivot table containing this field.
+ const XclExpPCField* mpCacheField; /// The referred pivot cache field.
+ XclPTFieldInfo maFieldInfo; /// General field info (SXVD record).
+ XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record).
+ XclPTPageFieldInfo maPageInfo; /// Page field info (entry in SXPI record).
+ XclPTDataFieldInfoVec maDataInfoVec; /// List of extended data field info (SXDI records).
+ XclExpPTItemList maItemList; /// List of all items of this field.
+};
+
+// ============================================================================
+
+class XclExpPivotTable : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpPivotTable( const XclExpRoot& rRoot,
+ const ScDPObject& rDPObj, const XclExpPivotCache& rPCache );
+
+ /** Returns a pivot cache field. */
+ const XclExpPCField* GetCacheField( sal_uInt16 nCacheIdx ) const;
+
+ /** Returns the output range of the pivot table. */
+ inline SCTAB GetScTab() const { return mnOutScTab; }
+
+ /** Returns a pivot table field by its name. */
+ const XclExpPTField* GetField( sal_uInt16 nFieldIdx ) const;
+ /** Returns a pivot table field by its name. */
+ const XclExpPTField* GetField( const String& rName ) const;
+
+ /** Returns the data-field-only index of the first data field with the passed name.
+ @param nDefaultIdx This value will be returned, if the field could not be found. */
+ sal_uInt16 GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const;
+
+ /** Writes the entire pivot table. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns a pivot table field by its name. */
+ XclExpPTField* GetFieldAcc( const String& rName );
+ /** Returns a pivot table field corresponding to the passed save dimension. */
+ XclExpPTField* GetFieldAcc( const ScDPSaveDimension& rSaveDim );
+
+ // fill data --------------------------------------------------------------
+
+ /** Fills internal members with all properties from the passed save data. */
+ void SetPropertiesFromDP( const ScDPSaveData& rSaveData );
+ /** Fills a pivot table field with all properties from the passed save dimension. */
+ void SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+ /** Fills a pivot table data field with all properties from the passed save dimension. */
+ void SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim );
+
+ /** Initializes any data after processing the entire source DataPilot. */
+ void Finalize();
+
+ // records ----------------------------------------------------------------
+
+ /** Writes the SXVIEW record starting the pivot table. */
+ void WriteSxview( XclExpStream& rStrm ) const;
+ /** Writes an SXIVD record for row field or column field order. */
+ void WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const;
+ /** Writes the SXPI record containing page field info. */
+ void WriteSxpi( XclExpStream& rStrm ) const;
+ /** Writes all SXDI records containing info about the data fields. */
+ void WriteSxdiList( XclExpStream& rStrm ) const;
+ /** Writes a dummy SXLI records containing item layout info. */
+ void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const;
+ /** Writes the SXEX records containing additional pivot table info. */
+ void WriteSxex( XclExpStream& rStrm ) const;
+
+ void WriteQsiSxTag( XclExpStream& rStrm ) const;
+ /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */
+ void WriteSxViewEx9( XclExpStream& rStrm ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList;
+ typedef XclExpPTFieldList::RecordRefType XclExpPTFieldRef;
+ typedef ::std::vector< XclPTDataFieldPos > XclPTDataFieldPosVec;
+
+ const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on.
+ XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record).
+ XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9)
+ XclExpPTFieldList maFieldList; /// All fields in pivot cache order.
+ ScfUInt16Vec maRowFields; /// Row field indexes.
+ ScfUInt16Vec maColFields; /// Column field indexes.
+ ScfUInt16Vec maPageFields; /// Page field indexes.
+ XclPTDataFieldPosVec maDataFields; /// Data field indexes.
+ XclExpPTField maDataOrientField; /// Special data field orientation field.
+ SCTAB mnOutScTab; /// Sheet index of the output range.
+ bool mbValid; /// true = The pivot table is valid for export.
+ bool mbFilterBtn; /// true = DataPilot has filter button.
+};
+
+// ============================================================================
+
+/** The main class for pivot table export.
+
+ This class contains all pivot caches and pivot tables in a Calc document.
+ It creates the pivot cache streams and pivot table records in the main
+ workbook stream. It supports sharing of pivot caches between multiple pivot
+ tables to decrease file size.
+ */
+class XclExpPivotTableManager : protected XclExpRoot
+{
+public:
+ explicit XclExpPivotTableManager( const XclExpRoot& rRoot );
+
+ /** Creates all pivot tables and caches from the Calc DataPilot objects. */
+ void CreatePivotTables();
+
+ /** Creates a record wrapper for exporting all pivot caches. */
+ XclExpRecordRef CreatePivotCachesRecord();
+ /** Creates a record wrapper for exporting all pivot tables of the specified sheet. */
+ XclExpRecordRef CreatePivotTablesRecord( SCTAB nScTab );
+
+ /** Writes all pivot caches (all Workbook records and cache streams). */
+ void WritePivotCaches( XclExpStream& rStrm );
+ void WritePivotCachesXml( XclExpXmlStream& rStrm );
+ /** Writes all pivot tables of the specified Calc sheet. */
+ void WritePivotTables( XclExpStream& rStrm, SCTAB nScTab );
+ void WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab );
+
+private:
+ /** Finds an existing (if enabled in mbShareCaches) or creates a new pivot cache.
+ @return Pointer to the pivot cache or 0, if the passed source range was invalid. */
+ const XclExpPivotCache* CreatePivotCache( const ScDPObject& rDPObj );
+
+private:
+ typedef XclExpRecordList< XclExpPivotCache > XclExpPivotCacheList;
+ typedef XclExpPivotCacheList::RecordRefType XclExpPivotCacheRef;
+ typedef XclExpRecordList< XclExpPivotTable > XclExpPivotTableList;
+ typedef XclExpPivotTableList::RecordRefType XclExpPivotTableRef;
+
+ XclExpPivotCacheList maPCacheList; /// List of all pivot caches.
+ XclExpPivotTableList maPTableList; /// List of all pivot tables.
+ bool mbShareCaches; /// true = Tries to share caches between tables.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xerecord.hxx b/sc/source/filter/inc/xerecord.hxx
new file mode 100644
index 000000000000..4bfa6dbb0d0d
--- /dev/null
+++ b/sc/source/filter/inc/xerecord.hxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XERECORD_HXX
+#define SC_XERECORD_HXX
+
+#include "xlconst.hxx"
+#include "xestream.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Base classes to export Excel records =======================================
+
+/** Base class for all Excel records.
+
+ Derive from this class to implement any functionality performed during
+ saving the records - except really writing a record (i.e. write a list of
+ records contained in the class). Derive from XclExpRecord (instead from
+ this class) to write common records.
+ */
+class XclExpRecordBase
+{
+public:
+ virtual ~XclExpRecordBase();
+
+ /** Overwrite this method to do any operation while saving the record. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpDelegatingRecord : public XclExpRecordBase
+{
+public:
+ XclExpDelegatingRecord( XclExpRecordBase* pRecord );
+ ~XclExpDelegatingRecord();
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ XclExpRecordBase* mpRecord;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlElementRecord : public XclExpRecordBase
+{
+public:
+ XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlElementRecord();
+
+protected:
+ sal_Int32 mnElement;
+ void (*mpAttributes)( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlStartElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlStartElementRecord();
+
+ /** Starts the element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlEndElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlEndElementRecord( sal_Int32 nElement );
+ virtual ~XclExpXmlEndElementRecord();
+
+ /** Ends the element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlStartSingleElementRecord : public XclExpXmlElementRecord
+{
+public:
+ XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ virtual ~XclExpXmlStartSingleElementRecord();
+
+ /** Starts the single element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpXmlEndSingleElementRecord : public XclExpRecordBase
+{
+public:
+ XclExpXmlEndSingleElementRecord();
+ virtual ~XclExpXmlEndSingleElementRecord();
+
+ /** Ends the single element nElement */
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for single records with any content.
+
+ This class handles writing the record header. Derived classes only have to
+ write the record body. Calculating the record size before saving optimizes
+ the write process (the stream does not have to seek back and update the
+ written record size). But it is not required to calculate a valid size
+ (maybe it would be too complex or just impossible until the record is
+ really written).
+ */
+class XclExpRecord : public XclExpRecordBase
+{
+public:
+ /** @param nRecId The record ID of this record. May be set later with SetRecId().
+ @param nRecSize The predicted record size. May be set later with SetRecSize(). */
+ explicit XclExpRecord(
+ sal_uInt16 nRecId = EXC_ID_UNKNOWN,
+ sal_Size nRecSize = 0 );
+
+ virtual ~XclExpRecord();
+
+ /** Returns the current record ID. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the current record size prediction. */
+ inline sal_Size GetRecSize() const { return mnRecSize; }
+
+ /** Sets a new record ID. */
+ inline void SetRecId( sal_uInt16 nRecId ) { mnRecId = nRecId; }
+ /** Sets a new record size prediction. */
+ inline void SetRecSize( sal_Size nRecSize ) { mnRecSize = nRecSize; }
+ /** Adds a size value to the record size prediction. */
+ inline void AddRecSize( sal_Size nRecSize ) { mnRecSize += nRecSize; }
+ /** Sets record ID and size with one call. */
+ void SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize );
+
+ /** Writes the record header and calls WriteBody(). */
+ virtual void Save( XclExpStream& rStrm );
+
+protected:
+ /** Writes the body of the record (without record header).
+ @descr Usually this method will be overwritten by derived classes. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_Size mnRecSize; /// The predicted record size.
+ sal_uInt16 mnRecId; /// The record ID.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A record without body. Only the record ID and the size 0 will be written. */
+class XclExpEmptyRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record. */
+ inline explicit XclExpEmptyRecord( sal_uInt16 nRecId );
+};
+
+inline XclExpEmptyRecord::XclExpEmptyRecord( sal_uInt16 nRecId ) :
+ XclExpRecord( nRecId, 0 )
+{
+}
+
+// ============================================================================
+
+/** A record with a single value of type Type.
+ @descr Requires operator<<( XclExpStream&, const Type& ). */
+template< typename Type >
+class XclExpValueRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param rValue The value for the record body.
+ @param nSize Record size. Uses sizeof( Type ), if this parameter is omitted. */
+ inline explicit XclExpValueRecord( sal_uInt16 nRecId, const Type& rValue, sal_Size nSize = sizeof( Type ) ) :
+ XclExpRecord( nRecId, nSize ), maValue( rValue ), mnAttribute( -1 ) {}
+
+ /** Returns the value of the record. */
+ inline const Type& GetValue() const { return maValue; }
+ /** Sets a new record value. */
+ inline void SetValue( const Type& rValue ) { maValue = rValue; }
+
+ /** Sets the OOXML attribute this record corresponds to */
+ XclExpValueRecord* SetAttribute( sal_Int32 nId );
+
+ /** Write the OOXML attribute and its value */
+ void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ inline virtual void WriteBody( XclExpStream& rStrm ) { rStrm << maValue; }
+ // inlining prevents warning in wntmsci10
+
+private:
+ Type maValue; /// The record data.
+ sal_Int32 mnAttribute; /// The OOXML attribute Id
+};
+
+template< typename Type >
+void XclExpValueRecord< Type >::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( mnAttribute == -1 )
+ return;
+ rStrm.WriteAttributes(
+ mnAttribute, rtl::OString::valueOf( (sal_Int32) maValue ).getStr(),
+ FSEND );
+}
+
+template<>
+void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm );
+
+template< typename Type >
+XclExpValueRecord< Type >* XclExpValueRecord< Type >::SetAttribute( sal_Int32 nId )
+{
+ mnAttribute = nId;
+ return this;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A record containing an unsigned 16-bit value. */
+typedef XclExpValueRecord< sal_uInt16 > XclExpUInt16Record;
+
+/** A record containing an unsigned 32-bit value. */
+typedef XclExpValueRecord< sal_uInt32 > XclExpUInt32Record;
+
+/** A record containing a double value. */
+typedef XclExpValueRecord< double > XclExpDoubleRecord;
+
+// ----------------------------------------------------------------------------
+
+/** Record which contains a Boolean value.
+ @descr The value is stored as 16-bit value: 0x0000 = sal_False, 0x0001 = TRUE. */
+class XclExpBoolRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param nValue The value for the record body. */
+ inline explicit XclExpBoolRecord( sal_uInt16 nRecId, bool bValue, sal_Int32 nAttribute = -1 ) :
+ XclExpRecord( nRecId, 2 ), mbValue( bValue ), mnAttribute( nAttribute ) {}
+
+ /** Returns the Boolean value of the record. */
+ inline bool GetBool() const { return mbValue; }
+ /** Sets a new Boolean record value. */
+ inline void SetBool( bool bValue ) { mbValue = bValue; }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ bool mbValue; /// The record data.
+ sal_Int32 mnAttribute; /// The attribute to generate within SaveXml()
+};
+
+// ----------------------------------------------------------------------------
+
+/** Record which exports a memory data array. */
+class XclExpDummyRecord : public XclExpRecord
+{
+public:
+ /** @param nRecId The record ID of this record.
+ @param pRecData Pointer to the data array representing the record body.
+ @param nRecSize Size of the data array. */
+ explicit XclExpDummyRecord(
+ sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize );
+
+ /** Sets a data array. */
+ void SetData( const void* pRecData, sal_Size nRecSize );
+
+private:
+ /** Writes the body of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const void* mpData; /// The record data.
+};
+
+// Future records =============================================================
+
+class XclExpFutureRecord : public XclExpRecord
+{
+public:
+ explicit XclExpFutureRecord( XclFutureRecType eRecType,
+ sal_uInt16 nRecId, sal_Size nRecSize = 0 );
+
+ /** Writes the extended record header and calls WriteBody(). */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ XclFutureRecType meRecType;
+};
+
+// List of records ============================================================
+
+/** A list of Excel record objects.
+
+ Provides saving the compete list. This class is derived from
+ XclExpRecordBase, so it can be used as record in another record list.
+ Requires RecType::Save( XclExpStream& ).
+ */
+template< typename RecType = XclExpRecordBase >
+class XclExpRecordList : public XclExpRecordBase
+{
+public:
+ typedef boost::shared_ptr< RecType > RecordRefType;
+
+ /** Returns pointer to an existing record or 0 on error. */
+ inline bool IsEmpty() const { return maRecs.empty(); }
+ /** Returns pointer to an existing record or 0 on error. */
+ inline size_t GetSize() const { return maRecs.size(); }
+
+ /** Returns true, if the passed index points to an exiting record. */
+ inline bool HasRecord( size_t nPos ) const
+ { return nPos < maRecs.size(); }
+ /** Returns reference to an existing record or empty reference on error. */
+ inline RecordRefType GetRecord( size_t nPos ) const
+ { return (nPos < maRecs.size()) ? maRecs[ nPos ] : RecordRefType(); }
+ /** Returns reference to the first existing record or empty reference, if list is empty. */
+ inline RecordRefType GetFirstRecord() const
+ { return maRecs.empty() ? RecordRefType() : maRecs.front(); }
+ /** Returns reference to the last existing record or empty reference, if list is empty. */
+ inline RecordRefType GetLastRecord() const
+ { return maRecs.empty() ? RecordRefType() : maRecs.back(); }
+
+ /** Inserts a record at the specified position into the list. */
+ inline void InsertRecord( RecordRefType xRec, size_t nPos )
+ { if( xRec.get() ) maRecs.insert( maRecs.begin() + ::std::min( nPos, maRecs.size() ), xRec ); }
+ /** Appends a record to the list. */
+ inline void AppendRecord( RecordRefType xRec )
+ { if( xRec.get() ) maRecs.push_back( xRec ); }
+ /** Replaces the record at the specified position from the list with the passed record. */
+ inline void ReplaceRecord( RecordRefType xRec, size_t nPos )
+ { RemoveRecord( nPos ); InsertRecord( xRec, nPos ); }
+
+ /** Inserts a newly created record at the specified position into the list. */
+ inline void InsertNewRecord( RecType* pRec, size_t nPos )
+ { if( pRec ) InsertRecord( RecordRefType( pRec ), nPos ); }
+ /** Appends a newly created record to the list. */
+ inline void AppendNewRecord( RecType* pRec )
+ { if( pRec ) AppendRecord( RecordRefType( pRec ) ); }
+ /** Replaces the record at the specified position from the list with the passed newly created record. */
+ inline void ReplaceNewRecord( RecType* pRec, size_t nPos )
+ { RemoveRecord( nPos ); InsertNewRecord( pRec, nPos ); }
+
+ /** Removes the record at the specified position from the list. */
+ inline void RemoveRecord( size_t nPos )
+ { if( nPos < maRecs.size() ) maRecs.erase( maRecs.begin() + nPos ); }
+ /** Removes all records from the list. */
+ inline void RemoveAllRecords() { maRecs.clear(); }
+
+ /** Writes the complete record list. */
+ inline virtual void Save( XclExpStream& rStrm )
+ {
+ // inlining prevents warning in wntmsci10
+ for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
+ (*aIt)->Save( rStrm );
+ }
+
+ inline virtual void SaveXml( XclExpXmlStream& rStrm )
+ {
+ // inlining prevents warning in wntmsci10
+ for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
+ (*aIt)->SaveXml( rStrm );
+ }
+
+private:
+ typedef ::std::vector< RecordRefType > RecordVec;
+ RecordVec maRecs;
+};
+
+// ============================================================================
+
+/** Represents a complete substream of records enclosed into a pair of BOF/EOF records. */
+class XclExpSubStream : public XclExpRecordList<>
+{
+public:
+ explicit XclExpSubStream( sal_uInt16 nSubStrmType );
+
+ /** Writes the complete substream, including leading BOF and trailing EOF. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnSubStrmType; /// Substream type, stored in leading BOF record.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx
new file mode 100644
index 000000000000..f27546eb219e
--- /dev/null
+++ b/sc/source/filter/inc/xeroot.hxx
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEROOT_HXX
+#define SC_XEROOT_HXX
+
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include "xlroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Forward declarations of objects in public use ==============================
+
+class XclExpStream;
+class XclExpRecordBase;
+class XclExpString;
+
+typedef boost::shared_ptr< XclExpRecordBase > XclExpRecordRef;
+typedef boost::shared_ptr< XclExpString > XclExpStringRef;
+
+// Global data ================================================================
+
+class XclExpTabInfo;
+class XclExpAddressConverter;
+class XclExpFormulaCompiler;
+class XclExpProgressBar;
+class XclExpSst;
+class XclExpPalette;
+class XclExpFontBuffer;
+class XclExpNumFmtBuffer;
+class XclExpXFBuffer;
+class XclExpLinkManager;
+class XclExpNameManager;
+class XclExpObjectManager;
+class XclExpFilterManager;
+class XclExpPivotTableManager;
+
+/** Stores global buffers and data needed for Excel export filter. */
+struct XclExpRootData : public XclRootData
+{
+ typedef boost::shared_ptr< XclExpTabInfo > XclExpTabInfoRef;
+ typedef boost::shared_ptr< XclExpAddressConverter > XclExpAddrConvRef;
+ typedef boost::shared_ptr< XclExpFormulaCompiler > XclExpFmlaCompRef;
+ typedef boost::shared_ptr< XclExpProgressBar > XclExpProgressRef;
+
+ typedef boost::shared_ptr< XclExpSst > XclExpSstRef;
+ typedef boost::shared_ptr< XclExpPalette > XclExpPaletteRef;
+ typedef boost::shared_ptr< XclExpFontBuffer > XclExpFontBfrRef;
+ typedef boost::shared_ptr< XclExpNumFmtBuffer > XclExpNumFmtBfrRef;
+ typedef boost::shared_ptr< XclExpXFBuffer > XclExpXFBfrRef;
+ typedef boost::shared_ptr< XclExpNameManager > XclExpNameMgrRef;
+ typedef boost::shared_ptr< XclExpLinkManager > XclExpLinkMgrRef;
+ typedef boost::shared_ptr< XclExpObjectManager > XclExpObjectMgrRef;
+ typedef boost::shared_ptr< XclExpFilterManager > XclExpFilterMgrRef;
+ typedef boost::shared_ptr< XclExpPivotTableManager > XclExpPTableMgrRef;
+
+ XclExpTabInfoRef mxTabInfo; /// Calc->Excel sheet index conversion.
+ XclExpAddrConvRef mxAddrConv; /// The address converter.
+ XclExpFmlaCompRef mxFmlaComp; /// The formula compiler.
+ XclExpProgressRef mxProgress; /// The export progress bar.
+
+ XclExpSstRef mxSst; /// The shared string table.
+ XclExpPaletteRef mxPalette; /// The color buffer.
+ XclExpFontBfrRef mxFontBfr; /// All fonts in the file.
+ XclExpNumFmtBfrRef mxNumFmtBfr; /// All number formats in the file.
+ XclExpXFBfrRef mxXFBfr; /// All XF records in the file.
+ XclExpNameMgrRef mxNameMgr; /// Internal defined names.
+ XclExpLinkMgrRef mxGlobLinkMgr; /// Global link manager for defined names.
+ XclExpLinkMgrRef mxLocLinkMgr; /// Local link manager for a sheet.
+ XclExpObjectMgrRef mxObjMgr; /// All drawing objects.
+ XclExpFilterMgrRef mxFilterMgr; /// Manager for filtered areas in all sheets.
+ XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
+
+ bool mbRelUrl; /// true = Store URLs relative.
+
+ explicit XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc );
+ virtual ~XclExpRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Access to global data from other classes. */
+class XclExpRoot : public XclRoot
+{
+public:
+ explicit XclExpRoot( XclExpRootData& rExpRootData );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclExpRoot& GetRoot() const { return *this; }
+ /** Returns true, if URLs should be stored relative to the document location. */
+ inline bool IsRelUrl() const { return mrExpData.mbRelUrl; }
+
+ /** Returns the buffer for Calc->Excel sheet index conversion. */
+ XclExpTabInfo& GetTabInfo() const;
+ /** Returns the address converter. */
+ XclExpAddressConverter& GetAddressConverter() const;
+ /** Returns the formula compiler to produce formula token arrays. */
+ XclExpFormulaCompiler& GetFormulaCompiler() const;
+ /** Returns the export progress bar. */
+ XclExpProgressBar& GetProgressBar() const;
+
+ /** Returns the shared string table. */
+ XclExpSst& GetSst() const;
+ /** Returns the color buffer. */
+ XclExpPalette& GetPalette() const;
+ /** Returns the font buffer. */
+ XclExpFontBuffer& GetFontBuffer() const;
+ /** Returns the number format buffer. */
+ XclExpNumFmtBuffer& GetNumFmtBuffer() const;
+ /** Returns the cell formatting attributes buffer. */
+ XclExpXFBuffer& GetXFBuffer() const;
+ /** Returns the global link manager for defined names. */
+ XclExpLinkManager& GetGlobalLinkManager() const;
+ /** Returns the local link manager for the current sheet. */
+ XclExpLinkManager& GetLocalLinkManager() const;
+ /** Returns the buffer that contains internal defined names. */
+ XclExpNameManager& GetNameManager() const;
+ /** Returns the drawing object manager. */
+ XclExpObjectManager& GetObjectManager() const;
+ /** Returns the filter manager. */
+ XclExpFilterManager& GetFilterManager() const;
+ /** Returns the pivot table manager. */
+ XclExpPivotTableManager& GetPivotTableManager() const;
+
+ /** Is called when export filter starts to create the Excel document (all BIFF versions). */
+ void InitializeConvert();
+ /** Is called when export filter starts to create the workbook global data (>=BIFF5). */
+ void InitializeGlobals();
+ /** Is called when export filter starts to create data for a single sheet (all BIFF versions). */
+ void InitializeTable( SCTAB nScTab );
+ /** Is called before export filter starts to write the records to the stream. */
+ void InitializeSave();
+ /** Returns the reference to a record (or record list) representing a root object.
+ @param nRecId Identifier that specifies which record is returned. */
+ XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+
+ bool IsDocumentEncrypted() const;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateEncryptionData( const ::rtl::OUString& aPass ) const;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData() const;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateDefaultEncryptionData() const;
+
+private:
+
+ /** Returns the local or global link manager, depending on current context. */
+ XclExpRootData::XclExpLinkMgrRef GetLocalLinkMgrRef() const;
+
+private:
+ XclExpRootData& mrExpData; /// Reference to the global export data struct.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
new file mode 100644
index 000000000000..0af3d7227779
--- /dev/null
+++ b/sc/source/filter/inc/xestream.hxx
@@ -0,0 +1,361 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef SC_XESTREAM_HXX
+#define SC_XESTREAM_HXX
+
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <map>
+#include <stack>
+#include <string>
+
+#include <oox/core/xmlfilterbase.hxx>
+#include <oox/token/tokens.hxx>
+#include <sax/fshelper.hxx>
+
+#include "xlstream.hxx"
+#include "xestring.hxx"
+
+#include <filter/msfilter/mscodec.hxx>
+#include <vector>
+
+/* ============================================================================
+Output stream class for Excel export
+- CONTINUE record handling
+- ByteString and UniString support
+============================================================================ */
+
+class XclExpRoot;
+class XclExpBiff8Encrypter;
+typedef boost::shared_ptr< XclExpBiff8Encrypter > XclExpEncrypterRef;
+
+/** This class is used to export Excel record streams.
+ @descr An instance is constructed with an SvStream and the maximum size of Excel
+ record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes).
+
+ To start writing a record call StartRecord(). Parameters are the record identifier
+ and any calculated record size. This is for optimizing the write process: if the real
+ written data has the same size as the calculated, the stream will not seek back and
+ update the record size field. But it is not mandatory to calculate a size. Each
+ record must be closed by calling EndRecord(). This will check (and update) the record
+ size field.
+
+ If some data exceeds the record size limit, a CONTINUE record is started automatically
+ and the new data will be written to this record.
+
+ If specific data pieces must not be splitted, use SetSliceLen(). For instance:
+ To write a sequence of 16-bit values, where 4 values form a unit and cannot be
+ split, call SetSliceLen( 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. This function is used
+ for instance from the class XclExpString which can write complete unicode strings.
+*/
+class XclExpStream
+{
+public:
+ /** Constructs the Excel record export stream.
+ @param rOutStrm The system output stream to write to.
+ @param nMaxRecSize The maximum allowed size of record content (depending on BIFF type).
+ If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */
+ XclExpStream(
+ SvStream& rOutStrm,
+ const XclExpRoot& rRoot,
+ sal_uInt16 nMaxRecSize = 0 );
+
+ ~XclExpStream();
+
+ /** Returns the filter root data. */
+ inline const XclExpRoot& GetRoot() const { return mrRoot; }
+
+ /** Starts a new record: writes header data, stores calculated record size. */
+ void StartRecord( sal_uInt16 nRecId, sal_Size nRecSize );
+ /** Checks and corrects real record length. Must be called everytime a record is finished. */
+ void EndRecord();
+
+ /** Returns the position inside of current record (starts by 0 in every CONTINUE). */
+ inline sal_uInt16 GetRawRecPos() const { return mnCurrSize; }
+
+ /** Returns the maximum size of a record. */
+ inline sal_uInt16 GetMaxRecSize() const { return mnMaxRecSize; }
+ /** Sets maximum record size (valid only for current record). */
+ inline void SetMaxRecSize( sal_uInt16 nMax ) { mnCurrMaxSize = nMax; }
+ /** Sets maximum size of CONTINUE records (valid only for current record). */
+ inline void SetMaxContSize( sal_uInt16 nMax ) { mnMaxContSize = nMax; }
+
+ /** Sets data slice length. 0 = no slices. */
+ void SetSliceSize( sal_uInt16 nSize );
+
+ XclExpStream& operator<<( sal_Int8 nValue );
+ XclExpStream& operator<<( sal_uInt8 nValue );
+ XclExpStream& operator<<( sal_Int16 nValue );
+ XclExpStream& operator<<( sal_uInt16 nValue );
+ XclExpStream& operator<<( sal_Int32 nValue );
+ XclExpStream& operator<<( sal_uInt32 nValue );
+ XclExpStream& operator<<( float fValue );
+ XclExpStream& operator<<( double fValue );
+
+ /** Writes nBytes bytes from memory. */
+ sal_Size Write( const void* pData, sal_Size nBytes );
+ /** Writes a sequence of nBytes zero bytes (respects slice setting). */
+ void WriteZeroBytes( sal_Size nBytes );
+
+ void WriteZeroBytesToRecord( sal_Size nBytes );
+
+ /** Copies nBytes bytes from current position of the stream rInStrm.
+ @descr Omitting the second parameter means: read to end of stream. */
+ sal_Size CopyFromStream( SvStream& rInStrm, sal_Size nBytes = STREAM_SEEK_TO_END );
+
+ // *** unicode string export is realized with helper class XclExpString ***
+ // (slice length setting has no effect here -> disabled automatically)
+
+ /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
+ void WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags );
+
+ // *** write 8-bit-strings ***
+ // (slice length setting has no effect here -> disabled automatically)
+
+ /** Writes string length field and ByteString buffer. */
+ void WriteByteString(
+ const ByteString& rString,
+ sal_uInt16 nMaxLen = 0x00FF,
+ bool b16BitCount = false );
+
+ /** Writes 8-bit character buffer. */
+ void WriteCharBuffer( const ScfUInt8Vec& rBuffer );
+
+ // *** SvStream access ***
+
+ /** Sets position of system stream (only allowed outside of records). */
+ sal_Size SetSvStreamPos( sal_Size nPos );
+ /** Returns the absolute position of the system stream. */
+ inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); }
+
+ void SetEncrypter( XclExpEncrypterRef xEncrypter );
+
+ bool HasValidEncrypter() const;
+
+ void EnableEncryption( bool bEnable = true );
+
+ void DisableEncryption();
+
+private:
+ /** Writes header data, internal setup. */
+ void InitRecord( sal_uInt16 nRecId );
+ /** Rewrites correct record length, if different from calculated. */
+ void UpdateRecSize();
+ /** Recalculates mnCurrSize and mnSliceSize. */
+ void UpdateSizeVars( sal_Size nSize );
+ /** Writes CONTINUE header, internal setup. */
+ void StartContinue();
+ /** Refreshes counter vars, creates CONTINUE records. */
+ void PrepareWrite( sal_uInt16 nSize );
+ /** Creates CONTINUE record at end of record.
+ @return Maximum data block size remaining. */
+ sal_uInt16 PrepareWrite();
+
+ /** Writes a raw sequence of zero bytes. */
+ void WriteRawZeroBytes( sal_Size nBytes );
+
+private:
+ SvStream& mrStrm; /// Reference to the system output stream.
+ const XclExpRoot& mrRoot; /// Filter root data.
+
+ bool mbUseEncrypter;
+ XclExpEncrypterRef mxEncrypter;
+
+ // length data
+ sal_uInt16 mnMaxRecSize; /// Maximum size of record content.
+ sal_uInt16 mnMaxContSize; /// Maximum size of CONTINUE content.
+ sal_uInt16 mnCurrMaxSize; /// Current maximum, either mnMaxRecSize or mnMaxContSize.
+ sal_uInt16 mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split).
+ sal_uInt16 mnHeaderSize; /// Record size written in last record header.
+ sal_uInt16 mnCurrSize; /// Count of bytes already written in current record.
+ sal_uInt16 mnSliceSize; /// Count of bytes already written in current slice.
+ sal_Size mnPredictSize; /// Predicted size received from calling function.
+
+ // stream position data
+ sal_Size mnLastSizePos; /// Stream position of size field in current header.
+ bool mbInRec; /// true = currently writing inside of a record.
+};
+
+// ============================================================================
+
+class XclExpBiff8Encrypter
+{
+public:
+ explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot );
+ ~XclExpBiff8Encrypter();
+
+ bool IsValid() const;
+
+ void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const;
+ void GetSalt( sal_uInt8 pnSalt[16] ) const;
+ void GetDocId( sal_uInt8 pnDocId[16] ) const;
+
+ void Encrypt( SvStream& rStrm, sal_uInt8 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt16 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt32 nData );
+
+ void Encrypt( SvStream& rStrm, sal_Int8 nData );
+ void Encrypt( SvStream& rStrm, sal_Int16 nData );
+ void Encrypt( SvStream& rStrm, sal_Int32 nData );
+
+ void Encrypt( SvStream& rStrm, float fValue );
+ void Encrypt( SvStream& rStrm, double fValue );
+
+ void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes );
+
+private:
+ void Init( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData );
+
+ sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const;
+ sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const;
+
+private:
+ ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation.
+ sal_uInt8 mpnDocId[16];
+ sal_uInt8 mpnSalt[16];
+ sal_uInt8 mpnSaltDigest[16];
+
+ const XclExpRoot& mrRoot;
+ sal_Size mnOldPos; /// Last known stream position
+ bool mbValid;
+};
+
+// ----------------------------------------------------------------------------
+
+
+// ============================================================================
+
+// `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
+#define XESTRING_TO_PSZ(s) \
+ (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
+
+class ScAddress;
+class ScDocShell;
+class ScDocument;
+class ScFormulaCell;
+class ScRange;
+class ScRangeList;
+class ScTokenArray;
+struct XclAddress;
+struct XclFontData;
+struct XclRange;
+class XclRangeList;
+
+class XclXmlUtils
+{
+ XclXmlUtils();
+ ~XclXmlUtils();
+ XclXmlUtils(const XclXmlUtils&);
+ XclXmlUtils& operator=(const XclXmlUtils&);
+public:
+ static void GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& sType, ::rtl::OUString& rValue);
+ static ::rtl::OUString GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId );
+
+ static ::rtl::OString ToOString( const Color& rColor );
+ static ::rtl::OString ToOString( const ::rtl::OUString& s );
+ static ::rtl::OString ToOString( const ScfUInt16Vec& rBuffer );
+ static ::rtl::OString ToOString( const String& s );
+ static ::rtl::OString ToOString( const ScAddress& rRange );
+ static ::rtl::OString ToOString( const ScRange& rRange );
+ static ::rtl::OString ToOString( const ScRangeList& rRangeList );
+ static ::rtl::OString ToOString( const XclAddress& rAddress );
+ static ::rtl::OString ToOString( const XclExpString& s );
+ static ::rtl::OString ToOString( const XclRange& rRange );
+ static ::rtl::OString ToOString( const XclRangeList& rRangeList );
+
+ static ::rtl::OUString ToOUString( const char* s );
+ static ::rtl::OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
+ static ::rtl::OUString ToOUString( const String& s );
+ static ::rtl::OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray );
+ static ::rtl::OUString ToOUString( const XclExpString& s );
+ static const char* ToPsz( bool b );
+
+ static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue );
+ static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue );
+ static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue );
+ static sax_fastparser::FSHelperPtr WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nNameId );
+};
+
+class XclExpXmlStream : public oox::core::XmlFilterBase
+{
+public:
+ XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rCC );
+ virtual ~XclExpXmlStream();
+
+ /** Returns the filter root data. */
+ inline const XclExpRoot& GetRoot() const { return *mpRoot; }
+
+ sax_fastparser::FSHelperPtr& GetCurrentStream();
+ void PushStream( sax_fastparser::FSHelperPtr aStream );
+ void PopStream();
+
+ sax_fastparser::FSHelperPtr GetStreamForPath( const ::rtl::OUString& rPath );
+
+ sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, ... );
+
+ sax_fastparser::FSHelperPtr CreateOutputStream (
+ const ::rtl::OUString& sFullStream,
+ const ::rtl::OUString& sRelativeStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation,
+ const char* sContentType,
+ const char* sRelationshipType,
+ ::rtl::OUString* pRelationshipId = NULL );
+
+ // ignore
+ virtual bool exportDocument() throw();
+
+ // only needed for import; ignore
+ virtual bool importDocument() throw();
+ virtual oox::vml::Drawing* getVmlDrawing();
+ virtual const oox::drawingml::Theme* getCurrentTheme() const;
+ virtual const oox::drawingml::table::TableStyleListPtr getTableStyles();
+ virtual oox::drawingml::chart::ChartConverter& getChartConverter();
+
+private:
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const;
+ virtual ::rtl::OUString implGetImplementationName() const;
+ ScDocShell *getDocShell();
+
+ typedef std::map< ::rtl::OUString,
+ std::pair< ::rtl::OUString,
+ sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap;
+
+ const XclExpRoot* mpRoot;
+ std::stack< sax_fastparser::FSHelperPtr > maStreams;
+ XclExpXmlPathToStateMap maOpenedStreamMap;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xestring.hxx b/sc/source/filter/inc/xestring.hxx
new file mode 100644
index 000000000000..abc6f331aa1b
--- /dev/null
+++ b/sc/source/filter/inc/xestring.hxx
@@ -0,0 +1,301 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XESTRING_HXX
+#define SC_XESTRING_HXX
+
+#include "xlstring.hxx"
+
+// ============================================================================
+
+class ScEditCell;
+class ScPatternAttr;
+class EditTextObject;
+class XclExpStream;
+class XclExpXmlStream;
+
+/** This class stores an unformatted or formatted string for Excel export.
+
+ The class supports two completely different types of Excel strings:
+ 1) BIFF2-BIFF7 byte strings: The text is encoded as a 8-bit character
+ array. The strings cannot contain any character formatting.
+ 2) BIFF8 Unicode strings: The text may be stored as UCS-2 character array,
+ or compressed to an 8-bit array, if all characters are less than
+ U+0100. Unicode strings may contain a formatting array, that specifies
+ the used FONT record for different ranges of characters.
+
+ The class provides full support for NUL characters in strings. On
+ construction or assignment the passed flags specify the behaviour of the
+ string while it is written to a stream (the 'Write' functions and
+ 'operator<<').
+ */
+class XclExpString
+{
+public:
+ // constructors -----------------------------------------------------------
+
+ /** Constructs an empty BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Constructs an unformatted BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+ /** Constructs an unformatted BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ explicit XclExpString(
+ const ::rtl::OUString& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ // assign -----------------------------------------------------------------
+
+ /** Assigns an unformatted string, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const String& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Assigns an unformatted string, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void Assign(
+ const ::rtl::OUString& rString,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Assigns a Unicode character, converts this object to a BIFF8 Unicode string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string (for appending). */
+ void Assign(
+ sal_Unicode cChar,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ /** Assigns an unformatted string, converts this object to a BIFF2-BIFF7 byte string.
+ @param nFlags Modifiers for string export.
+ @param nMaxLen The maximum number of characters to store in this string. */
+ void AssignByte(
+ const String& rString,
+ rtl_TextEncoding eTextEnc,
+ XclStrFlags nFlags = EXC_STR_DEFAULT,
+ sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
+
+ // append -----------------------------------------------------------------
+
+ /** Appends a string. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF8 Unicode string. */
+ void Append( const String& rString );
+
+ /** Appends a string. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF2-BIFF7 byte string. */
+ void AppendByte( const String& rString, rtl_TextEncoding eTextEnc );
+ /** Appends a character. Uses the string flags used in constructor or last Assign().
+ @descr This object must be a BIFF2-BIFF7 byte string. */
+ void AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc );
+
+ // formatting runs --------------------------------------------------------
+
+ /** Sets new formatting runs for the current text. */
+ void SetFormats( const XclFormatRunVec& rFormats );
+ /** Appends a formatting run. nChar must be greater than last contained character index. */
+ void AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate = true );
+ /** Appends a trailing formatting run with the passed font index. */
+ void AppendTrailingFormat( sal_uInt16 nFontIdx );
+ /** Removes formatting runs at the end, if the string contains too much. */
+ void LimitFormatCount( sal_uInt16 nMaxCount );
+ /** Removes and returns the font index for the first char from the formatting runs, otherwise EXC_FONT_NOTFOUND. */
+ sal_uInt16 RemoveLeadingFont();
+
+ // get data ---------------------------------------------------------------
+
+ /** Returns the character count of the string. */
+ inline sal_uInt16 Len() const { return mnLen; }
+ /** Returns true, if the string is empty. */
+ inline bool IsEmpty() const { return mnLen == 0; }
+ /** Returns true, if the string contains line breaks. */
+ inline bool IsWrapped() const { return mbWrapped; }
+ /** Returns true, if this string is equal to the passed string. */
+ bool IsEqual( const XclExpString& rCmp ) const;
+ /** Returns true, if this string is less than the passed string. */
+ bool IsLessThan( const XclExpString& rCmp ) const;
+
+ /** Returns true, if the string contains formatting information. */
+ inline bool IsRich() const { return !maFormats.empty(); }
+ /** Returns the current count of formatting runs for rich strings. */
+ sal_uInt16 GetFormatsCount() const;
+ /** Returns the vector with all formatting runs. */
+ inline const XclFormatRunVec& GetFormats() const { return maFormats; }
+
+ /** Returns the current string flags field to export. */
+ sal_uInt8 GetFlagField() const;
+ /** Returns the byte count the header will take on export. */
+ sal_uInt16 GetHeaderSize() const;
+ /** Returns the byte count the character buffer will take on export. */
+ sal_Size GetBufferSize() const;
+ /** Returns the byte count the whole string will take on export. */
+ sal_Size GetSize() const;
+
+ /** Returns the specified character from the (already encoded) string. */
+ sal_uInt16 GetChar( sal_uInt16 nCharIdx ) const;
+ /** Returns a hash value for the string. */
+ sal_uInt16 GetHash() const;
+
+ const ScfUInt16Vec& GetUnicodeBuffer() const { return maUniBuffer; }
+
+ // streaming --------------------------------------------------------------
+
+ /** Writes the string length field (1 byte or 2 bytes). */
+ void WriteLenField( XclExpStream& rStrm ) const;
+ /** Writes the string flags field (1 byte). */
+ void WriteFlagField( XclExpStream& rStrm ) const;
+ /** Writes 8-bit or 16-bit length field and string flags field. */
+ void WriteHeader( XclExpStream& rStrm ) const;
+ /** Writes the raw character buffer. */
+ void WriteBuffer( XclExpStream& rStrm ) const;
+ /** Writes the raw formatting run buffer. */
+ void WriteFormats( XclExpStream& rStrm, bool bWriteSize = false ) const;
+ /** Writes the complete Unicode string. */
+ void Write( XclExpStream& rStrm ) const;
+
+ /** Writes the string header to memory. */
+ void WriteHeaderToMem( sal_uInt8* pnMem ) const;
+ /** Writes the raw character buffer to memory (8-bit or 16-bit little-endian). */
+ void WriteBufferToMem( sal_uInt8* pnMem ) const;
+ /** Writes the entire string to memory. */
+ void WriteToMem( sal_uInt8* pnMem ) const;
+
+ void WriteXml( XclExpXmlStream& rStrm ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Returns true, if the flag field should be written. */
+ bool IsWriteFlags() const;
+ /** Returns true, if the formatting run vector should be written. */
+ bool IsWriteFormats() const;
+
+ /** Sets the string length but regards the limit given in mnMaxLen. */
+ void SetStrLen( sal_Int32 nNewLen );
+ /** Inserts the passed character array into the internal character buffer.
+ @param nBegin First index in internal buffer to fill.
+ @param nLen Number of characters to insert. */
+ void CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen );
+ /** Inserts the passed character array into the internal character buffer.
+ @param nBegin First index in internal buffer to fill.
+ @param nLen Number of characters to insert. */
+ void CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen );
+
+ /** Initializes flags, string length, and resizes character buffer.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The requested number of characters for the string.
+ @param nMaxLen The maximum length allowed of the resulting string.
+ @param bBiff8 true = BIFF8 Unicode string; false = BIFF2-BIFF7 byte string. */
+ void Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 );
+ /** Creates the character buffer from the given Unicode array.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The real count of characters contained in the passed buffer.
+ @param nMaxLen The maximum length allowed of the resulting string. */
+ void Build(
+ const sal_Unicode* pcSource, sal_Int32 nCurrLen,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen );
+ /** Creates the character buffer from the given character array.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nFlags Modifiers for string export.
+ @param nCurrLen The real count of characters contained in the passed buffer.
+ @param nMaxLen The maximum length allowed of the resulting string. */
+ void Build(
+ const sal_Char* pcSource, sal_Int32 nCurrLen,
+ XclStrFlags nFlags, sal_uInt16 nMaxLen );
+
+ /** Initializes string length and resizes character buffers for appending operation.
+ @param nAddLen The number of characters to be appended. */
+ void InitAppend( sal_Int32 nAddLen );
+ /** Appends the given Unicode array to the character buffer.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nAddLen The real count of characters contained in the passed buffer. */
+ void BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen );
+ /** Appends the given character array to the character buffer.
+ @param pcSource The source character buffer. Trailing NUL character is not necessary.
+ @param nAddLen The real count of characters contained in the passed buffer. */
+ void BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen );
+
+ /** Initializes write process on stream. */
+ void PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const;
+
+private:
+ ScfUInt16Vec maUniBuffer; /// The Unicode character buffer.
+ ScfUInt8Vec maCharBuffer; /// The byte character buffer.
+ XclFormatRunVec maFormats; /// All formatting runs.
+ sal_uInt16 mnLen; /// Character count to export.
+ sal_uInt16 mnMaxLen; /// Maximum allowed number of characters.
+ bool mbIsBiff8; /// true = BIFF8 Unicode string, false = BIFF2-7 bytestring.
+ bool mbIsUnicode; /// true, if at least one character is >0xFF.
+ bool mb8BitLen; /// true = write 8-bit string length; false = 16-bit.
+ bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags.
+ bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string.
+ bool mbWrapped; /// true = text contains several paragraphs.
+ bool mbSkipHeader; /// ture = skip length and flags when writing string bytes.
+};
+
+inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return rLeft.IsEqual( rRight );
+}
+
+inline bool operator!=( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return !(rLeft == rRight);
+}
+
+inline bool operator<( const XclExpString& rLeft, const XclExpString& rRight )
+{
+ return rLeft.IsLessThan( rRight );
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclExpString& rString )
+{
+ rString.Write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx
new file mode 100644
index 000000000000..8f38b6f13352
--- /dev/null
+++ b/sc/source/filter/inc/xestyle.hxx
@@ -0,0 +1,742 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XESTYLE_HXX
+#define SC_XESTYLE_HXX
+
+#include <map>
+#include <tools/mempool.hxx>
+#include <tools/string.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/nfkeytab.hxx>
+#include <editeng/svxfont.hxx>
+#include "xerecord.hxx"
+#include "xlstyle.hxx"
+#include "xeroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+/* ============================================================================
+- Buffers for style records (PALETTE, FONT, FORMAT, XF, STYLE).
+============================================================================ */
+
+const sal_uInt16 EXC_ID_FONTLIST = 0x8031; /// For internal use only.
+const sal_uInt16 EXC_ID_FORMATLIST = 0x801E; /// For internal use only.
+const sal_uInt16 EXC_ID_XFLIST = 0x8043; /// For internal use only.
+
+// PALETTE record - color information =========================================
+
+/** Different types of colors in a document. */
+enum XclExpColorType
+{
+ EXC_COLOR_CELLTEXT, /// Text in a cell.
+ EXC_COLOR_CELLBORDER, /// Border of a cell.
+ EXC_COLOR_CELLAREA, /// Background area of a cell.
+ EXC_COLOR_CHARTTEXT, /// Text color in a chart.
+ EXC_COLOR_CHARTLINE, /// Line in a chart.
+ EXC_COLOR_CHARTAREA, /// Area in a chart.
+ EXC_COLOR_CTRLTEXT, /// Text color in a form control.
+ EXC_COLOR_GRID, /// Spreadsheet grid color.
+ EXC_COLOR_TABBG /// Spreadsheet tab bg color.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclExpPaletteImpl;
+
+/** Stores all used colors in the document.
+
+ Supports color reduction to the maximum count of the current BIFF version.
+ An instance of this class collects all colors in the conversion phase of
+ the export, using the InsertColor() function. It returns a unique
+ identidier for each passed color.
+
+ After the entire document is converted, the Finalize() function will reduce
+ the palette to the number of colors supported by the current BIFF version.
+
+ Then, in the streaming phase, the functions GetColorIndex() and
+ GetMixedColors() return the real Excel palette index for all color
+ identifiers.
+ */
+class XclExpPalette : public XclDefaultPalette, public XclExpRecord
+{
+public:
+ explicit XclExpPalette( const XclExpRoot& rRoot );
+ virtual ~XclExpPalette();
+
+ /** Inserts the color into the list and updates weighting.
+ @param nAutoDefault The Excel palette index for automatic color.
+ @return A unique ID for this color. */
+ sal_uInt32 InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
+ /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
+ static sal_uInt32 GetColorIdFromIndex( sal_uInt16 nIndex );
+
+ /** Reduces the color list to the maximum count of the current BIFF version. */
+ void Finalize();
+
+ /** Returns the Excel palette index of the color with passed color ID. */
+ sal_uInt16 GetColorIndex( sal_uInt32 nColorId ) const;
+
+ /** Returns a foreground and background color for the two passed color IDs.
+ @descr If rnXclPattern contains a solid pattern, this function tries to find
+ the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
+ This will result in a better approximation to the passed foreground color. */
+ void GetMixedColors(
+ sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
+ sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+
+ /** Saves the PALETTE record, if it differs from the default palette. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the PALETTE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclExpPaletteImpl > XclExpPaletteImplRef;
+ XclExpPaletteImplRef mxImpl;
+};
+
+// FONT record - font information =============================================
+
+class Font;
+class SvxFont;
+
+const size_t EXC_FONTLIST_NOTFOUND = static_cast< size_t >( -1 );
+
+// ----------------------------------------------------------------------------
+
+/** Static helper functions for font export. */
+class XclExpFontHelper
+{
+public:
+ /** Returns the script type of the first font item found in the item set and its parents. */
+ static sal_Int16 GetFirstUsedScript(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet );
+
+ /** Returns a VCL font object filled from the passed item set. */
+ static Font GetFontFromItemSet(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript );
+
+ /** Returns true, if at least one font related item is set in the passed item set.
+ @param bDeep true = Searches in parent item sets too. */
+ static bool CheckItems(
+ const XclExpRoot& rRoot,
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript,
+ bool bDeep );
+
+private:
+ XclExpFontHelper();
+ ~XclExpFontHelper();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores all data of an Excel font and provides export of FONT records. */
+class XclExpFont : public XclExpRecord, protected XclExpRoot
+{
+public:
+ explicit XclExpFont( const XclExpRoot& rRoot,
+ const XclFontData& rFontData, XclExpColorType eColorType );
+
+ /** Returns read-only access to font data. */
+ inline const XclFontData& GetFontData() const { return maData; }
+ /** Returns the font color identifier. */
+ inline sal_uInt32 GetFontColorId() const { return mnColorId; }
+ /** Compares this font with the passed font data.
+ @param nHash The hash value calculated from the font data. */
+ virtual bool Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the FONT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclFontData maData; /// All font attributes.
+ sal_uInt32 mnColorId; /// Unique color ID for text color.
+ sal_uInt32 mnHash; /// Hash value for fast comparison.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Used as placeholder for font index 4, which is not used in Excel. */
+class XclExpBlindFont : public XclExpFont
+{
+public:
+ explicit XclExpBlindFont( const XclExpRoot& rRoot );
+
+ /** Returns always false to never find this font while searching the font list. */
+ virtual bool Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const;
+
+ /** Skips writing this record. */
+ virtual void Save( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class ScPatternAttr;
+
+/** Stores the data of all fonts used in the document. */
+class XclExpFontBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpFontBuffer( const XclExpRoot& rRoot );
+
+ /** Returns the specified font from font list. */
+ const XclExpFont* GetFont( sal_uInt16 nXclFont ) const;
+ /** Returns the application font data of this file, needed e.g. for column width. */
+ const XclFontData& GetAppFontData() const;
+
+ /** Inserts a new font with the passed font data into the buffer if not present.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const XclFontData& rFontData,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font into the buffer if not present.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const Font& rFont,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the SvxFont into the buffer if not present, e.g. where escapements are used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const SvxFont& rFont,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font contained in the passed item set into the buffer, if not present.
+ @param nScript The script type of the font properties to be used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const SfxItemSet& rItemSet, sal_Int16 nScript,
+ XclExpColorType eColorType, bool bAppFont = false );
+ /** Inserts the font contained in rPattern into the buffer if not present.
+ @param nScript The script type of the font properties to be used.
+ @param bAppFont true = Sets the application font; false = Inserts a new font.
+ @return The resulting Excel font index. */
+ sal_uInt16 Insert( const ScPatternAttr& rPattern, sal_Int16 nScript,
+ XclExpColorType eColorType, bool bAppFont = false );
+
+ /** Writes all FONT records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Initializes the default fonts for the current BIFF version. */
+ void InitDefaultFonts();
+ /** Tries to find the passed font and returns the current list index. */
+ size_t Find( const XclFontData& rFontData );
+
+private:
+ typedef XclExpRecordList< XclExpFont > XclExpFontList;
+ typedef XclExpFontList::RecordRefType XclExpFontRef;
+
+ XclExpFontList maFontList; /// List of all FONT records.
+ size_t mnXclMaxSize; /// Maximum number of fonts.
+};
+
+// FORMAT record - number formats =============================================
+
+/** Stores a core number format index with corresponding Excel format index. */
+struct XclExpNumFmt
+{
+ sal_uLong mnScNumFmt; /// Core index of the number format.
+ sal_uInt16 mnXclNumFmt; /// Resulting Excel format index.
+
+ inline explicit XclExpNumFmt( sal_uLong nScNumFmt, sal_uInt16 nXclNumFmt ) :
+ mnScNumFmt( nScNumFmt ), mnXclNumFmt( nXclNumFmt ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+class SvNumberFormatter;
+
+/** Stores all number formats used in the document. */
+class XclExpNumFmtBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpNumFmtBuffer( const XclExpRoot& rRoot );
+ virtual ~XclExpNumFmtBuffer();
+
+ /** Returns the core index of the current standard number format. */
+ inline sal_uLong GetStandardFormat() const { return mnStdFmt; }
+
+ /** Inserts a number format into the format buffer.
+ @param nScNumFmt The core index of the number format.
+ @return The resulting Excel format index. */
+ sal_uInt16 Insert( sal_uLong nScNumFmt );
+
+ /** Writes all FORMAT records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the FORMAT record with index nXclIx and format string rFormatStr. */
+ void WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const String& rFormatStr );
+ /** Writes the FORMAT record represented by rFormat. */
+ void WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat );
+
+ String GetFormatCode ( const XclExpNumFmt& rFormat );
+
+private:
+ typedef ::std::auto_ptr< SvNumberFormatter > SvNumberFormatterPtr;
+ typedef ::std::vector< XclExpNumFmt > XclExpNumFmtVec;
+
+ SvNumberFormatterPtr mxFormatter; /// Special number formatter for conversion.
+ XclExpNumFmtVec maFormatMap; /// Maps core formats to Excel indexes.
+ NfKeywordTable* mpKeywordTable; /// Replacement table.
+ sal_uLong mnStdFmt; /// Key for standard number format.
+ sal_uInt16 mnXclOffset; /// Offset to first user defined format.
+};
+
+// XF, STYLE record - Cell formatting =========================================
+
+/** Extends the XclCellProt struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellProt : public XclCellProt
+{
+ /** Fills the protection attributes from the passed item set.
+ @return true = At least one protection item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle = false );
+
+ /** Fills the data to the passed fields of a BIFF3-BIFF8 XF record. */
+ void FillToXF3( sal_uInt16& rnProt ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellAlign struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellAlign : public XclCellAlign
+{
+ /** Fills the alignment attributes from the passed item set.
+ @descr Fills only the attributes exported in the passed BIFF version.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ @return true = At least one alignment item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet,
+ bool bForceLineBreak, XclBiff eBiff, bool bStyle = false );
+
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt16& rnAlign ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellBorder struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellBorder : public XclCellBorder
+{
+ sal_uInt32 mnLeftColorId; /// Color ID for left line.
+ sal_uInt32 mnRightColorId; /// Color ID for right line.
+ sal_uInt32 mnTopColorId; /// Color ID for top line.
+ sal_uInt32 mnBottomColorId; /// Color ID for bottom line.
+ sal_uInt32 mnDiagColorId; /// Color ID for diagonal line(s).
+
+ explicit XclExpCellBorder();
+
+ /** Fills the border attributes from the passed item set.
+ @descr Fills only the attributes exported in the passed BIFF version.
+ @return true = At least one border item is set. */
+ bool FillFromItemSet( const SfxItemSet& rItemSet,
+ XclExpPalette& rPalette, XclBiff eBiff, bool bStyle = false );
+ /** Fills the mn***Color base members from the mn***ColorId members. */
+ void SetFinalColors( const XclExpPalette& rPalette );
+
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const;
+
+ /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
+ void FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellArea struct for export.
+ @descr Provides functions to fill from item sets and to fill to Excel record data. */
+struct XclExpCellArea : public XclCellArea
+{
+ sal_uInt32 mnForeColorId; /// Foreground color ID.
+ sal_uInt32 mnBackColorId; /// Background color ID.
+
+ explicit XclExpCellArea();
+
+ /** Fills the area attributes from the passed item set.
+ @return true = At least one area item is set. */
+ bool FillFromItemSet(
+ const SfxItemSet& rItemSet, XclExpPalette& rPalette,
+ bool bStyle = false );
+ /** Fills the mn***Color base members from the mn***ColorId members. */
+ void SetFinalColors( const XclExpPalette& rPalette );
+
+ /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
+ void FillToXF5( sal_uInt32& rnArea ) const;
+ /** Fills the data to the passed fields of a BIFF8 XF record. */
+ void FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const;
+
+ /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
+ void FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const;
+
+ void SaveXml( XclExpXmlStream& rStrm ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A combination of unique XF identifier with real Excel XF index. */
+struct XclExpXFId
+{
+ sal_uInt32 mnXFId; /// Temporary XF identifier.
+ sal_uInt16 mnXFIndex; /// Real Excel XF index.
+
+ explicit XclExpXFId();
+ explicit XclExpXFId( sal_uInt32 nXFId );
+
+ /** Converts the XF identifier in mnXFId to an Excel XF index and stores it in mnXFIndex. */
+ void ConvertXFIndex( const XclExpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxStyleSheetBase;
+
+/** Represents an XF record which contains all formatting data of a cell or cell style. */
+class XclExpXF : public XclXFBase, public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs a cell XF record from the passed Calc cell formatting. */
+ explicit XclExpXF(
+ const XclExpRoot& rRoot,
+ const ScPatternAttr& rPattern,
+ sal_Int16 nScript,
+ sal_uLong nScForceNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND,
+ sal_uInt16 nForceXclFont = EXC_FONT_NOTFOUND,
+ bool bForceLineBreak = false );
+ /** Constructs a style XF record from the passed cell style sheet. */
+ explicit XclExpXF(
+ const XclExpRoot& rRoot,
+ const SfxStyleSheetBase& rStyleSheet );
+
+ /** Returns the cell protection settings of this XF. */
+ const XclExpCellProt& GetProtectionData() const { return maProtection; }
+ /** Returns the alignment settings of this XF. */
+ const XclExpCellAlign& GetAlignmentData() const { return maAlignment; }
+ /** Returns the cell border settings of this XF. */
+ const XclExpCellBorder& GetBorderData() const { return maBorder; }
+ /** Returns the cell fill settings of this XF. */
+ const XclExpCellArea& GetAreaData() const { return maArea; }
+
+ /** Returns true, if this XF record represents the passed cell formatting.
+ @descr Searches for cell XFs only. */
+ bool Equals(
+ const ScPatternAttr& rPattern,
+ sal_uLong nScForceNumFmt,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak ) const;
+
+ /** Returns true, if this XF record represents the passed style.
+ @descr Searches for style XFs only. */
+ bool Equals( const SfxStyleSheetBase& rStyleSheet ) const;
+
+ /** Sets the resulting Excel palette index from all used color IDs (border and area). */
+ void SetFinalColors();
+
+ /** Returns true, if this XF record is completely equal to the passed. */
+ bool Equals( const XclExpXF& rCmpXF ) const;
+
+ void SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+protected:
+ explicit XclExpXF( const XclExpRoot& rRoot, bool bCellXF );
+
+protected: // access for XclExpDefaultXF
+ const SfxItemSet* mpItemSet; /// Pointer to the item set (we do not own it).
+
+ XclExpCellProt maProtection; /// Cell protection flags.
+ XclExpCellAlign maAlignment; /// All alignment attributes.
+ XclExpCellBorder maBorder; /// Border line style.
+ XclExpCellArea maArea; /// Background area style.
+ sal_uInt32 mnParentXFId; /// XF ID of parent XF record.
+ sal_uLong mnScNumFmt; /// Calc number format index.
+ sal_uInt16 mnXclFont; /// Excel font index.
+ sal_uInt16 mnXclNumFmt; /// Excel number format index.
+ sal_Int32 mnBorderId; /// OOXML Border Index
+ sal_Int32 mnFillId; /// OOXML Fill Index
+
+private:
+ using XclXFBase::Equals;
+
+ /** Initializes with default values. */
+ void InitDefault();
+ /** Fills all members from the passed item set.
+ @param bDefStyle true = This is the "Default"/"Normal" style - needs special handling. */
+ void Init(
+ const SfxItemSet& rItemSet,
+ sal_Int16 nScript,
+ sal_uLong nForceScNumFmt,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak,
+ bool bDefStyle );
+
+ /** Returns the bits specifying the used attributes.
+ @descr In cell XFs a set bit means a used attribute, in style XF a cleared
+ bit means a used attribute. This method regards the cell/style state.
+ @return The mask based on bit 0 (not yet bit-shifted as needed for export). */
+ sal_uInt8 GetUsedFlags() const;
+
+ void WriteBody5( XclExpStream& rStrm );
+ void WriteBody8( XclExpStream& rStrm );
+
+ /** Writes the contents of the XF record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a default XF record. Supports methods to set attributes directly. */
+class XclExpDefaultXF : public XclExpXF
+{
+public:
+ explicit XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF );
+
+ /** Sets the Excel font index. */
+ void SetFont( sal_uInt16 nXclFont );
+ /** Sets the Excel number format index. */
+ void SetNumFmt( sal_uInt16 nXclNumFmt );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a STYLE record containing the data of a cell style.
+ @descr The calss is able to store built-in and user-defined styles. */
+class XclExpStyle : public XclExpRecord
+{
+public:
+ explicit XclExpStyle( sal_uInt32 nXFId, const String& rStyleName );
+ explicit XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+
+ /** Returns true, if this record represents an Excel built-in style. */
+ inline bool IsBuiltIn() const { return mnStyleId != EXC_STYLE_USERDEF; }
+
+ inline const String& GetName() const { return maName; }
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the STYLE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ String maName; /// Name of the cell style.
+ XclExpXFId maXFId; /// XF identifier for style formatting.
+ sal_uInt8 mnStyleId; /// Built-in style identifier.
+ sal_uInt8 mnLevel; /// Outline level for RowLevel and ColLevel styles.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores all XF records (cell formats and cell styles) in the document.
+
+ Stores also the names of user defined cell styles (STYLE records). Supports
+ reduction to the maximum count of XF records of the current BIFF version.
+
+ An instance of this class collects all XF records in the conversion phase
+ of the export, using the Insert() and InsertStyle() functions. It returns a
+ unique identidier for each XF record.
+
+ After the entire document is converted, the Finalize() function will reduce
+ the list to the number of XF records supported by the current BIFF version.
+
+ Then, in the streaming phase, the function GetXFIndex() returns the real
+ Excel XF index for all XF identifiers.
+ */
+class XclExpXFBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXFBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts predefined built-in styles and user-defined styles. */
+ void Initialize();
+
+ /** Finds or creates a cell XF record for the passed item set.
+ @return A unique XF record ID. */
+ sal_uInt32 Insert( const ScPatternAttr* pPattern, sal_Int16 nScript );
+ /** Finds or creates a cell XF record for the passed item set.
+ @param nForceXclFont The font to be exported. If not equal to EXC_FONT_NOTFOUND,
+ this font index will be used unconditionally and the cell font will be ignored.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ This is required for cells that contain multi-line text.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertWithFont(
+ const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uInt16 nForceXclFont,
+ bool bForceLineBreak );
+ /** Finds or creates a cell XF record for the passed item set, with custom number format.
+ @param nXFFlags Additional flags allowing to control the creation of an XF.
+ @param nForceScNumFmt The number format to be exported, e.g. formula
+ result type. This format will always overwrite the cell's number format.
+ @param bForceLineBreak true = Set line break flag unconditionally.
+ This is required for cells that contain multi-line text.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertWithNumFmt(
+ const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uLong nForceScNumFmt,
+ bool bForceLineBreak );
+ /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
+ @return A unique XF record ID. */
+ sal_uInt32 InsertStyle( const SfxStyleSheetBase* pStyleSheet );
+ /** Returns the XF identifier representing a fixed Excel XF index (e.g. for built-in XFs). */
+ static sal_uInt32 GetXFIdFromIndex( sal_uInt16 nXFIndex );
+ /** Returns the XF identifier representing the default cell XF. */
+ static sal_uInt32 GetDefCellXFId();
+
+ /** Returns an XF record by its unique identifier. */
+ const XclExpXF* GetXFById( sal_uInt32 nXFId ) const;
+
+ /** Reduces the XF record list to the maximum allowed number of records. */
+ void Finalize();
+
+ /** Returns the Excel XF index of the XF record with passed XF ID. */
+ sal_uInt16 GetXFIndex( sal_uInt32 nXFId ) const;
+
+ sal_Int32 GetXmlStyleIndex( sal_uInt32 nXFId ) const;
+ sal_Int32 GetXmlCellIndex( sal_uInt32 nXFId ) const;
+
+ /** Writes all XF records contained in this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpXF > XclExpXFList;
+ typedef XclExpXFList::RecordRefType XclExpXFRef;
+ typedef XclExpRecordList< XclExpStyle > XclExpStyleList;
+
+private:
+ /** Returns the XF ID of the cell XF containing the passed format. */
+ sal_uInt32 FindXF( const ScPatternAttr& rPattern, sal_uLong nForceScNumFmt,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak ) const;
+ /** Returns the XF ID of the style XF containing the passed style. */
+ sal_uInt32 FindXF( const SfxStyleSheetBase& rStyleSheet ) const;
+
+ /** Returns the XF ID of a built-in style XF, searches by style identifier. */
+ sal_uInt32 FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL ) const;
+
+ /** Tries to find the XF record containing the passed format or inserts a new record.
+ @return The XF record ID. */
+ sal_uInt32 InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
+ sal_uLong nForceScNumFmt,
+ sal_uInt16 nForceXclFont, bool bForceLineBreak );
+ /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
+ @return The XF record ID. */
+ sal_uInt32 InsertStyleXF( const SfxStyleSheetBase& rStyleSheet );
+
+ /** Inserts an XF and a STYLE record for all user defined style sheets. */
+ void InsertUserStyles();
+
+ /** Inserts a built-in XF record without a STYLE record and returns the XF ID.
+ @param bCreateStyleRec true = Creates the related STYLE record. */
+ sal_uInt32 AppendBuiltInXF( XclExpXFRef xXF,
+ sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+ /** Inserts a built-in XF and STYLE record and returns the XF ID.
+ @param bCreateStyleRec true = Creates the related STYLE record. */
+ sal_uInt32 AppendBuiltInXFWithStyle( XclExpXFRef xXF,
+ sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
+
+ /** Inserts all default XF and STYLE records. */
+ void InsertDefaultRecords();
+
+ /** Appends a XF index to the internal ID<->index maps. */
+ void AppendXFIndex( sal_uInt32 nXFId );
+
+ void AddBorderAndFill( const XclExpXF& rXF );
+ void SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF );
+
+private:
+ /** Extended info about a built-in XF. */
+ struct XclExpBuiltInInfo
+ {
+ sal_uInt8 mnStyleId; /// Built-in style identifier.
+ sal_uInt8 mnLevel; /// Level for RowLevel/ColLevel styles.
+ bool mbPredefined; /// true = XF still predefined.
+ bool mbHasStyleRec; /// true = STYLE record created.
+ explicit XclExpBuiltInInfo();
+ };
+ typedef ::std::map< sal_uInt32, XclExpBuiltInInfo > XclExpBuiltInMap;
+ typedef ::std::vector< XclExpCellBorder > XclExpBorderList;
+ typedef ::std::vector< XclExpCellArea > XclExpFillList;
+
+ XclExpXFList maXFList; /// List of all XF records.
+ XclExpStyleList maStyleList; /// List of all STYLE records.
+ XclExpBuiltInMap maBuiltInMap; /// Contained elements describe built-in XFs.
+ ScfUInt16Vec maXFIndexVec; /// Maps XF IDs to XF indexes.
+ ScfUInt16Vec maStyleIndexes; /// Maps XF IDs to OOXML Style indexes
+ ScfUInt16Vec maCellIndexes; /// Maps XF IDs to OOXML Cell indexes
+ XclExpXFList maSortedXFList; /// List of XF records in XF index order.
+ XclExpBorderList maBorders; /// List of borders used by XF records
+ XclExpFillList maFills; /// List of fills used by XF records
+
+};
+
+// ============================================================================
+
+class XclExpXmlStyleSheet : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpXmlStyleSheet( const XclExpRoot& rRoot );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
new file mode 100644
index 000000000000..33b7b2c2fa77
--- /dev/null
+++ b/sc/source/filter/inc/xetable.hxx
@@ -0,0 +1,1070 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XETABLE_HXX
+#define SC_XETABLE_HXX
+
+#include "xltable.hxx"
+
+#include <deque>
+#include <tools/mempool.hxx>
+#include "xladdress.hxx"
+#include "xerecord.hxx"
+#include "xestring.hxx"
+#include "xeformula.hxx"
+#include "xestyle.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+/* ============================================================================
+Export of cell tables including row and column description.
+- Managing all used and formatted cells in a sheet.
+- Row and column properties, i.e. width/height, visibility.
+- Find default row formatting and default column formatting.
+- Merged cell ranges.
+============================================================================ */
+
+// ============================================================================
+// Helper records for cell records
+// ============================================================================
+
+/** Represents a STRING record that contains the result of a string formula. */
+class XclExpStringRec : public XclExpRecord
+{
+public:
+ explicit XclExpStringRec( const XclExpRoot& rRoot, const String& rResult );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mxResult;
+};
+
+// Additional records for special formula ranges ==============================
+
+/** Base record for additional range formula records (i.e. ARRAY, SHRFMLA). */
+class XclExpRangeFmlaBase : public XclExpRecord
+{
+public:
+ /** Returns true, if the passed cell position is equal to own base position. */
+ bool IsBasePos( sal_uInt16 nXclCol, sal_uInt32 nXclRow ) const;
+
+ /** Derived classes create the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const = 0;
+ /** Derived classes return true, if the own formula contains volatile functions. */
+ virtual bool IsVolatile() const = 0;
+
+protected:
+ /** Constructs the record with a single cell. */
+ explicit XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScAddress& rScPos );
+ /** Constructs the record with a cell range. */
+ explicit XclExpRangeFmlaBase(
+ sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScRange& rScRange );
+
+ /** Extends the cell range to include the passed cell address. */
+ void Extend( const ScAddress& rScPos );
+
+ /** Writes the range address covered by this record. */
+ void WriteRangeAddress( XclExpStream& rStrm ) const;
+
+protected:
+ XclRange maXclRange; /// Range described by this record.
+ XclAddress maBaseXclPos; /// Address of base cell (first FORMULA record).
+};
+
+typedef boost::shared_ptr< XclExpRangeFmlaBase > XclExpRangeFmlaRef;
+
+// Array formulas =============================================================
+
+class ScTokenArray;
+
+/** Represents an ARRAY record that contains the token array of a matrix formula.
+
+ An ARRAY record is stored following the first FORMULA record that is part
+ of a matrix formula. All FORMULA records of a matrix formula contain a
+ reference to the ARRAY record, while the ARRAY record contains the formula
+ token array used by all formulas.
+ */
+class XclExpArray : public XclExpRangeFmlaBase
+{
+public:
+ explicit XclExpArray( XclTokenArrayRef xTokArr, const ScRange& rScRange );
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the array formula contains volatile functions. */
+ virtual bool IsVolatile() const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclTokenArrayRef mxTokArr; /// The token array of a matrix formula.
+};
+
+typedef boost::shared_ptr< XclExpArray > XclExpArrayRef;
+
+// ----------------------------------------------------------------------------
+
+/** Caches all ARRAY records. */
+class XclExpArrayBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpArrayBuffer( const XclExpRoot& rRoot );
+
+ /** Inserts a new ARRAY record into the buffer and returns it. */
+ XclExpArrayRef CreateArray( const ScTokenArray& rScTokArr, const ScRange& rScRange );
+ /** Tries to find an ARRAY record that corresponds to an ocMatRef token. */
+ XclExpArrayRef FindArray( const ScTokenArray& rScTokArr ) const;
+
+private:
+ typedef ::std::map< ScAddress, XclExpArrayRef > XclExpArrayMap;
+ XclExpArrayMap maRecMap; /// Map containing the ARRAY records.
+};
+
+// Shared formulas ============================================================
+
+/** Represents a SHRFMLA record that contains the token array of a shared formula.
+
+ A SHRFMLA record is stored following the first FORMULA record that is part
+ of a shared formula. All FORMULA records of a shared formula contain a
+ reference to the SHRFMLA record, while the SHRFMLA record contains the
+ formula token array used by all formulas.
+ */
+class XclExpShrfmla : public XclExpRangeFmlaBase
+{
+public:
+ /** Creates a SHRFMLA record that consists of the passed cell address only. */
+ explicit XclExpShrfmla( XclTokenArrayRef xTokArr, const ScAddress& rScPos );
+
+ /** Extends the cell range to include the passed cell address. */
+ void ExtendRange( const ScAddress& rScPos );
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the shared formula contains volatile functions. */
+ virtual bool IsVolatile() const;
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclTokenArrayRef mxTokArr; /// The token array of a shared formula.
+ sal_uInt8 mnUsedCount; /// Number of FORMULA records referring to this record.
+};
+
+typedef boost::shared_ptr< XclExpShrfmla > XclExpShrfmlaRef;
+
+// ----------------------------------------------------------------------------
+
+/** Caches all SHRFMLA records and provides functions to update their ranges. */
+class XclExpShrfmlaBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpShrfmlaBuffer( const XclExpRoot& rRoot );
+
+ /** Tries to create a new or to update an existing SHRFMLA record.
+ @return An empty reference, if the passed token array does not contain
+ a shared formula. If the token array is a shared formula, this
+ function updates its cell range to include the passed cell position,
+ if there is a SHRFMLA record for the passed token array; otherwise
+ this function creates and returns a new SHRFMLA record. */
+ XclExpShrfmlaRef CreateOrExtendShrfmla(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos );
+
+private:
+ typedef ::std::map< const ScTokenArray*, XclExpShrfmlaRef > XclExpShrfmlaMap;
+ XclExpShrfmlaMap maRecMap; /// Map containing the SHRFMLA records.
+};
+
+// Multiple operations ========================================================
+
+struct XclMultipleOpRefs;
+
+/** Represents a TABLEOP record for a multiple operations range. */
+class XclExpTableop : public XclExpRangeFmlaBase
+{
+public:
+ explicit XclExpTableop( const ScAddress& rScPos,
+ const XclMultipleOpRefs& rRefs, sal_uInt8 nScMode );
+
+ /** Returns true, if the cell range has been extended to the passed position.
+ @descr All references passed in rRefs must fit the ranges passed in the constructor. */
+ bool TryExtend( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs );
+
+ /** Finalizes the record. Tests on valid cell range and reference addresses. */
+ void Finalize();
+
+ /** Creates and returns the token array for a corresponding FORMULA cell record. */
+ virtual XclTokenArrayRef CreateCellTokenArray( const XclExpRoot& rRoot ) const;
+ /** Returns true, if the multiple operations range is volatile. */
+ virtual bool IsVolatile() const;
+ /** Writes the record if it is valid. */
+ virtual void Save( XclExpStream& rStrm );
+
+private:
+ /** Returns true, if the passed cell position can be appended to this record. */
+ bool IsAppendable( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const;
+
+ /** Writes the contents of the TABLEOP record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ SCTAB mnScTab; /// Sheet index of this record.
+ sal_uInt16 mnLastAppXclCol;/// Column index of last appended cell.
+ sal_uInt16 mnColInpXclCol; /// Column index of column input cell.
+ sal_uInt32 mnColInpXclRow; /// Row index of column input cell.
+ sal_uInt16 mnRowInpXclCol; /// Column index of row input cell.
+ sal_uInt32 mnRowInpXclRow; /// Row index of row input cell.
+ sal_uInt8 mnScMode; /// Type of the multiple operation (Calc constant).
+ bool mbValid; /// true = Contains valid references.
+};
+
+typedef boost::shared_ptr< XclExpTableop > XclExpTableopRef;
+
+// ----------------------------------------------------------------------------
+
+/** Contains all created TABLEOP records and supports creating or updating them. */
+class XclExpTableopBuffer : protected XclExpRoot
+{
+public:
+ explicit XclExpTableopBuffer( const XclExpRoot& rRoot );
+
+ /** Tries to update an existing or to create a new TABLEOP record.
+ @return Reference to the TABLEOP record for this cell (existing or new),
+ or an empty reference, if rScTokArr does not contain a multiple
+ operations formula. */
+ XclExpTableopRef CreateOrExtendTableop(
+ const ScTokenArray& rScTokArr, const ScAddress& rScPos );
+
+ /** Finalizes all contained TABLEOP records. */
+ void Finalize();
+
+private:
+ /** Tries to create a new TABLEOP record, if rRefs contains valid references. */
+ XclExpTableopRef TryCreate( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs );
+
+private:
+ typedef XclExpRecordList< XclExpTableop > XclExpTableopList;
+ XclExpTableopList maTableopList; /// List of all TABLEOP records.
+};
+
+// ============================================================================
+// Cell records
+// ============================================================================
+
+/** The base class of all cell records. */
+class XclExpCellBase : public XclExpRecord
+{
+public:
+ /** Returns the (first) address of the cell(s). */
+ inline const XclAddress& GetXclPos() const { return maXclPos; }
+ /** Returns the (first) Excel column index of the cell(s). */
+ inline sal_uInt16 GetXclCol() const { return maXclPos.mnCol; }
+ /** Returns the Excel row index of the cell. */
+ inline sal_uInt32 GetXclRow() const { return maXclPos.mnRow; }
+
+ /** Derived classes return the column index of the last contained cell. */
+ virtual sal_uInt16 GetLastXclCol() const = 0;
+ /** Derived classes return the XF identifier of the first contained cell. */
+ virtual sal_uInt32 GetFirstXFId() const = 0;
+ /** Derived classes return true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const = 0;
+ /** Derived classes return whether the cell contains multi-line text. */
+ virtual bool IsMultiLineText() const;
+
+ /** Derived classes try to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+ /** Derived classes convert the XF identifier(s) into the Excel XF index(es).
+ @param rXFIndexes The converted XF index(es) are inserted here. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot ) = 0;
+ /** Derived classes for blank cells insert the Excel XF index(es) into the passed vector. */
+ virtual void GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+ /** Derived classes for blank cells remove unused Excel XF index(es). */
+ virtual void RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes );
+
+protected:
+ explicit XclExpCellBase(
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos );
+
+ /** Sets this record to a new column position. */
+ inline void SetXclCol( sal_uInt16 nXclCol ) { maXclPos.mnCol = nXclCol; }
+ /** Sets this record to a new row position. */
+ inline void SetXclRow( sal_uInt32 nXclRow ) { maXclPos.mnRow = nXclRow; }
+
+private:
+ XclAddress maXclPos; /// Address of the cell.
+};
+
+typedef boost::shared_ptr< XclExpCellBase > XclExpCellRef;
+
+// Single cell records ========================================================
+
+/** Base class for all cell records not supporting multiple contents. */
+class XclExpSingleCellBase : public XclExpCellBase
+{
+public:
+ /** Returns the last column, which is equal to the first column for single cells. */
+ virtual sal_uInt16 GetLastXclCol() const;
+ /** Return the XF identifier of the cell. */
+ virtual sal_uInt32 GetFirstXFId() const;
+ /** Returns true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const;
+ /** Converts the XF identifier into the Excel XF index. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot );
+ /** Writes cell address, XF index, and calls WriteContents() for each cell. */
+ virtual void Save( XclExpStream& rStrm );
+
+protected:
+ explicit XclExpSingleCellBase( sal_uInt16 nRecId, sal_Size nContSize,
+ const XclAddress& rXclPos, sal_uInt32 nXFId );
+
+ explicit XclExpSingleCellBase( const XclExpRoot& rRoot,
+ sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uInt32 nForcedXFId );
+
+ inline void SetContSize( sal_Size nContSize ) { mnContSize = nContSize; }
+ inline sal_Size GetContSize() const { return mnContSize; }
+
+ inline void SetXFId( sal_uInt32 nXFId ) { maXFId.mnXFId = nXFId; }
+ inline sal_uInt32 GetXFId() const { return maXFId.mnXFId; }
+
+private:
+ /** Writes cell address, XF index, and calls WriteContents() for each cell. */
+ virtual void WriteBody( XclExpStream& rStrm );
+ /** Derived classes write the contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm ) = 0;
+
+private:
+ XclExpXFId maXFId; /// The XF identifier of the cell formatting.
+ sal_Size mnContSize; /// The size of the cell contents.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a NUMBER record that describes a cell with a double value. */
+class XclExpNumberCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpNumberCell )
+
+public:
+ explicit XclExpNumberCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ double fValue );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ double mfValue; /// The cell value.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a BOOLERR record that describes a cell with a Boolean value. */
+class XclExpBooleanCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpBooleanCell )
+
+public:
+ explicit XclExpBooleanCell( const XclExpRoot rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ bool bValue );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ bool mbValue; /// The cell value.
+};
+
+class ScStringCell;
+class ScEditCell;
+class XclExpHyperlinkHelper;
+
+/** Represents a text cell record.
+
+ May contain a BIFF2-BIFF7 LABEL record for a simple string, or a BIFF2-BIFF7
+ RSTRING record for a formatted string, or a BIFF8 LABELSST string for any
+ string (simply stores a reference to the Shared String Table).
+ */
+class XclExpLabelCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpLabelCell )
+
+public:
+ /** Constructs the record from an unformatted Calc string cell. */
+ explicit XclExpLabelCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScStringCell& rCell );
+
+ /** Constructs the record from a formatted Calc edit cell. */
+ explicit XclExpLabelCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScEditCell& rCell, XclExpHyperlinkHelper& rHlinkHelper );
+
+ /** Returns true if the cell contains multi-line text. */
+ virtual bool IsMultiLineText() const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Initializes the record contents. Called from constructors. */
+ void Init( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, XclExpStringRef xText );
+
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ XclExpStringRef mxText; /// The cell text.
+ sal_uInt32 mnSstIndex; /// Index into Shared String Table (only used for BIFF8).
+ bool mbLineBreak; /// True = cell has automatic linebreaks enabled.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScFormulaCell;
+
+/** Represents a FORMULA record that describes a cell with a formula. */
+class XclExpFormulaCell : public XclExpSingleCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpFormulaCell )
+
+public:
+ explicit XclExpFormulaCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ const ScFormulaCell& rScFmlaCell,
+ XclExpArrayBuffer& rArrayBfr,
+ XclExpShrfmlaBuffer& rShrfmlaBfr,
+ XclExpTableopBuffer& rTableopBfr );
+
+ /** Writes the FORMULA record and additional records related to the formula. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ virtual void WriteContents( XclExpStream& rStrm );
+
+private:
+ ScFormulaCell& mrScFmlaCell; /// The Calc formula cell.
+ XclTokenArrayRef mxTokArr; /// The token array of the formula.
+ XclExpRangeFmlaRef mxAddRec; /// Additional record for matrix/shared formulas.
+ XclExpRecordRef mxStringRec; /// STRING record for string result.
+};
+
+// Multiple cell records ======================================================
+
+struct XclExpMultiXFId : public XclExpXFId
+{
+ sal_uInt16 mnCount; /// Number of XF identifiers.
+
+ inline explicit XclExpMultiXFId( sal_uInt32 nXFId, sal_uInt16 nCount = 1 ) :
+ XclExpXFId( nXFId ), mnCount( nCount ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for all cell records supporting multiple contents. */
+class XclExpMultiCellBase : public XclExpCellBase
+{
+public:
+ /** Returns the column index of the last cell this record describes. */
+ virtual sal_uInt16 GetLastXclCol() const;
+ /** Return the XF identifier of the first contained cell. */
+ virtual sal_uInt32 GetFirstXFId() const;
+ /** Returns true, if this record does not contain at least one valid cell. */
+ virtual bool IsEmpty() const;
+
+ /** Convert all XF identifiers into the Excel XF indexes. */
+ virtual void ConvertXFIndexes( const XclExpRoot& rRoot );
+ /** Writes the record, calls WriteContents() for each contained cell.
+ @descr May write several records, if unused XF indexes are contained. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+protected:
+ explicit XclExpMultiCellBase( sal_uInt16 nRecId, sal_uInt16 nMulRecId,
+ sal_Size nContSize, const XclAddress& rXclPos );
+
+ /** Sets the size of the remaining contents of one cell (without the XF index). */
+ inline void SetContSize( sal_Size nContSize ) { mnContSize = nContSize; }
+ /** Returns the size of the remaining contents of one cell (without the XF index). */
+ inline sal_Size GetContSize() const { return mnContSize; }
+
+ /** Returns the number of cells this record represents. */
+ sal_uInt16 GetCellCount() const;
+
+ /** Appends the passed XF identifier nCount times to the list of XF identifiers. */
+ void AppendXFId( const XclExpMultiXFId& rXFId );
+ /** Appends the passed cell format nCount times to the list of XF identifiers. */
+ void AppendXFId( const XclExpRoot& rRoot,
+ const ScPatternAttr* pPattern, sal_uInt16 nScript,
+ sal_uInt32 nForcedXFId, sal_uInt16 nCount = 1 );
+
+ /** Tries to merge the XF ID list of the passed cell with the own list. */
+ bool TryMergeXFIds( const XclExpMultiCellBase& rCell );
+ /** Inserts the Excel XF index(es) into the passed vector. */
+ void GetXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+
+ /** Removes unused Excel XF index(es).
+ @param rXFIndexes Specifies which XF indexes are used. */
+ void RemoveUnusedXFIndexes( const ScfUInt16Vec& rXFIndexes );
+
+private:
+ /** Derived classes write the remaining contents of the specified cell (without XF index).
+ @param nRelCol Relative column index (starts with 0 for first cell of this record). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol ) = 0;
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol ) = 0;
+
+private:
+ typedef ::std::deque< XclExpMultiXFId > XclExpMultiXFIdDeq;
+
+ sal_uInt16 mnMulRecId; /// Record ID for multiple record variant.
+ sal_Size mnContSize; /// Data size of contents for one cell
+ XclExpMultiXFIdDeq maXFIds; /// The XF identifiers of the cell formatting.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a BLANK or MULBLANK record that describes empty but formatted cells. */
+class XclExpBlankCell : public XclExpMultiCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpBlankCell )
+
+public:
+ explicit XclExpBlankCell( const XclAddress& rXclPos, const XclExpMultiXFId& rXFId );
+
+ explicit XclExpBlankCell( const XclExpRoot& rRoot,
+ const XclAddress& rXclPos, sal_uInt16 nLastXclCol,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId );
+
+ /** Tries to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+ /** Inserts the Excel XF index(es) into the passed vector. */
+ virtual void GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const;
+ /** Tries to remove unused Excel XF index(es). */
+ virtual void RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes );
+
+private:
+ /** Writes the remaining contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol );
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an RK or MULRK record that describes cells with a compressed double values. */
+class XclExpRkCell : public XclExpMultiCellBase
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclExpRkCell )
+
+public:
+ explicit XclExpRkCell( const XclExpRoot& rRoot, const XclAddress& rXclPos,
+ const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
+ sal_Int32 nRkValue );
+
+ /** Tries to merge the contents of the passed cell to own data. */
+ virtual bool TryMerge( const XclExpCellBase& rCell );
+
+private:
+ /** Writes the remaining contents of the specified cell (without XF index). */
+ virtual void WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol );
+ virtual void WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol );
+
+private:
+ ScfInt32Vec maRkValues; /// The cell values.
+};
+
+// ============================================================================
+// Rows and Columns
+// ============================================================================
+
+class ScOutlineArray;
+
+/** Base class for buffers containing row or column outline data. */
+class XclExpOutlineBuffer
+{
+public:
+ /** Returns true, if a collapsed group ends at the last processed position. */
+ inline bool IsCollapsed() const { return mbCurrCollapse; }
+ /** Returns the highest level of an open group at the last processed position. */
+ inline sal_uInt8 GetLevel() const { return ::std::min( mnCurrLevel, EXC_OUTLINE_MAX ); }
+
+protected:
+ /** Constructs the outline buffer.
+ @param bRows true = Process row ouline array; false = Process column outline array. */
+ explicit XclExpOutlineBuffer( const XclExpRoot& rRoot, bool bRows );
+
+ /** Updates the current state by processing the settings at the passed Calc position. */
+ void UpdateColRow( SCCOLROW nScPos );
+
+private:
+ /** Data about an outline level. */
+ struct XclExpLevelInfo
+ {
+ SCCOLROW mnScEndPos; /// The end position of a group in a level.
+ bool mbHidden; /// true = Group in this level is hidden.
+ inline explicit XclExpLevelInfo() : mnScEndPos( 0 ), mbHidden( false ) {}
+ };
+ typedef ::std::vector< XclExpLevelInfo > XclExpLevelInfoVec;
+
+ const ScOutlineArray* mpScOLArray; /// Pointer to Calc outline array.
+ XclExpLevelInfoVec maLevelInfos; /// Info for current row and all levels.
+ sal_uInt8 mnCurrLevel; /// Highest level of an open group for current position.
+ bool mbCurrCollapse; /// true = Collapsed group ends at current position.
+};
+
+// ----------------------------------------------------------------------------
+
+/** The outline buffer for column outlines. */
+class XclExpColOutlineBuffer : public XclExpOutlineBuffer
+{
+public:
+ inline explicit XclExpColOutlineBuffer( const XclExpRoot& rRoot ) :
+ XclExpOutlineBuffer( rRoot, false ) {}
+
+ /** Updates the current state by processing the settings of the passed Calc column. */
+ inline void Update( SCCOL nScCol )
+ { UpdateColRow( static_cast< SCCOLROW >( nScCol ) ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** The outline buffer for row outlines. */
+class XclExpRowOutlineBuffer : public XclExpOutlineBuffer
+{
+public:
+ inline explicit XclExpRowOutlineBuffer( const XclExpRoot& rRoot ) :
+ XclExpOutlineBuffer( rRoot, true ) {}
+
+ /** Updates the current state by processing the settings of the passed Calc row. */
+ inline void Update( SCROW nScRow )
+ { UpdateColRow( static_cast< SCCOLROW >( nScRow ) ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a GUTS record containing the level count of row and column outlines. */
+class XclExpGuts : public XclExpRecord
+{
+public:
+ explicit XclExpGuts( const XclExpRoot& rRoot );
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnColLevels; /// Number of visible column outline levels.
+ sal_uInt16 mnColWidth; /// Width of column outline area (pixels).
+ sal_uInt16 mnRowLevels; /// Number of visible row outline levels.
+ sal_uInt16 mnRowWidth; /// Width of row outline area (pixels).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a DIMENSIONS record containing the used area of a sheet. */
+class XclExpDimensions : public XclExpRecord
+{
+public:
+ explicit XclExpDimensions( const XclExpRoot& rRoot );
+
+ /** Sets the used area to the record. */
+ void SetDimensions(
+ sal_uInt16 nFirstUsedXclCol, sal_uInt32 nFirstUsedXclRow,
+ sal_uInt16 nFirstFreeXclCol, sal_uInt32 nFirstFreeXclRow );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the DIMENSIONS record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt32 mnFirstUsedXclRow; /// First used row.
+ sal_uInt32 mnFirstFreeXclRow; /// First unused row after used area.
+ sal_uInt16 mnFirstUsedXclCol; /// First used column.
+ sal_uInt16 mnFirstFreeXclCol; /// First free column after used area.
+};
+
+// ============================================================================
+
+/** Represents the DEFCOLWIDTH record containing the default column width of a sheet.
+
+ Excel stores the default column width in entire character widths of the '0'
+ character using the application default font (i.e. the default width is 10,
+ if the '0' character fits 10 times into a cell in a column with default
+ width.
+
+ The IsDefWidth() function returns true, if the passed width (measured in
+ 1/256 of the width of the '0' character) could be converted exactly to the
+ default width. If the passed width is rounded up or down to get the default
+ width, the function returns false.
+ */
+class XclExpDefcolwidth : public XclExpUInt16Record, protected XclExpRoot
+{
+public:
+ explicit XclExpDefcolwidth( const XclExpRoot& rRoot );
+
+ /** Returns true, if the own default width exactly matches the passed width. */
+ bool IsDefWidth( sal_uInt16 nXclColWidth ) const;
+
+ /** Sets the passed column width (in 1/256 character width) as default width. */
+ void SetDefWidth( sal_uInt16 nXclColWidth );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains the column settings for a range of columns.
+
+ After construction the record contains a temporary XF identifier returned
+ from the XF buffer. After creating the entire Excel document in memory, the
+ ConvertXFIndexes() function converts it into the real Excel XF index.
+ */
+class XclExpColinfo : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs the record with the settings in the Calc document. */
+ explicit XclExpColinfo( const XclExpRoot& rRoot,
+ SCCOL nScCol, SCROW nLastScRow,
+ XclExpColOutlineBuffer& rOutlineBfr );
+
+ /** Converts the XF identifier into the Excel XF index, returns the latter. */
+ sal_uInt16 ConvertXFIndexes();
+
+ /** Tries to merge this record with the passed record.
+ @descr Possible, if passed record directly follows this record and has equal contents.
+ @return true = This record is equal to passed record and has been updated. */
+ bool TryMerge( const XclExpColinfo& rColInfo );
+
+ /** Returns the Excel width of the column(s). */
+ inline sal_uInt16 GetColWidth() const { return mnWidth; }
+ /** Returns the final Excel XF index of the column(s). */
+ inline sal_uInt16 GetXFIndex() const { return maXFId.mnXFIndex; }
+ /** Returns the number of columns represented by this record. */
+ inline sal_uInt16 GetColCount() const { return mnLastXclCol - mnFirstXclCol + 1; }
+
+ /** Returns true, if the column has default format and width. */
+ bool IsDefault( const XclExpDefcolwidth& rDefColWidth ) const;
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of this COLINFO record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpXFId maXFId; /// The XF identifier for column default format.
+ sal_uInt16 mnWidth; /// Excel width of the column.
+ sal_uInt16 mnFlags; /// Additional column flags.
+ sal_uInt16 mnFirstXclCol; /// Index to first column.
+ sal_uInt16 mnLastXclCol; /// Index to last column.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains COLINFO records for all columns of a Calc sheet.
+
+ On construction one COLINFO record per column is created. After creating
+ the entire Excel document in memory, the ConvertXFIndexes() function converts
+ all temporary XF identifiers into real Excel XF indexes and merges all equal
+ COLINFO records together.
+ */
+class XclExpColinfoBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpColinfoBuffer( const XclExpRoot& rRoot );
+
+ /** Initializes the buffer: finds settings and formatting of all columns.
+ @param nLastScRow Last row used to find default formatting. */
+ void Initialize( SCROW nLastScRow );
+ /** Converts the XF identifiers into the Excel XF indexes and merges equal columns.
+ @param rXFIndexes Returns the final XF indexes of all columns. */
+ void Finalize( ScfUInt16Vec& rXFIndexes );
+
+ /** Writes all COLINFO records of this buffer. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpColinfo > XclExpColinfoList;
+ typedef XclExpColinfoList::RecordRefType XclExpColinfoRef;
+
+ XclExpColinfoList maColInfos; /// List of COLINFO records.
+ XclExpDefcolwidth maDefcolwidth; /// The DEFCOLWIDTH record.
+ XclExpColOutlineBuffer maOutlineBfr; /// Buffer for column outline groups.
+};
+
+// ============================================================================
+
+class XclExpRow;
+
+/** Contains all possible default row settings. */
+struct XclExpDefaultRowData
+{
+ sal_uInt16 mnFlags; /// Default flags for unspecified rows.
+ sal_uInt16 mnHeight; /// Default height for unspecified rows.
+
+ explicit XclExpDefaultRowData();
+ explicit XclExpDefaultRowData( const XclExpRow& rRow );
+
+ /** Returns true, if rows are hidden by default. */
+ inline bool IsHidden() const { return ::get_flag( mnFlags, EXC_DEFROW_HIDDEN ); }
+ /** Returns true, if the rows have a manually set height by default. */
+ inline bool IsUnsynced() const { return ::get_flag( mnFlags, EXC_DEFROW_UNSYNCED ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a DEFROWHEIGHT record containing default format for unused rows. */
+class XclExpDefrowheight : public XclExpRecord
+{
+public:
+ explicit XclExpDefrowheight();
+
+ /** Sets the passed default data as current record contents. */
+ void SetDefaultData( const XclExpDefaultRowData& rDefData );
+
+private:
+ /** Writes the contents of the record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclExpDefaultRowData maDefData; /// Record data.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a ROW record and additionally contains all cells records of a row.
+
+ This class contains all cell records of a row in a spreadsheet. There are 2
+ cell records in Excel that support storing a range of cells in one record
+ (MULBLANK for multiple blank cells, and MULRK for multiple RK values). The
+ insertion functions try to merge a new inserted cell with existing
+ neighbors, if this is supported by the current type of cell record.
+
+ The Finalize() function converts the XF identifiers of all cell records to
+ the final Excel XF indexes. Then a default
+ */
+class XclExpRow : public XclExpRecord, protected XclExpRoot
+{
+public:
+ /** Constructs the ROW record and converts the Calc row settings.
+ @param bAlwaysEmpty true = This row will not be filled with blank cells
+ in the Finalize() function. */
+ explicit XclExpRow( const XclExpRoot& rRoot, sal_uInt32 nXclRow,
+ XclExpRowOutlineBuffer& rOutlineBfr, bool bAlwaysEmpty );
+
+ /** Returns the excel row index of this ROW record. */
+ inline sal_uInt32 GetXclRow() const { return mnXclRow; }
+ /** Returns the height of the row in twips. */
+ inline sal_uInt16 GetHeight() const { return mnHeight; }
+ /** Returns true, if this row does not contain at least one valid cell. */
+ inline bool IsEmpty() const { return maCellList.IsEmpty(); }
+ /** Returns true, if this row is hidden. */
+ inline bool IsHidden() const { return ::get_flag( mnFlags, EXC_ROW_HIDDEN ); }
+ /** Returns true, if this row contains a manually set height. */
+ inline bool IsUnsynced() const { return ::get_flag( mnFlags, EXC_ROW_UNSYNCED ); }
+ /** Returns true, if this row is enabled (will be exported). */
+ inline bool IsEnabled() const { return mbEnabled; }
+
+ /** Appends the passed cell object to this row. */
+ void AppendCell( XclExpCellRef xCell, bool bIsMergedBase );
+
+ /** Converts all XF identifiers into the Excel XF indexes. */
+ void Finalize( const ScfUInt16Vec& rColXFIndexes );
+
+ /** Returns the column index of the first used cell in this row.
+ @descr This function can only be called after Finalize(). */
+ sal_uInt16 GetFirstUsedXclCol() const;
+ /** Returns the column index of the first unused cell following all used cells in this row.
+ @descr This function can only be called after Finalize(). */
+ sal_uInt16 GetFirstFreeXclCol() const;
+
+ /** Returns true, if this row may be omitted by using the DEFROWHEIGHT record.
+ @descr A row may be omitted, if it does not contain any cell or
+ explicit default cell formatting, and is not part of an outline.
+ This function can only be called after Finalize(). */
+ bool IsDefaultable() const;
+ /** Disables this row, if it is defaultable and has the passed default format.
+ @descr Disabled rows will not be saved.
+ This function can only be called after Finalize(). */
+ void DisableIfDefault( const XclExpDefaultRowData& rDefRowData );
+
+ /** Writes all cell records of this row. */
+ void WriteCellList( XclExpStream& rStrm );
+
+ /** Writes the ROW record if the row is not disabled (see DisableIfDefault() function). */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Initializes the record data. Called from constructors. */
+ void Init( sal_uInt16 nXclRow, XclExpRowOutlineBuffer* pOutlineBfr );
+ /** Inserts a cell at the specified list position, tries to merge with neighbors. */
+ void InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase );
+
+ /** Writes the contents of the ROW record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpCellBase > XclExpCellList;
+
+ XclExpCellList maCellList; /// List of cell records for this row.
+ sal_uInt32 mnXclRow; /// Excel row index of this row.
+ sal_uInt16 mnHeight; /// Row height in twips.
+ sal_uInt16 mnFlags; /// Flags for the ROW record.
+ sal_uInt16 mnXFIndex; /// Default row formatting.
+ sal_uInt16 mnOutlineLevel; /// Outline Level (for OOXML)
+ bool mbAlwaysEmpty; /// true = Do not add blank cells in Finalize().
+ bool mbEnabled; /// true = Write this ROW record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Collects all rows which contain all cells of a sheet.
+
+ This row buffer automatically creates ROW records when cells are inserted
+ with the AppendCell() function. It is possible to force creation of more
+ ROW records with the CreateRows() function. In both cases, all preceding
+ missing ROW records are inserted too.
+ */
+class XclExpRowBuffer : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpRowBuffer( const XclExpRoot& rRoot );
+
+ /** Appends the passed cell object to the row that the cell specifies. */
+ void AppendCell( XclExpCellRef xCell, bool bIsMergedBase );
+ /** Forces insertion of all ROW records before the passed row. */
+ void CreateRows( SCROW nFirstFreeScRow );
+
+ /** Converts all XF identifiers into the Excel XF indexes and calculates default formats.
+ @param rDefRowData (out-param) The default row format is returned here.
+ @param rColXFIndexes The column default XF indexes. */
+ void Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes );
+
+ /** Writes the DIMENSIONS record, all ROW records and all cell records. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+ XclExpDimensions* GetDimensions();
+
+private:
+ /** Returns access to the specified ROW record. Inserts preceding missing ROW records.
+ @param bRowAlwaysEmpty true = Created rows will not be filled with blank cells
+ in the XclExpRow::Finalize() function. */
+ XclExpRow& GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty );
+
+private:
+ typedef ::boost::shared_ptr<XclExpRow> RowRef;
+ typedef ::std::map<sal_uInt32, RowRef> RowMap;
+
+ RowMap maRowMap;
+ XclExpRowOutlineBuffer maOutlineBfr; /// Buffer for row outline groups.
+ XclExpDimensions maDimensions; /// DIMENSIONS record for used area.
+};
+
+// ============================================================================
+// Cell Table
+// ============================================================================
+
+class XclExpNote;
+class XclExpMergedcells;
+class XclExpHyperlink;
+class XclExpDval;
+
+/** This class contains the cell contents and more of an entire sheet.
+
+ The cell table includes the settings and default formatting of all columns,
+ the settings and default formatting of all used rows, and the contents of
+ all cells of one sheet in a spreadsheet document.
+
+ The constructor does all the work creating the cell table. It reads the
+ Calc sheet and converts all columns, rows, and cells to Excel record data.
+ Additioanlly, hyperlink records, note records, additional records for
+ formula cells, data validation records, and outline records are created.
+
+ The Finalize() function does even more work. It calculates default column
+ settings and removes column records that are equal to this default. The
+ same happens with rows: A default format is calculated for each row, and
+ all blank cells in this row that have the same format are removed. Then,
+ the most used row settings are calculated, and all empty rows that have the
+ same settings are removed too.
+
+ Records that are not stored inside the cell table area in an Excel file
+ (i.e. DEFROWHEIGHT record, NOTE records, MERGEDCELLS record, HLINK records,
+ DVAL and DV records for data validation) can be accessed with the function
+ CreateRecord(). It returns the reference to the respective record (or
+ record list) which can be inserted into a record list.
+ */
+class XclExpCellTable : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ explicit XclExpCellTable( const XclExpRoot& rRoot );
+
+ /** Converts all XF identifiers into the Excel XF indexes and calculates default formats. */
+ void Finalize();
+
+ /** Returns the reference to an internal record specified by the passed record id.
+ @param nRecId The record identifier that specifies which record is
+ returned. Possible values are: EXC_ID_DEFROWHEIGHT, EXC_ID_NOTE,
+ EXC_ID_MERGEDCELLS, EXC_ID_HLINK, EXC_ID_DVAL. */
+ XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+ /** Saves the entire cell table. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ typedef XclExpRecordList< XclExpNote > XclExpNoteList;
+ typedef XclExpRecordList< XclExpHyperlink > XclExpHyperlinkList;
+
+ typedef boost::shared_ptr< XclExpDefrowheight > XclExpDefrowhRef;
+ typedef boost::shared_ptr< XclExpNoteList > XclExpNoteListRef;
+ typedef boost::shared_ptr< XclExpMergedcells > XclExpMergedcellsRef;
+ typedef boost::shared_ptr< XclExpHyperlinkList > XclExpHyperlinkRef;
+ typedef boost::shared_ptr< XclExpDval > XclExpDvalRef;
+
+ XclExpColinfoBuffer maColInfoBfr; /// Buffer for column formatting.
+ XclExpRowBuffer maRowBfr; /// Rows and cell records.
+ XclExpArrayBuffer maArrayBfr; /// Buffer for ARRAY records.
+ XclExpShrfmlaBuffer maShrfmlaBfr; /// Buffer for SHRFMLA records.
+ XclExpTableopBuffer maTableopBfr; /// Buffer for TABLEOP records.
+ XclExpDefrowhRef mxDefrowheight; /// DEFROWHEIGHT record for default row format.
+ XclExpRecordRef mxGuts; /// GUTS record for outline areas.
+ XclExpNoteListRef mxNoteList; /// List of NOTE records.
+ XclExpMergedcellsRef mxMergedcells; /// MERGEDCELLS record for merged cell ranges.
+ XclExpHyperlinkRef mxHyperlinkList; /// List of HLINK records.
+ XclExpDvalRef mxDval; /// Data validation with DVAL and DV records.
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xeview.hxx b/sc/source/filter/inc/xeview.hxx
new file mode 100644
index 000000000000..db81d34ad60e
--- /dev/null
+++ b/sc/source/filter/inc/xeview.hxx
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XEVIEW_HXX
+#define SC_XEVIEW_HXX
+
+#include "xerecord.hxx"
+#include "xlview.hxx"
+#include "xeroot.hxx"
+
+// Workbook view settings records =============================================
+
+/** Represents the WINDOW1 record containing global workbook view settings. */
+class XclExpWindow1 : public XclExpRecord
+{
+public:
+ explicit XclExpWindow1( const XclExpRoot& rRoot );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the WINDOW1 record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnFlags; /// Option flags.
+ sal_uInt16 mnTabBarSize; /// Size of tabbar relative to window width (per mill).
+};
+
+// Sheet view settings records ================================================
+
+/** Represents a WINDOW2 record with general view settings for a sheet. */
+class XclExpWindow2 : public XclExpRecord
+{
+public:
+ explicit XclExpWindow2( const XclExpRoot& rRoot,
+ const XclTabViewData& rData, sal_uInt32 nGridColorId );
+
+private:
+ /** Writes the contents of the WINDOW2 record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ Color maGridColor; /// Grid color (<=BIFF5).
+ sal_uInt32 mnGridColorId; /// Color ID of grid color (>=BIFF8).
+ sal_uInt16 mnFlags; /// Option flags.
+ XclAddress maFirstXclPos; /// First visible cell.
+ sal_uInt16 mnNormalZoom; /// Zoom factor for normal view.
+ sal_uInt16 mnPageZoom; /// Zoom factor for pagebreak preview.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an SCL record for the zoom factor of the current view of a sheet. */
+class XclExpScl : public XclExpRecord
+{
+public:
+ explicit XclExpScl( sal_uInt16 nZoom );
+
+private:
+ /** Tries to shorten numerator and denominator by the passed value. */
+ void Shorten( sal_uInt16 nFactor );
+ /** Writes the contents of the SCL record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnNum; /// Numerator of the zoom factor.
+ sal_uInt16 mnDenom; /// Denominator of the zoom factor.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a PANE record containing settings for split/frozen windows. */
+class XclExpPane : public XclExpRecord
+{
+public:
+ explicit XclExpPane( const XclTabViewData& rData );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Writes the contents of the PANE record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ sal_uInt16 mnSplitX; /// Split X position, or frozen column.
+ sal_uInt32 mnSplitY; /// Split Y position, or frozen row.
+ XclAddress maSecondXclPos; /// First visible cell in additional panes.
+ sal_uInt8 mnActivePane; /// Active pane (with cell cursor).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a SELECTION record with selection data for a pane. */
+class XclExpSelection : public XclExpRecord
+{
+public:
+ explicit XclExpSelection( const XclTabViewData& rData, sal_uInt8 nPane );
+
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ /** Writes the contents of the SELECTION record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ XclSelectionData maSelData; /// Selection data.
+ sal_uInt8 mnPane; /// Pane identifier of this selection.
+};
+
+class XclExpTabBgColor : public XclExpRecord
+{
+public:
+ explicit XclExpTabBgColor( const XclTabViewData& rTabViewData );
+
+ /* virtual void SaveXml( XclExpXmlStream& rStrm ); TODO Fix XML Saving Stream */
+private:
+ /** Writes the contents of the SHEETEXT record. */
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclTabViewData& mrTabViewData; /// view settings data of current sheet.
+};
+
+// View settings ==============================================================
+
+/** Contains all view settings records for a single sheet. */
+class XclExpTabViewSettings : public XclExpRecordBase, protected XclExpRoot
+{
+public:
+ /** Creates all records containing the view settings of the specified sheet. */
+ explicit XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nScTab );
+
+ /** Writes all view settings records to the stream. */
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+
+private:
+ /** Creates selection data for the specified pane. */
+ void CreateSelectionData( sal_uInt8 nPane,
+ const ScAddress& rCursor, const ScRangeList& rSelection );
+
+ void WriteWindow2( XclExpStream& rStrm ) const;
+ void WriteScl( XclExpStream& rStrm ) const;
+ void WritePane( XclExpStream& rStrm ) const;
+ void WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane ) const;
+ void WriteTabBgColor( XclExpStream& rStrm ) const;
+
+private:
+ XclTabViewData maData; /// All view settings for a sheet.
+ sal_uInt32 mnGridColorId; /// Color identifier for grid color.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx
new file mode 100644
index 000000000000..a9440ee6d8ea
--- /dev/null
+++ b/sc/source/filter/inc/xichart.hxx
@@ -0,0 +1,1526 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XICHART_HXX
+#define SC_XICHART_HXX
+
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+
+#include <svl/itemset.hxx>
+
+#include "rangelst.hxx"
+#include "token.hxx"
+#include "xlchart.hxx"
+#include "xlstyle.hxx"
+#include "xiescher.hxx"
+#include "xistring.hxx"
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace awt
+ {
+ struct Rectangle;
+ }
+ namespace frame
+ {
+ class XModel;
+ }
+ namespace drawing
+ {
+ class XShape;
+ }
+ namespace chart2
+ {
+ struct ScaleData;
+ class XChartDocument;
+ class XDiagram;
+ class XCoordinateSystem;
+ class XChartType;
+ class XDataSeries;
+ class XRegressionCurve;
+ class XAxis;
+ class XLegend;
+ class XTitle;
+ class XFormattedString;
+ namespace data
+ {
+ class XDataProvider;
+ class XDataSequence;
+ class XLabeledDataSequence;
+ }
+ }
+} } }
+
+struct XclObjLineData;
+struct XclObjFillData;
+
+// Common =====================================================================
+
+class ScfProgressBar;
+struct XclImpChRootData;
+class XclImpChChart;
+class ScTokenArray;
+
+/** Base class for complex chart classes, provides access to other components of the chart. */
+class XclImpChRoot : public XclImpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+
+public:
+ explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData );
+ virtual ~XclImpChRoot();
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclImpChRoot& GetChRoot() const { return *this; }
+ /** Returns a reference to the parent chart data object. */
+ XclImpChChart& GetChartData() const;
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for an Excel chart type record identifier. */
+ const XclChTypeInfo& GetChartTypeInfo( sal_uInt16 nRecId ) const;
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+ /** Returns the default text color for charts. */
+ Color GetFontAutoColor() const;
+ /** Returns the automatic line color of linear series. */
+ Color GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const;
+ /** Returns the automatic fill color of filled series. */
+ Color GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const;
+
+ /** Starts the API chart document conversion. Must be called once before all API conversion. */
+ void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
+ /** Finishes the API chart document conversion. Must be called once after all API conversion. */
+ void FinishConversion( XclImpDffConverter& rDffConv ) const;
+
+ /** Returns the data provider for the chart document. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >
+ GetDataProvider() const;
+ /** Returns the drawing shape interface of the specified title object. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ GetTitleShape( const XclChTextKey& rTitleKey ) const;
+
+ /** Converts the passed horizontal coordinate from Excel chart units into 1/100 mm. */
+ sal_Int32 CalcHmmFromChartX( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from Excel chart units into 1/100 mm. */
+ sal_Int32 CalcHmmFromChartY( sal_Int32 nPosY ) const;
+ /** Converts the passed rectangle from Excel chart units into 1/100 mm. */
+ ::com::sun::star::awt::Rectangle CalcHmmFromChartRect( const XclChRectangle& rRect ) const;
+
+ /** Converts the passed horizontal coordinate from 1/100 mm into a relative position. */
+ double CalcRelativeFromHmmX( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from 1/100 mm into a relative position. */
+ double CalcRelativeFromHmmY( sal_Int32 nPosY ) const;
+
+ /** Converts the passed horizontal coordinate from Excel chart units into a relative position. */
+ double CalcRelativeFromChartX( sal_Int32 nPosX ) const;
+ /** Converts the passed vertical coordinate from Excel chart units into a relative position. */
+ double CalcRelativeFromChartY( sal_Int32 nPosY ) const;
+
+ /** Writes all line properties to the passed property set. */
+ void ConvertLineFormat(
+ ScfPropertySet& rPropSet,
+ const XclChLineFormat& rLineFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes solid area properties to the passed property set. */
+ void ConvertAreaFormat(
+ ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes gradient or bitmap area properties to the passed property set. */
+ void ConvertEscherFormat(
+ ScfPropertySet& rPropSet,
+ const XclChEscherFormat& rEscherFmt,
+ const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode ) const;
+ /** Writes font properties to the passed property set. */
+ void ConvertFont(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nFontIdx,
+ const Color* pFontColor = 0 ) const;
+
+ /** Writes the pie rotation property for the passed angle. */
+ static void ConvertPieRotation(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nAngle );
+
+private:
+ typedef boost::shared_ptr< XclImpChRootData > XclImpChRootDataRef;
+ XclImpChRootDataRef mxChData; /// Reference to the root data object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for chart record groups. Provides helper functions to read sub records.
+
+ A chart record group consists of a header record, followed by a CHBEGIN
+ record, followed by group sub records, and finished with a CHEND record.
+ */
+class XclImpChGroupBase
+{
+public:
+ virtual ~XclImpChGroupBase();
+
+ /** Reads the entire record group.
+ @descr First calls ReadHeaderRecord() to read the contents of the
+ header record. Then tries to read the sub records. If next record
+ is a CHBEGIN record, ReadSubRecord() is called for each following
+ record until a CHEND record is found. */
+ void ReadRecordGroup( XclImpStream& rStrm );
+
+ /** Helper to skip a CHBEGIN/CHEND block, includes nested blocks. */
+ static void SkipBlock( XclImpStream& rStrm );
+
+ /** Derived classes implement to read the group header record. */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm ) = 0;
+ /** Derived classes implement to read a record from the group. */
+ virtual void ReadSubRecord( XclImpStream& rStrm ) = 0;
+};
+
+// Frame formatting ===========================================================
+
+class XclImpChFramePos
+{
+public:
+ /** Reads the CHFRAMEPOS record (frame position and size). */
+ void ReadChFramePos( XclImpStream& rStrm );
+
+ /** Returns read-only access to the imported frame position data. */
+ inline const XclChFramePos& GetFramePosData() const { return maData; }
+
+private:
+ XclChFramePos maData; /// Position of the frame.
+};
+
+typedef boost::shared_ptr< XclImpChFramePos > XclImpChFramePosRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHLINEFORMAT record containing line formatting data. */
+class XclImpChLineFormat
+{
+public:
+ /** Creates a new line format object with automatic formatting. */
+ inline explicit XclImpChLineFormat() {}
+ /** Creates a new line format object with the passed formatting. */
+ inline explicit XclImpChLineFormat( const XclChLineFormat& rLineFmt ) : maData( rLineFmt ) {}
+
+ /** Reads the CHLINEFORMAT record (basic line properties). */
+ void ReadChLineFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO ); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return IsAuto() || (maData.mnPattern != EXC_CHLINEFORMAT_NONE); }
+ /** Returns the line width of this line format (returns 'single', if the line is invisible). */
+ inline sal_Int16 GetWeight() const { return (IsAuto() || !HasLine()) ? EXC_CHLINEFORMAT_SINGLE : maData.mnWeight; }
+ /** Returns true, if the "show axis" flag is set. */
+ inline bool IsShowAxis() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS ); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+private:
+ XclChLineFormat maData; /// Contents of the CHLINEFORMAT record.
+};
+
+typedef boost::shared_ptr< XclImpChLineFormat > XclImpChLineFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHAREAFORMAT record containing simple area formatting data (solid or patterns). */
+class XclImpChAreaFormat
+{
+public:
+ /** Creates a new area format object with automatic formatting. */
+ inline explicit XclImpChAreaFormat() {}
+ /** Creates a new area format object with the passed formatting. */
+ inline explicit XclImpChAreaFormat( const XclChAreaFormat& rAreaFmt ) : maData( rAreaFmt ) {}
+
+ /** Reads the CHAREAFORMAT record (basic fill properties, e.g. transparent or colored). */
+ void ReadChAreaFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO ); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return IsAuto() || (maData.mnPattern != EXC_PATT_NONE); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+private:
+ XclChAreaFormat maData; /// Contents of the CHAREAFORMAT record.
+};
+
+typedef boost::shared_ptr< XclImpChAreaFormat > XclImpChAreaFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHESCHERFORMAT record containing complex area formatting data (bitmaps, hatches). */
+class XclImpChEscherFormat : public XclImpChGroupBase
+{
+public:
+ explicit XclImpChEscherFormat( const XclImpRoot& rRoot );
+
+ /** Reads the CHESCHERFORMAT record (complex fill data) (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHESCHERFORMAT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;
+
+private:
+ XclChEscherFormat maData; /// Fill properties for complex areas (CHESCHERFORMAT record).
+ XclChPicFormat maPicFmt; /// Image options, e.g. stretched, stacked (CHPICFORMAT record).
+};
+
+typedef boost::shared_ptr< XclImpChEscherFormat > XclImpChEscherFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Base class for record groups containing frame formatting.
+
+ Frame formatting can be part of several record groups, e.g. CHFRAME,
+ CHDATAFORMAT, CHDROPBAR. It consists of CHLINEFORMAT, CHAREAFORMAT, and
+ CHESCHERFORMAT group.
+ */
+class XclImpChFrameBase : public XclImpChGroupBase
+{
+public:
+ /** Creates a new frame object without internal formatting objects. */
+ inline explicit XclImpChFrameBase() {}
+ /** Creates a new frame object with specific default formatting. */
+ explicit XclImpChFrameBase( const XclChFormatInfo& rFmtInfo );
+
+ /** Reads a frame formatting record (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Returns true, if the line format is set to automatic. */
+ inline bool IsAutoLine() const { return !mxLineFmt || mxLineFmt->IsAuto(); }
+ /** Returns true, if the line style is set to something visible. */
+ inline bool HasLine() const { return IsAutoLine() || mxLineFmt->HasLine(); }
+ /** Returns the line weight used for this frame. */
+ inline sal_Int16 GetLineWeight() const { return mxLineFmt ? mxLineFmt->GetWeight() : EXC_CHLINEFORMAT_SINGLE; }
+
+ /** Returns true, if the area format is set to automatic. */
+ inline bool IsAutoArea() const { return !mxEscherFmt && (!mxAreaFmt || mxAreaFmt->IsAuto()); }
+ /** Returns true, if the area style is set to something visible. */
+ inline bool HasArea() const { return mxEscherFmt || IsAutoArea() || mxAreaFmt->HasArea(); }
+
+protected:
+ /** Converts and writes the contained line formatting to the passed property set. */
+ void ConvertLineBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+ /** Converts and writes the contained area formatting to the passed property set. */
+ void ConvertAreaBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+ /** Converts and writes the contained data to the passed property set. */
+ void ConvertFrameBase( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, XclChObjectType eObjType,
+ sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
+
+protected:
+ XclImpChLineFormatRef mxLineFmt; /// Line format (CHLINEFORMAT record).
+ XclImpChAreaFormatRef mxAreaFmt; /// Area format (CHAREAFORMAT record).
+ XclImpChEscherFormatRef mxEscherFmt; /// Complex area format (CHESCHERFORMAT record).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHFRAME record group containing object frame properties.
+
+ The CHFRAME group consists of: CHFRAME, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclImpChFrame : public XclImpChFrameBase, protected XclImpChRoot
+{
+public:
+ /** Creates a new frame object with specific default formatting. */
+ explicit XclImpChFrame(
+ const XclImpChRoot& rRoot,
+ XclChObjectType eObjType );
+
+ /** Reads the CHFRAME record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChFrame maData; /// Contents of the CHFRAME record.
+ XclChObjectType meObjType; /// Type of the represented object.
+};
+
+typedef boost::shared_ptr< XclImpChFrame > XclImpChFrameRef;
+
+// Source links ===============================================================
+
+class XclImpChSourceLink : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > XDataSequenceRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > XFormattedStringRef;
+ typedef ::com::sun::star::uno::Sequence< XFormattedStringRef > XFormattedStringSeq;
+
+public:
+ explicit XclImpChSourceLink( const XclImpChRoot& rRoot );
+ virtual ~XclImpChSourceLink();
+
+ /** Reads the CHSOURCELINK record (link to source data). */
+ void ReadChSourceLink( XclImpStream& rStrm );
+ /** Sets explicit string data for this text object. */
+ void SetString( const String& rString );
+ /** Sets formatting runs read from a CHFORMATRUNS record. */
+ void SetTextFormats( const XclFormatRunVec& rFormats );
+
+ /** Returns the destination object (title, values, category, ...). */
+ inline sal_uInt8 GetDestType() const { return maData.mnDestType; }
+ /** Returns the link type (to worksheet, directly, default, ...). */
+ inline sal_uInt8 GetLinkType() const { return maData.mnLinkType; }
+
+ /** Returns true, if the source link contains explicit string data. */
+ inline bool HasString() const { return mxString && !mxString->IsEmpty(); }
+ /** Returns explicit string data or an empty string. */
+ inline const String& GetString() const { return mxString ? mxString->GetText() : String::EmptyString(); }
+ /** Returns the number of data points of this source link. */
+ sal_uInt16 GetCellCount() const;
+
+ /** Converts and writes the contained number format to the passed property set. */
+ void ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;
+
+ /** Creates a data sequence containing the link into the Calc document. */
+ XDataSequenceRef CreateDataSequence( const ::rtl::OUString& rRole ) const;
+ /** Creates a sequence of formatted string objects. */
+ XFormattedStringSeq CreateStringSequence( const XclImpChRoot& rRoot,
+ sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const;
+
+ void FillSourceLink(::std::vector<ScTokenRef>& rTokens) const;
+
+private:
+ XclChSourceLink maData; /// Contents of the CHSOURCELINK record.
+ XclImpStringRef mxString; /// Text data (CHSTRING record).
+ boost::shared_ptr< ScTokenArray> mxTokenArray; /// Token array representing the data ranges.
+};
+
+typedef boost::shared_ptr< XclImpChSourceLink > XclImpChSourceLinkRef;
+
+// Text =======================================================================
+
+/** Base class for objects with font settings. Provides font conversion helper functions. */
+class XclImpChFontBase
+{
+public:
+ virtual ~XclImpChFontBase();
+
+ /** Derived classes return the leading font index for the text object. */
+ virtual sal_uInt16 GetFontIndex() const = 0;
+ /** Derived classes return the leading font color for the text object. */
+ virtual Color GetFontColor() const = 0;
+ /** Derived classes return the rotation value for the text object. */
+ virtual sal_uInt16 GetRotation() const = 0;
+
+ /** Converts and writes the contained font settings to the passed property set. */
+ void ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained rotation settings to the passed property set. */
+ void ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** The CHFONT record containing a font index for text objects. */
+class XclImpChFont
+{
+public:
+ explicit XclImpChFont();
+ /** Reads the CHFONT record (font index). */
+ void ReadChFont( XclImpStream& rStrm );
+
+ /** Returns the contained font index. */
+ inline sal_uInt16 GetFontIndex() const { return mnFontIdx; }
+
+private:
+ sal_uInt16 mnFontIdx; /// Index into font buffer.
+};
+
+typedef boost::shared_ptr< XclImpChFont > XclImpChFontRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTEXT record group containing text object properties.
+
+ The CHTEXT group consists of: CHTEXT, CHBEGIN, CHFRAMEPOS, CHFONT,
+ CHFORMATRUNS, CHSOURCELINK, CHSTRING, CHFRAME group, CHOBJECTLINK, and CHEND.
+ */
+class XclImpChText : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > XTitleRef;
+
+public:
+ explicit XclImpChText( const XclImpChRoot& rRoot );
+
+ /** Reads the CHTEXT record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHTEXT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Returns the leading font index for the text object. */
+ virtual sal_uInt16 GetFontIndex() const;
+ /** Returns the leading font color for the text object. */
+ virtual Color GetFontColor() const;
+ /** Returns the rotation value for the text object. */
+ virtual sal_uInt16 GetRotation() const;
+
+ /** Sets explicit string data for this text object. */
+ void SetString( const String& rString );
+ /** Updates missing parts of this text object from the passed object. */
+ void UpdateText( const XclImpChText* pParentText );
+ /** Updates display type of this data point label text object. */
+ void UpdateDataLabel( bool bCateg, bool bValue, bool bPercent );
+
+ /** Returns the target object this text is linked to. */
+ inline sal_uInt16 GetLinkTarget() const { return maObjLink.mnTarget; }
+ /** Returns the position of the data point label this text is linked to. */
+ inline const XclChDataPointPos& GetPointPos() const { return maObjLink.maPointPos; }
+ /** Returns true, if this text group contains string data. */
+ inline bool HasString() const { return mxSrcLink && mxSrcLink->HasString(); }
+ /** Returns true, if the text object is marked as deleted. */
+ inline bool IsDeleted() const { return ::get_flag( maData.mnFlags, EXC_CHTEXT_DELETED ); }
+
+ /** Converts and writes the contained font settings to the passed property set. */
+ void ConvertFont( ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained rotation settings to the passed property set. */
+ void ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
+ /** Converts and writes the contained frame data to the passed property set. */
+ void ConvertFrame( ScfPropertySet& rPropSet ) const;
+ /** Converts and writes the contained number format to the passed property set. */
+ void ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;
+ /** Converts and writes all contained data to the passed data point label property set. */
+ void ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const;
+ /** Creates a title text object. */
+ XTitleRef CreateTitle() const;
+ /** Converts the manual position of the specified title */
+ void ConvertTitlePosition( const XclChTextKey& rTitleKey ) const;
+
+private:
+ using XclImpChRoot::ConvertFont;
+
+ /** Reads a CHFRLABELPROPS record. */
+ void ReadChFrLabelProps( XclImpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclChFrLabelProps > XclChFrLabelPropsRef;
+
+ XclChText maData; /// Contents of the CHTEXT record.
+ XclChObjectLink maObjLink; /// Link target for this text object.
+ XclFormatRunVec maFormats; /// Formatting runs (CHFORMATRUNS record).
+ XclImpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
+ XclImpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
+ XclImpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
+ XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclChFrLabelPropsRef mxLabelProps; /// Extended data label properties (CHFRLABELPROPS record).
+};
+
+typedef boost::shared_ptr< XclImpChText > XclImpChTextRef;
+
+// Data series ================================================================
+
+/** The CHMARKERFORMAT record containing data point marker formatting data. */
+class XclImpChMarkerFormat
+{
+public:
+ /** Reads the CHMARKERFORMAT record (data point marker properties). */
+ void ReadChMarkerFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the marker format is set to automatic. */
+ inline bool IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO ); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet,
+ sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const;
+ /** Sets the marker fill color as main color to the passed property set. */
+ void ConvertColor( const XclImpChRoot& rRoot,
+ ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;
+
+private:
+ XclChMarkerFormat maData; /// Contents of the CHMARKERFORMAT record.
+};
+
+typedef boost::shared_ptr< XclImpChMarkerFormat > XclImpChMarkerFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHPIEFORMAT record containing data point formatting data for pie segments. */
+class XclImpChPieFormat
+{
+public:
+ explicit XclImpChPieFormat();
+ /** Reads the CHPIEFORMAT record (pie segment properties). */
+ void ReadChPieFormat( XclImpStream& rStrm );
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ sal_uInt16 mnPieDist; /// Pie distance to diagram center.
+};
+
+typedef boost::shared_ptr< XclImpChPieFormat > XclImpChPieFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHSERIESFORMAT record containing additional settings for a data series. */
+class XclImpChSeriesFormat
+{
+public:
+ explicit XclImpChSeriesFormat();
+ /** Reads the CHSERIESFORMAT record (additional settings for a series). */
+ void ReadChSeriesFormat( XclImpStream& rStrm );
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return ::get_flag( mnFlags, EXC_CHSERIESFORMAT_SMOOTHED ); }
+
+private:
+ sal_uInt16 mnFlags; /// Additional flags.
+};
+
+typedef boost::shared_ptr< XclImpChSeriesFormat > XclImpChSeriesFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CH3DDATAFORMAT record containing the bar type in 3D bar charts. */
+class XclImpCh3dDataFormat
+{
+public:
+ /** Reads the CH3DDATAFORMAT record (3D bar properties). */
+ void ReadCh3dDataFormat( XclImpStream& rStrm );
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclCh3dDataFormat maData; /// Contents of the CH3DDATAFORMAT record.
+};
+
+typedef boost::shared_ptr< XclImpCh3dDataFormat > XclImpCh3dDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** The CHATTACHEDLABEL record that contains the type of a data point label. */
+class XclImpChAttachedLabel : protected XclImpChRoot
+{
+public:
+ explicit XclImpChAttachedLabel( const XclImpChRoot& rRoot );
+ /** Reads the CHATTACHEDLABEL record (data series/point labels). */
+ void ReadChAttachedLabel( XclImpStream& rStrm );
+ /** Creates a CHTEXT group for the label. Clones xParentText and sets additional label settings */
+ XclImpChTextRef CreateDataLabel( const XclImpChText* pParent ) const;
+
+private:
+ sal_uInt16 mnFlags; /// Additional flags.
+};
+
+typedef boost::shared_ptr< XclImpChAttachedLabel > XclImpChAttLabelRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDATAFORMAT record group containing data point properties.
+
+ The CHDATAFORMAT group consists of: CHDATAFORMAT, CHBEGIN, CHFRAME group,
+ CHMARKERFORMAT, CHPIEFORMAT, CH3DDATAFORMAT, CHSERIESFORMAT,
+ CHATTACHEDLABEL, CHEND.
+ */
+class XclImpChDataFormat : public XclImpChFrameBase, protected XclImpChRoot
+{
+public:
+ explicit XclImpChDataFormat( const XclImpChRoot& rRoot );
+
+ /** Reads the CHDATAFORMAT record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHDATAFORMAT group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Sets this object to the specified data point position. */
+ void SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx );
+ /** Sets type and text formatting for a data point label (CHTEXT group). */
+ inline void SetDataLabel( XclImpChTextRef xLabel ) { mxLabel = xLabel; }
+
+ /** Updates default data format for series group. */
+ void UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo );
+ /** Updates missing series settings from the passed chart type group data format. */
+ void UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt );
+ /** Updates missing data point settings from the passed series format. */
+ void UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt );
+ /** Updates default data format for trend lines. */
+ void UpdateTrendLineFormat();
+
+ /** Returns the position of the data point described by this group. */
+ inline const XclChDataPointPos& GetPointPos() const { return maData.maPointPos; }
+ /** Returns the format index of the data point described by this group. */
+ inline sal_uInt16 GetFormatIdx() const { return maData.mnFormatIdx; }
+ /** Returns true, if markers are set to automatic format. */
+ inline bool IsAutoMarker() const { return !mxMarkerFmt || mxMarkerFmt->IsAuto(); }
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return mxSeriesFmt && mxSeriesFmt->HasSpline(); }
+ /** Returns the data label text object. */
+ inline const XclImpChText* GetDataLabel() const { return mxLabel.get(); }
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const;
+ /** Writes the line format only, e.g. for trend lines or error bars. */
+ void ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;
+ /** Writes the area format only for the series or a data point. */
+ void ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;
+
+private:
+ /** Removes unused formatting (e.g. pie distance in a bar chart). */
+ void RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo );
+ /** Updates or creates the data point label. */
+ void UpdateDataLabel( const XclImpChDataFormat* pParentFmt );
+
+private:
+ XclChDataFormat maData; /// Contents of the CHDATAFORMAT record.
+ XclImpChMarkerFormatRef mxMarkerFmt; /// Data point marker (CHMARKERFORMAT record).
+ XclImpChPieFormatRef mxPieFmt; /// Pie segment format (CHPIEFORMAT record).
+ XclImpChSeriesFormatRef mxSeriesFmt; /// Series properties (CHSERIESFORMAT record).
+ XclImpCh3dDataFormatRef mx3dDataFmt; /// 3D bar format (CH3DDATAFORMAT record).
+ XclImpChAttLabelRef mxAttLabel; /// Data point label type (CHATTACHEDLABEL record).
+ XclImpChTextRef mxLabel; /// Data point label formatting (CHTEXT group).
+};
+
+typedef boost::shared_ptr< XclImpChDataFormat > XclImpChDataFormatRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERTRENDLINE record containing settings for a trend line. */
+class XclImpChSerTrendLine : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;
+
+public:
+ explicit XclImpChSerTrendLine( const XclImpChRoot& rRoot );
+
+ /** Reads the CHSERTRENDLINE record. */
+ void ReadChSerTrendLine( XclImpStream& rStrm );
+ /** Sets formatting information for the trend line. */
+ inline void SetDataFormat( XclImpChDataFormatRef xDataFmt ) { mxDataFmt = xDataFmt; }
+
+ /** Creates an API object representing this trend line. */
+ XRegressionCurveRef CreateRegressionCurve() const;
+
+private:
+ XclChSerTrendLine maData; /// Contents of the CHSERTRENDLINE record.
+ XclImpChDataFormatRef mxDataFmt; /// Formatting settings of the trend line.
+};
+
+typedef boost::shared_ptr< XclImpChSerTrendLine > XclImpChSerTrendLineRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERERRORBAR record containing settings for error bars. */
+class XclImpChSerErrorBar : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+
+public:
+ explicit XclImpChSerErrorBar( const XclImpChRoot& rRoot );
+
+ /** Reads the CHSERERRORBAR record. */
+ void ReadChSerErrorBar( XclImpStream& rStrm );
+ /** Sets link and formatting information for the error bars. */
+ void SetSeriesData(
+ XclImpChSourceLinkRef xValueLink,
+ XclImpChDataFormatRef xDataFmt );
+
+ /** Returns the type of this error bar (X/Y, plus/minus). */
+ inline sal_uInt8 GetBarType() const { return maData.mnBarType; }
+ /** Creates a labeled data sequence object from value data link. */
+ XLabeledDataSeqRef CreateValueSequence() const;
+
+ /** Tries to create an error bar API object from the specified Excel error bars. */
+ static XPropertySetRef CreateErrorBar(
+ const XclImpChSerErrorBar* pPosBar,
+ const XclImpChSerErrorBar* pNegBar );
+
+private:
+ XclChSerErrorBar maData; /// Contents of the CHSERERRORBAR record.
+ XclImpChSourceLinkRef mxValueLink; /// Link data for manual error bar values.
+ XclImpChDataFormatRef mxDataFmt; /// Formatting settings of the error bars.
+};
+
+typedef boost::shared_ptr< XclImpChSerErrorBar > XclImpChSerErrorBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHSERIES record group describing a data series in a chart.
+
+ The CHSERIES group consists of: CHSERIES, CHBEGIN, CHSOURCELINK groups,
+ CHDATAFORMAT groups, CHSERGROUP, CHSERPARENT, CHSERERRORBAR,
+ CHSERTRENDLINE, CHEND.
+ */
+class XclImpChSeries : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > XPropertySetRef;
+
+public:
+ explicit XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx );
+
+ /** Reads the CHSERIES record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHSERIES group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+
+ /** Sets a data point or series format (CHDATAFORMAT group) for this series. */
+ void SetDataFormat( XclImpChDataFormatRef xDataFmt );
+ /** Sets a label text (CHTEXT group) attached to a series or data point. */
+ void SetDataLabel( XclImpChTextRef xLabel );
+ /** Adds error bar settings from the passed series to the own series. */
+ void AddChildSeries( const XclImpChSeries& rSeries );
+ /** Updates missing series formatting by using default formatting from axes sets. */
+ void FinalizeDataFormats();
+
+ /** Returns the axes set identifier this series is assigned to (primary/secondary). */
+ inline sal_uInt16 GetGroupIdx() const { return mnGroupIdx; }
+ /** Returns the 0-based series index described by this series. */
+ inline sal_uInt16 GetSeriesIdx() const { return mnSeriesIdx; }
+ /** Returns the 0-based index of the parent series (e.g. of a trend line). */
+ inline sal_uInt16 GetParentIdx() const { return mnParentIdx; }
+ /** Returns the format index of the series used for automatic line and area colors. */
+ inline sal_uInt16 GetFormatIdx() const { return mxSeriesFmt ? mxSeriesFmt->GetFormatIdx() : EXC_CHDATAFORMAT_DEFAULT; }
+ /** Returns true, if the series is child of another series (e.g. trend line). */
+ inline bool HasParentSeries() const { return mnParentIdx != EXC_CHSERIES_INVALID; }
+ /** Returns true, if the series contains child series (e.g. trend lines). */
+ inline bool HasChildSeries() const { return !maTrendLines.empty() || !maErrorBars.empty(); }
+ /** Returns series title or an empty string, if the series does not contain a title. */
+ inline const String& GetTitle() const { return mxTitleLink ? mxTitleLink->GetString() : String::EmptyString(); }
+
+ /** Returns true, if the series line is smoothed. */
+ inline bool HasSpline() const { return mxSeriesFmt && mxSeriesFmt->HasSpline(); }
+
+ /** Creates a labeled data sequence object from value data link. */
+ XLabeledDataSeqRef CreateValueSequence( const ::rtl::OUString& rValueRole ) const;
+ /** Creates a labeled data sequence object from category data link. */
+ XLabeledDataSeqRef CreateCategSequence( const ::rtl::OUString& rCategRole ) const;
+ /** Creates a data series object with initialized source links. */
+ XDataSeriesRef CreateDataSeries() const;
+
+ void FillAllSourceLinks(::std::vector<ScTokenRef>& rTokens) const;
+
+private:
+ /** Reads a CHSOURCELINK record. */
+ void ReadChSourceLink( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT group containing series and point formatting. */
+ void ReadChDataFormat( XclImpStream& rStrm );
+ /** Reads a CHSERPARENT record specifying the parent series of this series. */
+ void ReadChSerParent( XclImpStream& rStrm );
+ /** Reads a CHSERTRENDLINE record containing trend line settings. */
+ void ReadChSerTrendLine( XclImpStream& rStrm );
+ /** Reads a CHSERERRORBAR record containing error bar settings. */
+ void ReadChSerErrorBar( XclImpStream& rStrm );
+
+ /** Creates a new CHDATAFORMAT group with the specified point index. */
+ XclImpChDataFormatRef CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx );
+ /** Returns the pointer to a CHDATAFORMAT group reference or 0 for invalid pointer index. */
+ XclImpChDataFormatRef* GetDataFormatRef( sal_uInt16 nPointIdx );
+ /** Returns the pointer to a CHTEXT group reference or 0 for invalid pointer index. */
+ XclImpChTextRef* GetDataLabelRef( sal_uInt16 nPointIdx );
+
+ /** Converts all trend lines and inserts them into the passed API data series object. */
+ void ConvertTrendLines( XDataSeriesRef xDataSeries ) const;
+ /** Tries to create an error bar API object from the specified Excel error bars. */
+ XPropertySetRef CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const;
+
+private:
+ typedef ::std::map<sal_uInt16, XclImpChDataFormatRef> XclImpChDataFormatMap;
+ typedef ::std::map<sal_uInt16, XclImpChTextRef> XclImpChTextMap;
+ typedef ::std::list< XclImpChSerTrendLineRef > XclImpChSerTrendLineList;
+ typedef ::boost::ptr_map<sal_uInt8, XclImpChSerErrorBar> XclImpChSerErrorBarMap;
+
+ XclChSeries maData; /// Contents of the CHSERIES record.
+ XclImpChSourceLinkRef mxValueLink; /// Link data for series values.
+ XclImpChSourceLinkRef mxCategLink; /// Link data for series category names.
+ XclImpChSourceLinkRef mxTitleLink; /// Link data for series title.
+ XclImpChSourceLinkRef mxBubbleLink; /// Link data for series bubble sizes.
+ XclImpChDataFormatRef mxSeriesFmt; /// CHDATAFORMAT group for series format.
+ XclImpChDataFormatMap maPointFmts; /// CHDATAFORMAT groups for data point formats.
+ XclImpChTextMap maLabels; /// Data point labels (CHTEXT groups).
+ XclImpChSerTrendLineList maTrendLines; /// Trend line settings (CHSERTRENDLINE records).
+ XclImpChSerErrorBarMap maErrorBars; /// Error bar settings (CHSERERRORBAR records).
+ sal_uInt16 mnGroupIdx; /// Chart type group (CHTYPEGROUP group) this series is assigned to.
+ sal_uInt16 mnSeriesIdx; /// 0-based series index.
+ sal_uInt16 mnParentIdx; /// 0-based index of parent series (trend lines and error bars).
+};
+
+typedef boost::shared_ptr< XclImpChSeries > XclImpChSeriesRef;
+
+// Chart type groups ==========================================================
+
+class XclImpChType : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+
+public:
+ explicit XclImpChType( const XclImpChRoot& rRoot );
+
+ /** Reads a chart type record (e.g. CHBAR, CHLINE, CHPIE, ...). */
+ void ReadChType( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize( bool bStockChart );
+
+ /** Returns the record identifier of the chart type record. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChTypeInfo& 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 chart type has category labels enabled (may be disabled in radar charts). */
+ bool HasCategoryLabels() const;
+
+ /** Creates a coordinate system according to the contained chart type. */
+ XCoordSystemRef CreateCoordSystem( bool b3dChart ) const;
+ /** Creates and returns an object that represents the contained chart type. */
+ XChartTypeRef CreateChartType( XDiagramRef xDiagram, bool b3dChart ) const;
+
+private:
+ XclChType maData; /// Contents of the chart type record.
+ sal_uInt16 mnRecId; /// Record identifier for chart type.
+ XclChTypeInfo maTypeInfo; /// Chart type info for the contained type.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHCHART3D record that contains 3D view settings. */
+class XclImpChChart3d
+{
+public:
+ /** Reads the CHCHART3D record (properties for 3D charts). */
+ void ReadChChart3d( XclImpStream& rStrm );
+ /** Returns true, if the data points are clustered on the X axis. */
+ inline bool IsClustered() const { return ::get_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const;
+
+private:
+ XclChChart3d maData; /// Contents of the CHCHART3D record.
+};
+
+typedef boost::shared_ptr< XclImpChChart3d > XclImpChChart3dRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHLEGEND record group describing the chart legend.
+
+ The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
+ group, CHTEXT group, CHEND.
+ */
+class XclImpChLegend : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XLegend > XLegendRef;
+
+public:
+ explicit XclImpChLegend( const XclImpChRoot& rRoot );
+
+ /** Reads the CHLEGEND record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHLEGEND group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Creates a new legend object. */
+ XLegendRef CreateLegend() const;
+
+private:
+ XclChLegend maData; /// Contents of the CHLEGEND record.
+ XclImpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
+ XclImpChTextRef mxText; /// Legend text format (CHTEXT group).
+ XclImpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
+};
+
+typedef boost::shared_ptr< XclImpChLegend > XclImpChLegendRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHDROPBAR record group describing pos/neg bars in line charts.
+
+ The CHDROPBAR group consists of: CHDROPBAR, CHBEGIN, CHLINEFORMAT,
+ CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
+ */
+class XclImpChDropBar : public XclImpChFrameBase
+{
+public:
+ explicit XclImpChDropBar( sal_uInt16 nDropBar );
+
+ /** Reads the CHDROPBAR record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+
+ /** Converts and writes the contained frame data to the passed property set. */
+ void Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;
+
+private:
+ sal_uInt16 mnDropBar; /// Drop bar identifier, needed for auto format.
+ sal_uInt16 mnBarDist; /// Distance between bars (CHDROPBAR record).
+};
+
+typedef boost::shared_ptr< XclImpChDropBar > XclImpChDropBarRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHTYPEGROUP record group describing a group of series.
+
+ The CHTYPEGROUP group consists of: CHTYPEGROUP, CHBEGIN, a chart type
+ record (e.g. CHBAR, CHLINE, CHAREA, CHPIE, ...), CHCHART3D, CHLEGEND group,
+ CHDEFAULTTEXT groups (CHDEFAULTTEXT with CHTEXT groups), CHDROPBAR groups,
+ CHCHARTLINE groups (CHCHARTLINE with CHLINEFORMAT), CHDATAFORMAT group,
+ CHEND.
+ */
+class XclImpChTypeGroup : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > XChartTypeRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > XDataSeriesRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence > XLabeledDataSeqRef;
+
+public:
+ explicit XclImpChTypeGroup( const XclImpChRoot& rRoot );
+
+ /** Reads the CHTYPEGROUP record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHTYPEGROUP group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Inserts a series attached to this chart type group.*/
+ void AddSeries( XclImpChSeriesRef xSeries );
+ /** Marks the passed format index as used. PopUnusedFormatIndex() will not return this index. */
+ void SetUsedFormatIndex( sal_uInt16 nFormatIdx );
+ /** Returns the next unused format index and marks it as used. */
+ sal_uInt16 PopUnusedFormatIndex();
+
+ /** Returns the index of this chart type group. */
+ inline sal_uInt16 GetGroupIdx() const { return maData.mnGroupIdx; }
+ /** Returns the chart type info struct for the contained chart type. */
+ inline const XclChExtTypeInfo& GetTypeInfo() const { return maTypeInfo; }
+ /** Returns true, if this chart type group contains at least one valid series. */
+ inline bool IsValidGroup() const { return !maSeries.empty(); }
+ /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
+ inline bool IsStacked() const { return maType.IsStacked(); }
+ /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
+ inline bool IsPercent() const { return maType.IsPercent(); }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool Is3dChart() const { return mxChart3d && maTypeInfo.mbSupports3d; }
+ /** Returns true, if chart type supports wall and floor format in 3d mode. */
+ inline bool Is3dWallChart() const { return Is3dChart() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE); }
+ /** Returns true, if the series in this chart type group are ordered on the Z axis. */
+ inline bool Is3dDeepChart() const { return Is3dWallChart() && mxChart3d && !mxChart3d->IsClustered(); }
+ /** Returns true, if category (X axis) labels are enabled (may be disabled in radar charts). */
+ inline bool HasCategoryLabels() const { return maType.HasCategoryLabels(); }
+ /** Returns true, if points of a series show varying automatic area format. */
+ bool HasVarPointFormat() const;
+ /** Returns true, if bars are connected with lines (stacked bar charts only). */
+ bool HasConnectorLines() const;
+
+ /** Returns the legend object. */
+ inline XclImpChLegendRef GetLegend() const { return mxLegend; }
+ /** Returns the default series data format. */
+ inline XclImpChDataFormatRef GetGroupFormat() const { return mxGroupFmt; }
+ /** Returns series title, if the chart type group contains only one single series. */
+ const String& GetSingleSeriesTitle() const;
+
+ /** Converts and writes all 3D settings to the passed diagram. */
+ void ConvertChart3d( ScfPropertySet& rPropSet ) const;
+ /** Creates a coordinate system according to the contained chart type. */
+ XCoordSystemRef CreateCoordSystem() const;
+ /** Creates and returns an object that represents the contained chart type. */
+ XChartTypeRef CreateChartType( XDiagramRef xDiagram, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates a labeled data sequence object for axis categories. */
+ XLabeledDataSeqRef CreateCategSequence() const;
+
+private:
+ /** Reads a CHDROPBAR record group. */
+ void ReadChDropBar( XclImpStream& rStrm );
+ /** Reads a CHCHARTLINE record group. */
+ void ReadChChartLine( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT record group (default series format). */
+ void ReadChDataFormat( XclImpStream& rStrm );
+
+ /** Returns true, if the chart type group contains a hi-lo line format. */
+ inline bool HasHiLoLine() const { return maChartLines.find( EXC_CHCHARTLINE_HILO ) != maChartLines.end(); }
+ /** Returns true, if the chart type group contains drop bar formats. */
+ inline bool HasDropBars() const { return !maDropBars.empty(); }
+
+ /** Inserts the passed series into the chart type. Adds additional properties to the series. */
+ void InsertDataSeries( XChartTypeRef xChartType,
+ XDataSeriesRef xSeries, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates all data series of any chart type except stock charts. */
+ void CreateDataSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;
+ /** Creates all data series of of a stock chart. */
+ void CreateStockSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;
+
+private:
+ typedef ::std::vector< XclImpChSeriesRef > XclImpChSeriesVec;
+ typedef boost::ptr_map<sal_uInt16, XclImpChDropBar> XclImpChDropBarMap;
+ typedef boost::ptr_map<sal_uInt16, XclImpChLineFormat> XclImpChLineFormatMap;
+ typedef ::std::set< sal_uInt16 > UInt16Set;
+
+ XclChTypeGroup maData; /// Contents of the CHTYPEGROUP record.
+ XclImpChType maType; /// Chart type (e.g. CHBAR, CHLINE, ...).
+ XclChExtTypeInfo maTypeInfo; /// Extended chart type info.
+ XclImpChSeriesVec maSeries; /// Series attached to this chart type group (CHSERIES groups).
+ XclImpChSeriesRef mxFirstSeries; /// First series in this chart type group (CHSERIES groups).
+ XclImpChChart3dRef mxChart3d; /// 3D settings (CHCHART3D record).
+ XclImpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+ XclImpChDropBarMap maDropBars; /// Dropbars (CHDROPBAR group).
+ XclImpChLineFormatMap maChartLines; /// Global line formats (CHCHARTLINE group).
+ XclImpChDataFormatRef mxGroupFmt; /// Default format for all series (CHDATAFORMAT group).
+ UInt16Set maUnusedFormats; /// Contains unused format indexes for automatic colors.
+};
+
+typedef boost::shared_ptr< XclImpChTypeGroup > XclImpChTypeGroupRef;
+
+// Axes =======================================================================
+
+class XclImpChLabelRange : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::chart2::ScaleData ScaleData;
+
+public:
+ explicit XclImpChLabelRange( const XclImpChRoot& rRoot );
+ /** Reads the CHLABELRANGE record (category axis scaling properties). */
+ void ReadChLabelRange( XclImpStream& rStrm );
+ /** Reads the CHDATERANGE record (date axis scaling properties). */
+ void ReadChDateRange( XclImpStream& rStrm );
+ /** Converts category axis scaling settings. */
+ void Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const;
+
+private:
+ XclChLabelRange maLabelData; /// Contents of the CHLABELRANGE record.
+ XclChDateRange maDateData; /// Contents of the CHDATERANGE record.
+};
+
+typedef boost::shared_ptr< XclImpChLabelRange > XclImpChLabelRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclImpChValueRange : protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::chart2::ScaleData ScaleData;
+
+public:
+ explicit XclImpChValueRange( const XclImpChRoot& rRoot );
+ /** Reads the CHVALUERANGE record (numeric axis scaling properties). */
+ void ReadChValueRange( XclImpStream& rStrm );
+ /** Converts value axis scaling settings. */
+ void Convert( ScaleData& rScaleData, bool bMirrorOrient ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChValueRange maData; /// Contents of the CHVALUERANGE record.
+};
+
+typedef boost::shared_ptr< XclImpChValueRange > XclImpChValueRangeRef;
+
+// ----------------------------------------------------------------------------
+
+class XclImpChTick : protected XclImpChRoot
+{
+public:
+ explicit XclImpChTick( const XclImpChRoot& rRoot );
+ /** Reads the CHTICK record (axis ticks properties). */
+ void ReadChTick( XclImpStream& rStrm );
+
+ /** Returns true, if the axis shows attached labels. */
+ inline bool HasLabels() const { return maData.mnLabelPos != EXC_CHTICK_NOLABEL; }
+ /** Returns the leading font color for the axis labels. */
+ Color GetFontColor() const;
+ /** Returns the rotation value for the axis labels. */
+ sal_uInt16 GetRotation() const;
+
+ /** Converts and writes the contained data to the passed property set. */
+ void Convert( ScfPropertySet& rPropSet ) const;
+
+private:
+ XclChTick maData; /// Contents of the CHTICK record.
+};
+
+typedef boost::shared_ptr< XclImpChTick > XclImpChTickRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXIS record group describing an entire chart axis.
+
+ The CHAXIS group consists of: CHAXIS, CHBEGIN, CHLABELRANGE, CHEXTRANGE,
+ CHVALUERANGE, CHFORMAT, CHTICK, CHFONT, CHAXISLINE groups (CHAXISLINE with
+ CHLINEFORMAT, CHAREAFORMAT, and CHESCHERFORMAT group), CHEND.
+ */
+class XclImpChAxis : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+
+public:
+ explicit XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType = EXC_CHAXIS_NONE );
+
+ /** Reads the CHAXIS record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHAXIS group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Returns the font index for the axis labels. */
+ virtual sal_uInt16 GetFontIndex() const;
+ /** Returns the font color for the axis labels. */
+ virtual Color GetFontColor() const;
+ /** Returns the rotation value for axis labels. */
+ virtual sal_uInt16 GetRotation() const;
+
+ /** Returns the type of this axis. */
+ inline sal_uInt16 GetAxisType() const { return maData.mnType; }
+ /** Returns the axis dimension index used by the chart API. */
+ inline sal_Int32 GetApiAxisDimension() const { return maData.GetApiAxisDimension(); }
+ /** Returns true, if the axis is active. */
+ inline bool IsActivated() const { return !mxAxisLine || mxAxisLine->IsShowAxis(); }
+ /** Returns true, if the axis contains caption labels. */
+ inline bool HasLabels() const { return !mxTick || mxTick->HasLabels(); }
+ /** Returns true, if the axis shows its major grid lines. */
+ inline bool HasMajorGrid() const { return mxMajorGrid; }
+ /** Returns true, if the axis shows its minor grid lines. */
+ inline bool HasMinorGrid() const { return mxMinorGrid; }
+
+ /** Creates an API axis object. */
+ XAxisRef CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const;
+ /** Converts and writes 3D wall/floor properties to the passed property set. */
+ void ConvertWall( ScfPropertySet& rPropSet ) const;
+ /** Converts position settings of this axis at a crossing axis. */
+ void ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const;
+
+private:
+ /** Reads a CHAXISLINE record specifying the target for following line properties. */
+ void ReadChAxisLine( XclImpStream& rStrm );
+ /** Creates a CHFRAME object and stores it into the mxWallFrame member. */
+ void CreateWallFrame();
+
+private:
+ XclChAxis maData; /// Contents of the CHAXIS record.
+ XclImpChLabelRangeRef mxLabelRange; /// Category scaling (CHLABELRANGE record).
+ XclImpChValueRangeRef mxValueRange; /// Value scaling (CHVALUERANGE record).
+ XclImpChTickRef mxTick; /// Axis ticks (CHTICK record).
+ XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record).
+ XclImpChLineFormatRef mxAxisLine; /// Axis line format (CHLINEFORMAT record).
+ XclImpChLineFormatRef mxMajorGrid; /// Major grid line format (CHLINEFORMAT record).
+ XclImpChLineFormatRef mxMinorGrid; /// Minor grid line format (CHLINEFORMAT record).
+ XclImpChFrameRef mxWallFrame; /// Wall/floor format (sub records of CHFRAME group).
+ sal_uInt16 mnNumFmtIdx; /// Index into number format buffer (CHFORMAT record).
+};
+
+typedef boost::shared_ptr< XclImpChAxis > XclImpChAxisRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents the CHAXESSET record group describing an axes set (X/Y/Z axes).
+
+ The CHAXESSET group consists of: CHAXESSET, CHBEGIN, CHFRAMEPOS, CHAXIS
+ groups, CHTEXT groups, CHPLOTFRAME group (CHPLOTFRAME with CHFRAME group),
+ CHTYPEGROUP group, CHEND.
+ */
+class XclImpChAxesSet : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;
+
+public:
+ explicit XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId );
+
+ /** Reads the CHAXESSET record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHAXESSET group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Final processing after reading the entire chart. */
+ void Finalize();
+
+ /** Returns true, if this axes set exists (returns false if this is a dummy object). */
+ inline bool IsValidAxesSet() const { return !maTypeGroups.empty(); }
+ /** Returns the index of the axes set (primary/secondary). */
+ inline sal_uInt16 GetAxesSetId() const { return maData.mnAxesSetId; }
+ /** Returns the axes set index used by the chart API. */
+ inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }
+
+ /** Returns the outer plot area position, if existing. */
+ inline XclImpChFramePosRef GetPlotAreaFramePos() const { return mxFramePos; }
+ /** Returns the specified chart type group. */
+ XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const;
+ /** Returns the first chart type group. */
+ XclImpChTypeGroupRef GetFirstTypeGroup() const;
+ /** Looks for a legend in all chart type groups and returns it. */
+ XclImpChLegendRef GetLegend() const;
+ /** Returns series title, if the axes set contains only one single series. */
+ const String& GetSingleSeriesTitle() const;
+
+ /** Creates a coordinate system and converts all series and axis settings. */
+ void Convert( XDiagramRef xDiagram ) const;
+ /** Converts the manual positions of all axis titles. */
+ void ConvertTitlePositions() const;
+
+private:
+ /** Reads a CHAXIS record group containing a single axis. */
+ void ReadChAxis( XclImpStream& rStrm );
+ /** Reads a CHTEXT record group containing an axis title. */
+ void ReadChText( XclImpStream& rStrm );
+ /** Reads the CHPLOTFRAME record group containing diagram area formatting. */
+ void ReadChPlotFrame( XclImpStream& rStrm );
+ /** Reads a CHTYPEGROUP record group containing chart type and chart settings. */
+ void ReadChTypeGroup( XclImpStream& rStrm );
+
+ /** Updates text formatting of the passed axis title with global text formatting. */
+ void UpdateAxisTitle( XclImpChTextRef xTitle );
+
+ /** Creates a coordinate system that contains all chart types for this axes set. */
+ XCoordSystemRef CreateCoordSystem( XDiagramRef xDiagram ) const;
+ /** Creates and inserts an axis into the container and registers the coordinate system. */
+ void ConvertAxis( XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
+ XCoordSystemRef xCoordSystem, const XclImpChAxis* pCrossingAxis ) const;
+ /** Creates and returns an API axis object. */
+ XAxisRef CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const;
+ /** Writes all properties of the background area to the passed diagram. */
+ void ConvertBackground( XDiagramRef xDiagram ) const;
+
+private:
+ typedef ::std::map<sal_uInt16, XclImpChTypeGroupRef> XclImpChTypeGroupMap;
+
+ XclChAxesSet maData; /// Contents of the CHAXESSET record.
+ XclImpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
+ XclImpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
+ XclImpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
+ XclImpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
+ XclImpChTextRef mxXAxisTitle; /// The X axis title (CHTEXT group).
+ XclImpChTextRef mxYAxisTitle; /// The Y axis title (CHTEXT group).
+ XclImpChTextRef mxZAxisTitle; /// The Z axis title (CHTEXT group).
+ XclImpChFrameRef mxPlotFrame; /// Plot area (CHPLOTFRAME group).
+ XclImpChTypeGroupMap maTypeGroups; /// Chart type groups (CHTYPEGROUP group).
+};
+
+typedef boost::shared_ptr< XclImpChAxesSet > XclImpChAxesSetRef;
+
+// The chart object ===========================================================
+
+/** Represents the CHCHART record group describing the chart contents.
+
+ The CHCHART group consists of: CHCHART, CHBEGIN, SCL, CHPLOTGROWTH, CHFRAME
+ group, CHSERIES groups, CHPROPERTIES, CHDEFAULTTEXT groups (CHDEFAULTTEXT
+ with CHTEXT groups), CHUSEDAXESSETS, CHAXESSET groups, CHTEXT groups, CHEND.
+ */
+class XclImpChChart : public XclImpChGroupBase, protected XclImpChRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > XDiagramRef;
+
+public:
+ explicit XclImpChChart( const XclImpRoot& rRoot );
+ virtual ~XclImpChChart();
+
+ /** Reads the CHCHART record (called by base class). */
+ virtual void ReadHeaderRecord( XclImpStream& rStrm );
+ /** Reads a record from the CHCHART group (called by base class). */
+ virtual void ReadSubRecord( XclImpStream& rStrm );
+ /** Reads a CHDEFAULTTEXT group (default text formats). */
+ void ReadChDefaultText( XclImpStream& rStrm );
+ /** Reads a CHDATAFORMAT group describing a series format or a data point format. */
+ void ReadChDataFormat( XclImpStream& rStrm );
+
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Returns the specified chart type group. */
+ XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const;
+ /** Returns the specified default text. */
+ const XclImpChText* GetDefaultText( XclChTextType eTextType ) const;
+ /** Returns true, if the plot area has benn moved and/or resized manually. */
+ bool IsManualPlotArea() const;
+ /** Returns the number of units on the progress bar needed for the chart. */
+ inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; }
+
+ /** Converts and writes all properties to the passed chart. */
+ void Convert( XChartDocRef xChartDoc,
+ XclImpDffConverter& rDffConv,
+ const ::rtl::OUString& rObjName,
+ const Rectangle& rChartRect ) const;
+
+private:
+ /** Reads a CHSERIES group (data series source and formatting). */
+ void ReadChSeries( XclImpStream& rStrm );
+ /** Reads a CHPROPERTIES record (global chart properties). */
+ void ReadChProperties( XclImpStream& rStrm );
+ /** Reads a CHAXESSET group (primary/secondary axes set). */
+ void ReadChAxesSet( XclImpStream& rStrm );
+ /** Reads a CHTEXT group (chart title and series/point captions). */
+ void ReadChText( XclImpStream& rStrm );
+
+ /** Final processing after reading the entire chart data. */
+ void Finalize();
+ /** Finalizes series list, assigns child series to parent series. */
+ void FinalizeSeries();
+ /** Assigns all imported CHDATAFORMAT groups to the respective series. */
+ void FinalizeDataFormats();
+ /** Finalizes chart title, tries to detect title auto-generated from series name. */
+ void FinalizeTitle();
+
+ /** Creates and returns a new diagram object and converts global chart settings. */
+ XDiagramRef CreateDiagram() const;
+
+private:
+ typedef ::std::vector< XclImpChSeriesRef > XclImpChSeriesVec;
+ typedef ::std::map<XclChDataPointPos, XclImpChDataFormatRef> XclImpChDataFormatMap;
+ typedef ::boost::ptr_map<sal_uInt16, XclImpChText> XclImpChTextMap;
+
+ XclChRectangle maRect; /// Position of the chart on the sheet (CHCHART record).
+ XclImpChSeriesVec maSeries; /// List of series data (CHSERIES groups).
+ XclImpChDataFormatMap maDataFmts; /// All series and point formats (CHDATAFORMAT groups).
+ XclImpChFrameRef mxFrame; /// Chart frame format (CHFRAME group).
+ XclChProperties maProps; /// Chart properties (CHPROPERTIES record).
+ XclImpChTextMap maDefTexts; /// Default text objects (CHDEFAULTTEXT groups).
+ XclImpChAxesSetRef mxPrimAxesSet; /// Primary axes set (CHAXESSET group).
+ XclImpChAxesSetRef mxSecnAxesSet; /// Secondary axes set (CHAXESSET group).
+ XclImpChTextRef mxTitle; /// Chart title (CHTEXT group).
+ XclImpChLegendRef mxLegend; /// Chart legend (CHLEGEND group).
+};
+
+typedef boost::shared_ptr< XclImpChChart > XclImpChChartRef;
+
+// ----------------------------------------------------------------------------
+
+/** Drawing container of a chart. */
+class XclImpChartDrawing : public XclImpDrawing
+{
+public:
+ explicit XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab );
+
+ /** Converts all objects and inserts them into the chart drawing page. */
+ void ConvertObjects(
+ XclImpDffConverter& rDffConv,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel,
+ const Rectangle& rChartRect );
+
+ /** Calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const;
+ /** Called whenever an object has been inserted into the draw page. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj );
+
+private:
+ Rectangle maChartRect; /// Position and size of the chart shape in 1/100 mm.
+ SCTAB mnScTab; /// Index of the sheet that contains the chart.
+ bool mbOwnTab; /// True = own sheet, false = embedded object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents the entire chart substream (all records in BOF/EOF block). */
+class XclImpChart : protected XclImpRoot
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > XModelRef;
+
+public:
+ /** Constructs a new chart object.
+ @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */
+ explicit XclImpChart( const XclImpRoot& rRoot, bool bOwnTab );
+ virtual ~XclImpChart();
+
+ /** Reads the complete chart substream (BOF/EOF block).
+ @descr The passed stream must be located in the BOF record of the chart substream. */
+ void ReadChartSubStream( XclImpStream& rStrm );
+ /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
+ void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );
+
+ /** Returns the number of units on the progress bar needed for the chart. */
+ sal_Size GetProgressSize() const;
+ /** Returns true, if the chart is based on a pivot table. */
+ inline bool IsPivotChart() const { return mbIsPivotChart; }
+
+ /** Creates the chart object in the passed component. */
+ void Convert( XModelRef xModel,
+ XclImpDffConverter& rDffConv,
+ const ::rtl::OUString& rObjName,
+ const Rectangle& rChartRect ) const;
+
+private:
+ /** Returns (initially creates) the drawing container for embedded shapes. **/
+ XclImpChartDrawing& GetChartDrawing();
+ /** Reads the CHCHART group (entire chart data). */
+ void ReadChChart( XclImpStream& rStrm );
+
+private:
+ typedef boost::shared_ptr< XclImpChartDrawing > XclImpChartDrawingRef;
+
+ XclImpChChartRef mxChartData; /// The chart data (CHCHART group).
+ XclImpChartDrawingRef mxChartDrawing; /// Drawing container for embedded shapes.
+ bool mbOwnTab; /// true = own sheet; false = embedded object.
+ bool mbIsPivotChart; /// true = chart is based on a pivot table.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
new file mode 100644
index 000000000000..31a62aba7aa5
--- /dev/null
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XICONTENT_HXX
+#define SC_XICONTENT_HXX
+
+#include "global.hxx"
+#include "rangelst.hxx"
+#include "xlcontent.hxx"
+#include "xistring.hxx"
+#include "xiroot.hxx"
+#include "validat.hxx"
+
+#include <map>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/noncopyable.hpp>
+
+/* ============================================================================
+Classes to import the big Excel document contents (related to several cells or
+globals for the document).
+- Shared string tables
+- Hyperlinks
+- Label ranges
+- Conditional formatting
+- Data validation
+- Web queries
+- Stream decryption
+============================================================================ */
+
+// Shared string table ========================================================
+
+class ScBaseCell;
+
+/** The SST (shared string table) contains all strings used in a BIFF8 file.
+
+ This class loads the SST, provides access to the strings, and is able to
+ create Calc string or edit cells.
+ */
+class XclImpSst : protected XclImpRoot
+{
+public:
+ explicit XclImpSst( const XclImpRoot& rRoot );
+
+ /** Reads the entire SST record.
+ @descr Import stream must be located at start of a SST record. */
+ void ReadSst( XclImpStream& rStrm );
+
+ /** Returns a pointer to the string with the passed index. */
+ const XclImpString* GetString( sal_uInt32 nSstIndex ) const;
+
+ /** Creates a new text cell or edit cell for a Calc document.
+ @param nXFIndex Index to XF for first text portion (checks escapement). */
+ ScBaseCell* CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex = 0 ) const;
+
+private:
+ typedef ::std::vector< XclImpString > XclImpStringVec;
+ XclImpStringVec maStrings; /// List with all strings in the SST.
+};
+
+// Hyperlinks =================================================================
+
+/** Provides importing hyperlinks and inserting them into a document. */
+class XclImpHyperlink : private boost::noncopyable
+{
+public:
+ /** Reads a HLINK record and inserts it into the document.
+ @descr Import stream must be located at start of a HLINK record. */
+ static void ReadHlink( XclImpStream& rStrm );
+
+ /** Reads the (undocumented) embedded hyperlink data and returns the URL. */
+ static String ReadEmbeddedData( XclImpStream& rStrm );
+
+ /** Inserts the URL into a range of cells. Does not modify value or formula cells. */
+ static void InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl );
+
+ /** Convert the sheet name with invalid character(s) in URL when the URL is
+ to a location within the same document (e.g. #'Sheet&Name'.A1). */
+ static void ConvertToValidTabName(String& rName);
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclImpHyperlink();
+};
+
+// Label ranges ===============================================================
+
+/** Provides importing label ranges and inserting them into a document. */
+class XclImpLabelranges : private boost::noncopyable
+{
+public:
+ /** Reads a LABELRANGES record and inserts the label ranges into the document.
+ @descr Import stream must be located at start of a LABELRANGES record. */
+ static void ReadLabelranges( XclImpStream& rStrm );
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclImpLabelranges();
+};
+
+// Conditional formatting =====================================================
+
+class ScConditionalFormat;
+
+/** Represents a conditional format with condition formulas, and formatting attributes. */
+class XclImpCondFormat : protected XclImpRoot
+{
+public:
+ explicit XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex );
+ virtual ~XclImpCondFormat();
+
+ /** Reads a CONDFMT record and initializes this conditional format. */
+ void ReadCondfmt( XclImpStream& rStrm );
+ /** Reads a CF record and adds a new condition and the formatting attributes. */
+ void ReadCF( XclImpStream& rStrm );
+
+ /** Inserts this conditional format into the document. */
+ void Apply();
+
+private:
+ typedef ::std::auto_ptr< ScConditionalFormat > ScCondFmtPtr;
+
+ ScRangeList maRanges; /// Destination cell ranges.
+ ScCondFmtPtr mxScCondFmt; /// Calc conditional format.
+ sal_uInt32 mnFormatIndex; /// Index of this conditional format in list.
+ sal_uInt16 mnCondCount; /// Number of conditions to be inserted.
+ sal_uInt16 mnCondIndex; /// Condition index to be inserted next.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Imports and collects all conditional formatting of a sheet. */
+class XclImpCondFormatManager : protected XclImpRoot
+{
+public:
+ explicit XclImpCondFormatManager( const XclImpRoot& rRoot );
+
+ /** Reads a CONDFMT record and starts a new conditional format to be filled from CF records. */
+ void ReadCondfmt( XclImpStream& rStrm );
+ /** Reads a CF record and inserts the formatting data to the current conditional format. */
+ void ReadCF( XclImpStream& rStrm );
+
+ /** Inserts the conditional formattings into the document. */
+ void Apply();
+
+private:
+ typedef boost::ptr_vector< XclImpCondFormat > XclImpCondFmtList;
+ XclImpCondFmtList maCondFmtList; /// List with all conditional formattings.
+};
+
+// Data Validation ============================================================
+
+/** Imports validation data. */
+class XclImpValidationManager : protected XclImpRoot
+{
+public:
+ explicit XclImpValidationManager( const XclImpRoot& rRoot );
+
+ /** Reads a DVAL record and sets marks the dropdown arrow control to be ignored. */
+ void ReadDval( XclImpStream& rStrm );
+ /** Reads a DV record and inserts validation data into the document. */
+ void ReadDV( XclImpStream& rStrm );
+
+ void Apply();
+private:
+ struct DVItem
+ {
+ ScRangeList maRanges;
+ ScValidationData maValidData;
+
+ explicit DVItem ( const ScRangeList& rRanges, const ScValidationData& rValidData );
+ };
+ typedef ::boost::ptr_vector<DVItem> DVItemList;
+
+ DVItemList maDVItems;
+};
+
+// Web queries ================================================================
+
+/** Stores the data of one web query. */
+class XclImpWebQuery : private boost::noncopyable
+{
+public:
+ explicit XclImpWebQuery( const ScRange& rDestRange );
+
+ /** Reads a PARAMQRY record and sets data to the web query. */
+ void ReadParamqry( XclImpStream& rStrm );
+ /** Reads a WQSTRING record and sets URL. */
+ void ReadWqstring( XclImpStream& rStrm );
+ /** Reads a WEBQRYSETTINGS record and sets refresh rate. */
+ void ReadWqsettings( XclImpStream& rStrm );
+ /** Reads a WEBQRYTABLES record and sets source range list. */
+ void ReadWqtables( XclImpStream& rStrm );
+
+ /** Inserts the web query into the document. */
+ void Apply( ScDocument& rDoc, const String& rFilterName );
+
+private:
+ /** Specifies the type of the web query (which ranges are imported). */
+ enum XclImpWebQueryMode
+ {
+ xlWQUnknown, /// Not specified.
+ xlWQDocument, /// Entire document.
+ xlWQAllTables, /// All tables.
+ xlWQSpecTables /// Specific tables.
+ };
+
+ String maURL; /// Source document URL.
+ String maTables; /// List of source range names.
+ ScRange maDestRange; /// Destination range.
+ XclImpWebQueryMode meMode; /// Current mode of the web query.
+ sal_uInt16 mnRefresh; /// Refresh time in minutes.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpWebQueryBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpWebQueryBuffer( const XclImpRoot& rRoot );
+
+ /** Reads the QSI record and creates a new web query in the buffer. */
+ void ReadQsi( XclImpStream& rStrm );
+ /** Reads a PARAMQRY record and sets data to the current web query. */
+ void ReadParamqry( XclImpStream& rStrm );
+ /** Reads a WQSTRING record and sets URL to the current web query. */
+ void ReadWqstring( XclImpStream& rStrm );
+ /** Reads a WEBQRYSETTINGS record and sets refresh rate to the current web query. */
+ void ReadWqsettings( XclImpStream& rStrm );
+ /** Reads a WEBQRYTABLES record and sets source range list to the current web query. */
+ void ReadWqtables( XclImpStream& rStrm );
+
+ /** Inserts all web queries into the document. */
+ void Apply();
+
+private:
+ typedef boost::ptr_vector< XclImpWebQuery > XclImpWebQueryList;
+ XclImpWebQueryList maWQList; /// List of the web query objects.
+};
+
+// Decryption =================================================================
+
+/** Provides static functions to import stream decryption settings. */
+class XclImpDecryptHelper : private boost::noncopyable
+{
+public:
+ /** Reads the FILEPASS record, queries a password and sets decryption algorihm.
+ @return Error code that may cause an error message after import. */
+ static ErrCode ReadFilepass( XclImpStream& rStrm );
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclImpDecryptHelper();
+};
+
+// ============================================================================
+
+// Document protection ========================================================
+
+class XclImpDocProtectBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpDocProtectBuffer( const XclImpRoot& rRoot );
+
+ /** document structure protection flag */
+ void ReadDocProtect( XclImpStream& rStrm );
+
+ /** document windows properties protection flag */
+ void ReadWinProtect( XclImpStream& rStrm );
+
+ void ReadPasswordHash( XclImpStream& rStrm );
+
+ void Apply() const;
+
+private:
+ sal_uInt16 mnPassHash;
+ bool mbDocProtect:1;
+ bool mbWinProtect:1;
+};
+
+// Sheet protection ===========================================================
+
+class XclImpSheetProtectBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpSheetProtectBuffer( const XclImpRoot& rRoot );
+
+ void ReadProtect( XclImpStream& rStrm, SCTAB nTab );
+
+ void ReadOptions( XclImpStream& rStrm, SCTAB nTab );
+
+ void ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab );
+
+ void Apply() const;
+
+private:
+ struct Sheet
+ {
+ bool mbProtected;
+ sal_uInt16 mnPasswordHash;
+ sal_uInt16 mnOptions;
+
+ Sheet();
+ Sheet(const Sheet& r);
+ };
+
+ Sheet* GetSheetItem( SCTAB nTab );
+
+private:
+ typedef ::std::map<SCTAB, Sheet> ProtectedSheetMap;
+ ProtectedSheetMap maProtectedSheets;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx
new file mode 100644
index 000000000000..be6a48f317bc
--- /dev/null
+++ b/sc/source/filter/inc/xiescher.hxx
@@ -0,0 +1,1315 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIESCHER_HXX
+#define SC_XIESCHER_HXX
+
+#include <vector>
+#include <map>
+#include <filter/msfilter/msdffimp.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <vcl/graph.hxx>
+#include "xlescher.hxx"
+#include "xiroot.hxx"
+#include "xistring.hxx"
+#include <boost/shared_ptr.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShape; }
+ namespace form { class XForm; }
+} } }
+
+class SdrObjList;
+class ScfProgressBar;
+class ScfPropertySet;
+class XclImpChart;
+class XclImpDffConverter;
+class XclImpDrawing;
+
+// Drawing objects ============================================================
+
+class XclImpDrawObjBase;
+typedef boost::shared_ptr< XclImpDrawObjBase > XclImpDrawObjRef;
+
+/** Base class for drawing objects (OBJ records). */
+class XclImpDrawObjBase : protected XclImpRoot
+{
+public:
+ explicit XclImpDrawObjBase( const XclImpRoot& rRoot );
+ virtual ~XclImpDrawObjBase();
+
+ /** Reads the BIFF3 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF4 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF5 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads the BIFF8 OBJ record, returns a new drawing object. */
+ static XclImpDrawObjRef ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Sets whether this is an area object (then its width and height must be greater than 0). */
+ inline void SetAreaObj( bool bAreaObj ) { mbAreaObj = bAreaObj; }
+ /** If set to true, a new SdrObject will be created while in DFF import. */
+ inline void SetSimpleMacro( bool bMacro ) { mbSimpleMacro = bMacro; }
+
+ /** Sets the object anchor explicitly. */
+ void SetAnchor( const XclObjAnchor& rAnchor );
+ /** Sets shape data from DFF stream. */
+ void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin );
+
+ /** If set to false, the SdrObject will not be created, processed, or inserted into the draw page. */
+ inline void SetProcessSdrObj( bool bProcess ) { mbProcessSdr = bProcess; }
+ /** If set to false, the SdrObject will be created or processed, but not be inserted into the draw page. */
+ inline void SetInsertSdrObj( bool bInsert ) { mbInsertSdr = bInsert; }
+ /** If set to true, a new SdrObject will be created while in DFF import. */
+ inline void SetCustomDffObj( bool bCustom ) { mbCustomDff = bCustom; }
+
+ /** Returns the sheet index and Excel object identifier from OBJ record. */
+ inline sal_uInt16 GetObjId() const { return mnObjId; }
+ /** Returns the Excel object type from OBJ record. */
+ inline sal_uInt16 GetObjType() const { return mnObjType; }
+ /** Returns the name of this object, may generate a default name. */
+ virtual String GetObjName() const;
+ /** Returns associated macro name, if set, otherwise zero length string. */
+ inline const String& GetMacroName() const { return maMacroName; }
+
+ /** Returns the shape identifier used in the DFF stream. */
+ inline sal_uInt32 GetDffShapeId() const { return mnDffShapeId; }
+ /** Returns the shape flags from the DFF stream. */
+ inline sal_uInt32 GetDffFlags() const { return mnDffFlags; }
+
+ /** Returns true, if the object is hidden. */
+ inline bool IsHidden() const { return mbHidden; }
+ /** Returns true, if the object is visible. */
+ inline bool IsVisible() const { return mbVisible; }
+ /** Returns true, if the object is printable. */
+ inline bool IsPrintable() const { return mbPrintable; }
+
+ /** Returns the object anchor if existing, null otherwise. */
+ const XclObjAnchor* GetAnchor() const;
+ /** Returns true, if the passed size is valid for this object. */
+ bool IsValidSize( const Rectangle& rAnchorRect ) const;
+ /** Returns the range in the sheet covered by this object. */
+ ScRange GetUsedArea( SCTAB nScTab ) const;
+
+ /** Returns true, if the object is valid and will be processed. */
+ inline bool IsProcessSdrObj() const { return mbProcessSdr && !mbHidden; }
+ /** Returns true, if the SdrObject will be created or processed, but not be inserted into the draw page. */
+ inline bool IsInsertSdrObj() const { return mbInsertSdr; }
+
+ /** Returns the needed size on the progress bar (calls virtual DoGetProgressSize() function). */
+ sal_Size GetProgressSize() const;
+ /** Creates and returns an SdrObject from the contained data. Caller takes ownership! */
+ SdrObject* CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const;
+ /** Additional processing for the passed SdrObject before insertion into
+ the drawing page (calls virtual DoPreProcessSdrObj() function). */
+ void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+ /** Additional processing for the passed SdrObject after insertion into the
+ drawing page (calls virtual DoPostProcessSdrObj() function). */
+ void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+protected:
+ /** Reads the object name in a BIFF5 OBJ record. */
+ void ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen );
+ /** Reads the macro link in a BIFF3 OBJ record. */
+ void ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the macro link in a BIFF4 OBJ record. */
+ void ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the macro link in a BIFF5 OBJ record. */
+ void ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the ftMacro sub structure in an OBJ record. */
+ void ReadMacro8( XclImpStream& rStrm );
+
+ /** Converts the passed line formatting to the passed SdrObject. */
+ void ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const;
+ /** Converts the passed fill formatting to the passed SdrObject. */
+ void ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const;
+ /** Converts the passed frame flags to the passed SdrObject. */
+ void ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const;
+
+ /** Returns a solid line color from the passed line data struct. */
+ Color GetSolidLineColor( const XclObjLineData& rLineData ) const;
+ /** Returns a solid fill color from the passed fill data struct. */
+ Color GetSolidFillColor( const XclObjFillData& rFillData ) const;
+
+ /** Derived classes read the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Derived classes read the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+
+ /** Derived classes may return a progress bar size different from 1. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Derived classes create and return a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Derived classes may perform additional processing for the passed SdrObject before insertion. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+ /** Derived classes may perform additional processing for the passed SdrObject after insertion. */
+ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+ SCTAB GetTab() const { return mnTab; }
+private:
+ /** Reads the contents of a BIFF3 OBJ record. */
+ void ImplReadObj3( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF4 OBJ record. */
+ void ImplReadObj4( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF5 OBJ record. */
+ void ImplReadObj5( XclImpStream& rStrm );
+ /** Reads the contents of a BIFF8 OBJ record. */
+ void ImplReadObj8( XclImpStream& rStrm );
+
+private:
+ XclObjAnchor maAnchor; /// The position of the object in its parent.
+ sal_uInt16 mnObjId; /// The object identifier (unique per drawing).
+ SCTAB mnTab; /// Location of object
+ sal_uInt16 mnObjType; /// The Excel object type from OBJ record.
+ sal_uInt32 mnDffShapeId; /// Shape ID from DFF stream.
+ sal_uInt32 mnDffFlags; /// Shape flags from DFF stream.
+ String maObjName; /// Name of the object.
+ String maMacroName; /// Name of an attached macro.
+ String maHyperlink; /// On-click hyperlink URL.
+ bool mbHasAnchor; /// true = maAnchor is initialized.
+ bool mbHidden; /// true = Object is hidden.
+ bool mbVisible; /// true = Object is visible.
+ bool mbPrintable; /// true = Object is printable.
+ bool mbAreaObj; /// true = Width and height must be greater than 0.
+ bool mbAutoMargin; /// true = Set automatic text margin.
+ bool mbSimpleMacro; /// true = Create simple macro link and hyperlink.
+ bool mbProcessSdr; /// true = Object is valid, do processing and insertion.
+ bool mbInsertSdr; /// true = Insert the SdrObject into draw page.
+ bool mbCustomDff; /// true = Recreate SdrObject in DFF import.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpDrawObjVector : public ::std::vector< XclImpDrawObjRef >
+{
+public:
+ inline explicit XclImpDrawObjVector() {}
+
+ /** Tries to insert the passed object into the last group or appends it. */
+ void InsertGrouped( XclImpDrawObjRef xDrawObj );
+
+ /** Returns the needed size on the progress bar for all contained objects. */
+ sal_Size GetProgressSize() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A placeholder object for unknown object types. */
+class XclImpPhObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpPhObj( const XclImpRoot& rRoot );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A group object. */
+class XclImpGroupObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpGroupObj( const XclImpRoot& rRoot );
+
+ /** Tries to insert the drawing object into this or a nested group. */
+ bool TryInsert( XclImpDrawObjRef xDrawObj );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Returns a progress bar size that takes all group children into account. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclImpDrawObjVector maChildren; /// Grouped objects.
+ sal_uInt16 mnFirstUngrouped; /// Object identfier of first object not grouped into this group.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A line object. */
+class XclImpLineObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpLineObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt16 mnArrows; /// Line arrows.
+ sal_uInt8 mnStartPoint; /// Starting point.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A rectangle or oval object. */
+class XclImpRectObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpRectObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads fil data, line data, and frame flags. */
+ void ReadFrameData( XclImpStream& rStrm );
+
+ /** Converts fill formatting, line formattind, and frame style. */
+ void ConvertRectStyle( SdrObject& rSdrObj ) const;
+
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjFillData maFillData; /// BIFF5 fill formatting.
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt16 mnFrameFlags; /// Additional flags.
+};
+
+// ----------------------------------------------------------------------------
+
+/** An oval object. */
+class XclImpOvalObj : public XclImpRectObj
+{
+public:
+ explicit XclImpOvalObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An arc object. */
+class XclImpArcObj : public XclImpDrawObjBase
+{
+public:
+ explicit XclImpArcObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ XclObjFillData maFillData; /// BIFF5 fill formatting.
+ XclObjLineData maLineData; /// BIFF5 line formatting.
+ sal_uInt8 mnQuadrant; /// Visible quadrant of the circle.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A polygon object. */
+class XclImpPolygonObj : public XclImpRectObj
+{
+public:
+ explicit XclImpPolygonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the COORDLIST record following the OBJ record. */
+ void ReadCoordList( XclImpStream& rStrm );
+
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+
+protected:
+ typedef ::std::vector< Point > PointVector;
+ PointVector maCoords; /// Coordinates relative to bounding rectangle.
+ sal_uInt16 mnPolyFlags; /// Additional flags.
+ sal_uInt16 mnPointCount; /// Polygon point count.
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclImpObjTextData
+{
+ XclObjTextData maData; /// BIFF5 text data.
+ XclImpStringRef mxString; /// Plain or rich string.
+
+ /** Reads a byte string from the passed stream. */
+ void ReadByteString( XclImpStream& rStrm );
+ /** Reads text formatting from the passed stream. */
+ void ReadFormats( XclImpStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A drawing object supporting text contents. Used for all simple objects in BIFF8. */
+class XclImpTextObj : public XclImpRectObj
+{
+public:
+ explicit XclImpTextObj( const XclImpRoot& rRoot );
+
+ /** Stores the passed textbox data. */
+ inline void SetTextData( const XclImpObjTextData& rTextData ) { maTextData = rTextData; }
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Inserts the contained text data at the passed object. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+protected:
+ XclImpObjTextData maTextData; /// Textbox data from BIFF5 OBJ or BIFF8 TXO record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A chart object. This is the drawing object wrapper for the chart data. */
+class XclImpChartObj : public XclImpRectObj
+{
+public:
+ /** @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */
+ explicit XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab = false );
+
+ /** Reads the complete chart substream (BOF/EOF block). */
+ void ReadChartSubStream( XclImpStream& rStrm );
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Returns the needed size on the progress bar. */
+ virtual sal_Size DoGetProgressSize() const;
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Converts the chart document. */
+ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ /** Calculates the object anchor of a sheet chart (chart fills one page). */
+ void FinalizeTabChart();
+
+private:
+ typedef boost::shared_ptr< XclImpChart > XclImpChartRef;
+
+ XclImpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
+ bool mbOwnTab; /// true = own sheet; false = embedded object.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A note object, which is a specialized text box objext. */
+class XclImpNoteObj : public XclImpTextObj
+{
+public:
+ explicit XclImpNoteObj( const XclImpRoot& rRoot );
+
+ /** Sets note flags and the note position in the Calc sheet. */
+ void SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags );
+
+protected:
+ /** Inserts the note into the document, sets visibility. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ ScAddress maScPos; /// Cell position of the note object.
+ sal_uInt16 mnNoteFlags; /// Flags from NOTE record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Helper base class for TBX and OCX form controls to manage spreadsheet links. */
+class XclImpControlHelper
+{
+public:
+ explicit XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode );
+ virtual ~XclImpControlHelper();
+
+ /** Returns true, if a linked cell address is present. */
+ inline bool HasCellLink() const { return mxCellLink != 0; }
+ /** Returns true, if a linked source cell range is present. */
+ inline bool HasSourceRange() const { return mxSrcRange != 0; }
+
+ /** Returns the SdrObject from the passed control shape and sets the bounding rectangle. */
+ SdrObject* CreateSdrObjectFromShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const Rectangle& rAnchorRect ) const;
+
+ /** Sets additional properties to the form control model, calls virtual DoProcessControl(). */
+ void ProcessControl( const XclImpDrawObjBase& rDrawObj ) const;
+
+protected:
+ /** Reads the formula for the linked cell from the current position of the stream. */
+ void ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize );
+ /** Reads the formula for the source range from the current position of the stream. */
+ void ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize );
+
+ /** Derived classes will set additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+
+ void ApplySheetLinkProps() const;
+ mutable ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ mxShape; /// The UNO wrapper of the control shape.
+ boost::shared_ptr< ScAddress > mxCellLink; /// Linked cell in the Calc document.
+private:
+ /** Reads a list of cell ranges from a formula at the current stream position. */
+ void ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm );
+ /** Reads leading formula size and a list of cell ranges from a formula if the leading size is not zero. */
+ void ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize );
+
+private:
+ const XclImpRoot& mrRoot; /// Not derived from XclImpRoot to allow multiple inheritance.
+ boost::shared_ptr< ScRange > mxSrcRange; /// Source data range in the Calc document.
+ XclCtrlBindMode meBindMode; /// Value binding mode.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for textbox based form controls. */
+class XclImpTbxObjBase : public XclImpTextObj, public XclImpControlHelper
+{
+public:
+ explicit XclImpTbxObjBase( const XclImpRoot& rRoot );
+
+ /** Sets line and fill formatting from the passed DFF property set. */
+ void SetDffProperties( const DffPropSet& rDffPropSet );
+
+ /** Returns the service name of the control component to be created. */
+ inline ::rtl::OUString GetServiceName() const { return DoGetServiceName(); }
+ /** Fills the passed macro event descriptor. */
+ bool FillMacroDescriptor(
+ ::com::sun::star::script::ScriptEventDescriptor& rDescriptor ) const;
+
+protected:
+ /** Sets control text formatting. */
+ void ConvertFont( ScfPropertySet& rPropSet ) const;
+ /** Sets control label and text formatting. */
+ void ConvertLabel( ScfPropertySet& rPropSet ) const;
+
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Additional processing on the SdrObject, calls new virtual function DoProcessControl(). */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+ /** Derived classes return the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const = 0;
+ /** Derived classes return the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A button control. */
+class XclImpButtonObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A checkbox control. */
+class XclImpCheckBoxObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpCheckBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnState;
+ sal_uInt16 mnCheckBoxFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An option button control. */
+class XclImpOptionButtonObj : public XclImpCheckBoxObj
+{
+public:
+ explicit XclImpOptionButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ void ApplyGrouping( XclImpOptionButtonObj& rLeader, sal_Int32 nRefVal );
+ sal_uInt16 mnNextInGroup; /// Next option button in a group.
+ sal_uInt16 mnFirstInGroup; /// 1 = Button is the first in a group.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A label control. */
+class XclImpLabelObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpLabelObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A groupbox control. */
+class XclImpGroupBoxObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpGroupBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnGroupBoxFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A dialog control. */
+class XclImpDialogObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpDialogObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** An edit control. */
+class XclImpEditObj : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpEditObj( const XclImpRoot& rRoot );
+
+protected:
+ /** REturns true, if the field type is numeric. */
+ bool IsNumeric() const;
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnContentType;
+ sal_uInt16 mnMultiLine;
+ sal_uInt16 mnScrollBar;
+ sal_uInt16 mnListBoxObjId;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class of scrollable form controls (spin button, scrollbar, listbox, dropdown). */
+class XclImpTbxObjScrollableBase : public XclImpTbxObjBase
+{
+public:
+ explicit XclImpTbxObjScrollableBase( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads scrollbar data. */
+ void ReadSbs( XclImpStream& rStrm );
+
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+
+protected:
+ sal_uInt16 mnValue;
+ sal_uInt16 mnMin;
+ sal_uInt16 mnMax;
+ sal_uInt16 mnStep;
+ sal_uInt16 mnPageStep;
+ sal_uInt16 mnOrient;
+ sal_uInt16 mnThumbWidth;
+ sal_uInt16 mnScrollFlags;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A spinbutton control. */
+class XclImpSpinButtonObj : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpSpinButtonObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A scrollbar control. */
+class XclImpScrollBarObj : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpScrollBarObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Base class for list controls (listbox, dropdown). */
+class XclImpTbxObjListBase : public XclImpTbxObjScrollableBase
+{
+public:
+ explicit XclImpTbxObjListBase( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads common listbox settings. */
+ void ReadLbsData( XclImpStream& rStrm );
+ /** Sets common listbox/dropdown formatting attributes. */
+ void SetBoxFormatting( ScfPropertySet& rPropSet ) const;
+
+protected:
+ sal_uInt16 mnEntryCount;
+ sal_uInt16 mnSelEntry;
+ sal_uInt16 mnListFlags;
+ sal_uInt16 mnEditObjId;
+ bool mbHasDefFontIdx;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A listbox control. */
+class XclImpListBoxObj : public XclImpTbxObjListBase
+{
+public:
+ explicit XclImpListBoxObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Reads listbox settings and selection. */
+ void ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft );
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ ScfUInt8Vec maSelection;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A dropdown listbox control. */
+class XclImpDropDownObj : public XclImpTbxObjListBase
+{
+public:
+ explicit XclImpDropDownObj( const XclImpRoot& rRoot );
+
+protected:
+ /** Returns the type of the dropdown control. */
+ sal_uInt16 GetDropDownType() const;
+
+ /** Reads dropdown box settings. */
+ void ReadFullLbsData( XclImpStream& rStrm );
+
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Sets additional properties for the current form control. */
+ virtual void DoProcessControl( ScfPropertySet& rPropSet ) const;
+ /** Returns the service name of the control component to be created. */
+ virtual ::rtl::OUString DoGetServiceName() const;
+ /** Returns the type of the macro event to be created. */
+ virtual XclTbxEventType DoGetEventType() const;
+
+protected:
+ sal_uInt16 mnLeft;
+ sal_uInt16 mnTop;
+ sal_uInt16 mnRight;
+ sal_uInt16 mnBottom;
+ sal_uInt16 mnDropDownFlags;
+ sal_uInt16 mnLineCount;
+ sal_uInt16 mnMinWidth;
+};
+
+// ----------------------------------------------------------------------------
+
+/** A picture, an embedded or linked OLE object, or an OCX form control. */
+class XclImpPictureObj : public XclImpRectObj, public XclImpControlHelper
+{
+public:
+ explicit XclImpPictureObj( const XclImpRoot& rRoot );
+ /** Returns the ObjectName - can use non-obvious lookup for override in the associated vba document module stream**/
+ virtual String GetObjName() const;
+ /** Returns the graphic imported from the IMGDATA record. */
+ inline const Graphic& GetGraphic() const { return maGraphic; }
+ /** Returns the visible area of the imported graphic. */
+ inline const Rectangle& GetVisArea() const { return maVisArea; }
+
+ /** Returns true, if the OLE object will be shown as symbol. */
+ inline bool IsSymbol() const { return mbSymbol; }
+ /** Returns the storage name for the OLE object. */
+ String GetOleStorageName() const;
+
+ /** Returns true, if this object is an OCX form control. */
+ inline bool IsOcxControl() const { return mbEmbedded && mbControl && mbUseCtlsStrm; }
+ /** Returns the position in the 'Ctls' stream for additional form control data. */
+ inline sal_Size GetCtlsStreamPos() const { return mnCtlsStrmPos; }
+ /** Returns the size in the 'Ctls' stream for additional form control data. */
+ inline sal_Size GetCtlsStreamSize() const { return mnCtlsStrmSize; }
+
+protected:
+ /** Reads the contents of the a BIFF3 OBJ record from the passed stream. */
+ virtual void DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF4 OBJ record from the passed stream. */
+ virtual void DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize );
+ /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
+ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize );
+ /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */
+ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize );
+ /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */
+ virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const;
+ /** Overloaded to do additional processing on the SdrObject. */
+ virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const;
+
+private:
+ /** Reads and sets the picture flags from a BIFF3-BIFF5 OBJ picture record. */
+ void ReadFlags3( XclImpStream& rStrm );
+ /** Reads the contents of the OBJFLAGS subrecord. */
+ void ReadFlags8( XclImpStream& rStrm );
+ /** Reads the contents of the OBJPICTFMLA subrecord. */
+ void ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize );
+
+private:
+ Graphic maGraphic; /// Picture or OLE placeholder graphic.
+ Rectangle maVisArea; /// Size of graphic.
+ String maClassName; /// Class name of embedded OLE object.
+ sal_uInt32 mnStorageId; /// Identifier of the storage for this object.
+ sal_Size mnCtlsStrmPos; /// Position in 'Ctls' stream for this control.
+ sal_Size mnCtlsStrmSize; /// Size in 'Ctls' stream for this control.
+ bool mbEmbedded; /// true = Embedded OLE object.
+ bool mbLinked; /// true = Linked OLE object.
+ bool mbSymbol; /// true = Show as symbol.
+ bool mbControl; /// true = Form control, false = OLE object.
+ bool mbUseCtlsStrm; /// true = Form control data in 'Ctls' stream, false = Own storage.
+};
+
+// DFF stream conversion ======================================================
+
+/** The solver container collects all connector rules for connected objects. */
+class XclImpSolverContainer : public SvxMSDffSolverContainer
+{
+public:
+
+ /** Inserts information about a new SdrObject. */
+ void InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags );
+ /** Removes inforamtion of an SdrObject (and all child objects if it is a group). */
+ void RemoveSdrObjectInfo( SdrObject& rSdrObj );
+
+ /** Inserts the SdrObject pointers into all connector rules. */
+ void UpdateConnectorRules();
+ /** Removes all contained connector rules. */
+ void RemoveConnectorRules();
+
+private:
+ /** Returns the first connector rule from the internal list. */
+ SvxMSDffConnectorRule* GetFirstRule();
+ /** Returns the next connector rule from the internal list. */
+ SvxMSDffConnectorRule* GetNextRule();
+ /** Updates the data of a connected shape in a connector rule. */
+ void UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags = 0 );
+
+private:
+ /** Stores data about an SdrObject processed during import. */
+ struct XclImpSdrInfo
+ {
+ SdrObject* mpSdrObj; /// Pointer to an SdrObject.
+ sal_uInt32 mnDffFlags; /// Shape flags from DFF stream.
+ inline explicit XclImpSdrInfo() : mpSdrObj( 0 ), mnDffFlags( 0 ) {}
+ inline void Set( SdrObject* pSdrObj, sal_uInt32 nDffFlags )
+ { mpSdrObj = pSdrObj; mnDffFlags = nDffFlags; }
+ };
+ typedef ::std::map< sal_uInt32, XclImpSdrInfo > XclImpSdrInfoMap;
+ typedef ::std::map< SdrObject*, sal_uInt32 > XclImpSdrObjMap;
+
+ XclImpSdrInfoMap maSdrInfoMap; /// Maps shape IDs to SdrObjects and flags.
+ XclImpSdrObjMap maSdrObjMap; /// Maps SdrObjects to shape IDs.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Simple implementation of the SVX DFF manager. Implements resolving palette
+ colors. Used by XclImpDffPropSet (as is), extended by XclImpDffConverter.
+ */
+class XclImpSimpleDffConverter : public SvxMSDffManager, protected XclImpRoot
+{
+public:
+ explicit XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm );
+ virtual ~XclImpSimpleDffConverter();
+
+protected:
+ /** Returns a color from the Excel color palette. */
+ virtual bool GetColorFromPalette( sal_uInt16 nIndex, Color& rColor ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** This is the central instance for converting binary DFF data into shape
+ objects. Used for all sheet shapes and shapes embedded in chart objects.
+
+ The class derives from SvxMSDffManager and SvxMSConvertOCXControls and
+ contains core implementation of DFF stream import and OCX form control
+ import.
+ */
+class XclImpDffConverter : public XclImpSimpleDffConverter, private SvxMSConvertOCXControls
+{
+public:
+ explicit XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm );
+ virtual ~XclImpDffConverter();
+
+ /** Initializes the internal progress bar with the passed size and starts it. */
+ void StartProgressBar( sal_Size nProgressSize );
+ /** Increase the progress bar by the passed value. */
+ void Progress( sal_Size nDelta = 1 );
+
+ /** Initially called before the objects of the passed drawing manager are converted. */
+ void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage );
+ /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */
+ void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj );
+ /** Processes all objects in the passed list. */
+ void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs );
+ /** Processes a drawing container in the passed DFF stream, converts all objects. */
+ void ProcessDrawing( SvStream& rDffStrm );
+ /** Finally called after the objects of the passed drawing manager have been converted. */
+ void FinalizeDrawing();
+
+ /** Creates the SdrObject for the passed Excel TBX form control object. */
+ SdrObject* CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect );
+ /** Creates the SdrObject for the passed Excel OLE object or OCX form control object. */
+ SdrObject* CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect );
+
+ /** Returns true, if the conversion of OLE objects is supported. */
+ bool SupportsOleObjects() const;
+ /** Returns the default text margin in drawing layer units. */
+ inline sal_Int32 GetDefaultTextMargin() const { return mnDefTextMargin; }
+
+private:
+ // virtual functions of SvxMSDffManager
+
+ /** Reads the client anchor from the DFF stream and sets it at the correct object. */
+ virtual void ProcessClientAnchor2(
+ SvStream& rDffStrm,
+ DffRecordHeader& rHeader,
+ void* pClientData,
+ DffObjData& rObjData );
+ /** Processes an DFF object, reads properties from DFF stream. */
+ virtual SdrObject* ProcessObj(
+ SvStream& rDffStrm,
+ DffObjData& rDffObjData,
+ void* pClientData,
+ Rectangle& rTextRect,
+ SdrObject* pOldSdrObj = 0 );
+ /** Returns the BLIP stream position, based on the passed DFF stream position. */
+ virtual sal_uLong Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong nStreamPos ) const;
+
+ // virtual functions of SvxMSConvertOCXControls
+
+ /** Inserts the passed control rxFComp into the form. Needs call to SetCurrentForm() before. */
+ virtual sal_Bool InsertControl(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::form::XFormComponent >& rxFormComp,
+ const ::com::sun::star::awt::Size& rSize,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::drawing::XShape >* pxShape,
+ sal_Bool bFloatingCtrl );
+
+private:
+ /** Data per registered drawing manager, will be stacked for recursive calls. */
+ struct XclImpDffConvData
+ {
+ XclImpDrawing& mrDrawing; /// Current drawing container with all drawing objects.
+ SdrModel& mrSdrModel; /// The SdrModel of the drawing manager.
+ SdrPage& mrSdrPage; /// The SdrPage of the drawing manager.
+ XclImpSolverContainer maSolverCont; /// The solver container for connector rules.
+ ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm >
+ mxCtrlForm; /// Controls form of current drawing page.
+ sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events).
+ bool mbHasCtrlForm; /// True = mxCtrlForm is initialized (but maybe still null).
+
+ explicit XclImpDffConvData( XclImpDrawing& rDrawing,
+ SdrModel& rSdrModel, SdrPage& rSdrPage );
+ };
+
+ /** Returns the current drawing manager data struct from top of the stack. */
+ XclImpDffConvData& GetConvData();
+ /** Returns the current drawing manager data struct from top of the stack. */
+ const XclImpDffConvData& GetConvData() const;
+
+ /** Reads contents of a hyperlink property and returns the extracted URL. */
+ String ReadHlinkProperty( SvStream& rDffStrm ) const;
+
+ /** Processes a drawing container (all drawing data of a sheet). */
+ void ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader );
+ /** Processes the global shape group container (all shapes of a sheet). */
+ void ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader );
+ /** Processes the solver container (connectors of a sheet). */
+ void ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader );
+ /** Processes a shape or shape group container (one top-level shape). */
+ void ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader );
+
+ /** Inserts the passed SdrObject into the document. This function takes ownership of pSdrObj! */
+ void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj );
+ /** Initializes the mxCtrlForm referring to the standard controls form. */
+ void InitControlForm();
+
+private:
+ typedef boost::shared_ptr< ScfProgressBar > ScfProgressBarRef;
+ typedef boost::shared_ptr< XclImpDffConvData > XclImpDffConvDataRef;
+ typedef ::std::vector< XclImpDffConvDataRef > XclImpDffConvDataStack;
+
+ const ::rtl::OUString maStdFormName; /// Standard name of control forms.
+ SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream for OCX form controls.
+ ScfProgressBarRef mxProgress; /// The progress bar used in ProcessObj().
+ XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers.
+ sal_uInt32 mnOleImpFlags; /// Application OLE import settings.
+ sal_Int32 mnDefTextMargin; /// Default margin in text boxes.
+};
+
+// Drawing manager ============================================================
+
+/** Base class for a container for all objects on a drawing (spreadsheet or
+ embedded chart object). */
+class XclImpDrawing : protected XclImpRoot
+{
+public:
+ explicit XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects );
+ virtual ~XclImpDrawing();
+
+ /** Reads and returns a bitmap from the IMGDATA record. */
+ static Graphic ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Reads a plain OBJ record (without leading DFF data). */
+ void ReadObj( XclImpStream& rStrm );
+ /** Reads the MSODRAWING or MSODRAWINGSELECTION record. */
+ void ReadMsoDrawing( XclImpStream& rStrm );
+
+ /** Returns true, if the conversion of OLE objects is supported. */
+ inline bool SupportsOleObjects() const { return mbOleObjs; }
+ /** Finds the OBJ record data related to the DFF shape at the passed position. */
+ XclImpDrawObjRef FindDrawObj( const DffRecordHeader& rHeader ) const;
+ /** Finds the OBJ record data specified by the passed object identifier. */
+ XclImpDrawObjRef FindDrawObj( sal_uInt16 nObjId ) const;
+ /** Finds the textbox data related to the DFF shape at the passed position. */
+ const XclImpObjTextData* FindTextData( const DffRecordHeader& rHeader ) const;
+
+ /** Sets the object with the passed identification to be skipped on import. */
+ void SetSkipObj( sal_uInt16 nObjId );
+ /** Returns the size of the progress bar shown while processing all objects. */
+ sal_Size GetProgressSize() const;
+
+ /** Derived classes calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const = 0;
+ /** Called whenever an object has been inserted into the draw page. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) = 0;
+
+protected:
+ /** Appends a new drawing object to the list of raw objects (without DFF data). */
+ void AppendRawObject( const XclImpDrawObjRef& rxDrawObj );
+ /** Converts all objects and inserts them into the current drawing page. */
+ void ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage );
+
+private:
+ /** Reads and returns a bitmap from WMF/PICT format. */
+ static void ReadWmf( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm );
+ /** Reads and returns a bitmap from BMP format. */
+ static void ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm );
+
+ /** Reads contents of an DFF record and append data to internal DFF stream. */
+ void ReadDffRecord( XclImpStream& rStrm );
+ /** Reads a BIFF8 OBJ record following an MSODRAWING record. */
+ void ReadObj8( XclImpStream& rStrm );
+ /** Reads the TXO record and following CONTINUE records containing string and formatting. */
+ void ReadTxo( XclImpStream& rStrm );
+
+private:
+ typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap;
+ typedef ::std::map< sal_uInt16, XclImpDrawObjRef > XclImpObjMapById;
+ typedef boost::shared_ptr< XclImpObjTextData > XclImpObjTextRef;
+ typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap;
+
+ XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data.
+ SvMemoryStream maDffStrm; /// Copy of the DFF page stream in memory.
+ XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position.
+ XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to object ID.
+ XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position.
+ ScfUInt16Vec maSkipObjs; /// IDs of all objects to be skipped.
+ bool mbOleObjs; /// True = draw model supports OLE objects.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Drawing manager of a single sheet. */
+class XclImpSheetDrawing : public XclImpDrawing
+{
+public:
+ explicit XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab );
+
+ /** Reads the NOTE record. */
+ void ReadNote( XclImpStream& rStrm );
+ /** Inserts a new chart object and reads the chart substream (BOF/EOF block).
+ @descr Used to import chart sheets, which do not have a corresponding OBJ record. */
+ void ReadTabChart( XclImpStream& rStrm );
+
+ /** Returns the total cell range covered by any shapes in the sheet. */
+ inline const ScRange& GetUsedArea() const { return maScUsedArea; }
+ /** Converts all objects and inserts them into the sheet drawing page. */
+ void ConvertObjects( XclImpDffConverter& rDffConv );
+
+ /** Calculate the resulting rectangle of the passed anchor. */
+ virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const;
+ /** On call, updates the used area of the sheet. */
+ virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj );
+
+private:
+ /** Reads a BIFF3-BIFF5 NOTE record. */
+ void ReadNote3( XclImpStream& rStrm );
+ /** Reads a BIFF8 NOTE record. */
+ void ReadNote8( XclImpStream& rStrm );
+
+private:
+ ScRange maScUsedArea; /// Sheet index and used area in this sheet.
+};
+
+// The object manager =========================================================
+
+/** Stores all drawing and OLE objects and additional data related to these objects. */
+class XclImpObjectManager : protected XclImpRoot
+{
+public:
+ explicit XclImpObjectManager( const XclImpRoot& rRoot );
+ virtual ~XclImpObjectManager();
+
+ /** Reads the MSODRAWINGGROUP record. */
+ void ReadMsoDrawingGroup( XclImpStream& rStrm );
+
+ /** Returns (initially creates) the drawing manager of the specified sheet. */
+ XclImpSheetDrawing& GetSheetDrawing( SCTAB nScTab );
+ /** Inserts all objects into the Calc document. */
+ void ConvertObjects();
+
+ /** Returns the default name for the passed object. */
+ String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const;
+ /** Returns the used area in the sheet with the passed index. */
+ ScRange GetUsedArea( SCTAB nScTab ) const;
+ /** Sets the container to receive overridden shape/ctrl names from
+ the filter. */
+ void SetOleNameOverrideInfo( const com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >& rxOverrideInfo ) { mxOleCtrlNameOverride = rxOverrideInfo; }
+ /** Returns the name of overridden name ( or zero length string ) for
+ associated object id. */
+ String GetOleNameOverride( SCTAB nTab, sal_uInt16 nObjId );
+ // ------------------------------------------------------------------------
+private:
+
+ /** Reads and returns a bitmap from WMF/PICT format. */
+ static void ReadWmf( Graphic& rGraphic, XclImpStream& rStrm );
+ /** Reads and returns a bitmap from BMP format. */
+ static void ReadBmp( Graphic& rGraphic, XclImpStream& rStrm );
+
+ /** Reads contents of an DFF record and append data to internal DFF stream. */
+ void ReadDffRecord( XclImpStream& rStrm );
+ /** Reads a BIFF8 OBJ record following an MSODRAWING record. */
+ void ReadObj8( XclImpStream& rStrm );
+ /** Reads the TXO record and following CONTINUE records containing string and formatting. */
+ void ReadTxo( XclImpStream& rStrm );
+
+ /** Reads a BIFF3-BIFF5 NOTE record. */
+ void ReadNote3( XclImpStream& rStrm );
+ /** Reads a BIFF8 NOTE record. */
+ void ReadNote8( XclImpStream& rStrm );
+
+ /** Returns the size of the progress bar shown while processing all objects. */
+ sal_Size GetProgressSize() const;
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap;
+ typedef ::std::map< XclObjId, XclImpDrawObjRef > XclImpObjMapById;
+ typedef boost::shared_ptr< XclImpObjTextData > XclImpObjTextRef;
+ typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap;
+ typedef ::std::vector< XclObjId > XclObjIdVec;
+
+ typedef ::std::map< sal_uInt16, String > DefObjNameMap;
+ typedef boost::shared_ptr< XclImpSheetDrawing > XclImpSheetDrawingRef;
+ typedef ::std::map< SCTAB, XclImpSheetDrawingRef > XclImpSheetDrawingMap;
+
+ com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > mxOleCtrlNameOverride;
+ DefObjNameMap maDefObjNames; /// Default base names for all object types.
+ SvMemoryStream maDggStrm; /// Copy of global DFF data (DGG container) in memory.
+ XclImpSheetDrawingMap maSheetDrawings; /// Drawing managers of all sheets.
+};
+
+// DFF property set helper ====================================================
+
+/** This class reads an DFF property set (msofbtOPT record).
+
+ It can return separate property values or an item set which contains items
+ translated from these properties.
+ */
+class XclImpDffPropSet : protected XclImpRoot
+{
+public:
+ explicit XclImpDffPropSet( const XclImpRoot& rRoot );
+
+ /** Reads an DFF property set from the stream.
+ @descr The stream must point to the start of an DFF record containing properties. */
+ void Read( XclImpStream& rStrm );
+
+ /** Returns the specified property or the default value, if not extant. */
+ sal_uInt32 GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault = 0 ) const;
+
+ /** Translates the properties and fills the item set. */
+ void FillToItemSet( SfxItemSet& rItemSet ) const;
+
+private:
+ typedef ::std::auto_ptr< SvMemoryStream > SvMemoryStreamPtr;
+
+ SvMemoryStream maDummyStrm; /// Dummy DGG stream for DFF manager.
+ XclImpSimpleDffConverter maDffConv; /// DFF converter used to resolve palette colors.
+ SvMemoryStreamPtr mxMemStrm; /// Helper stream.
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet );
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xiformula.hxx b/sc/source/filter/inc/xiformula.hxx
new file mode 100644
index 000000000000..b245fe92cee1
--- /dev/null
+++ b/sc/source/filter/inc/xiformula.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIFORMULA_HXX
+#define SC_XIFORMULA_HXX
+
+#include "xlformula.hxx"
+#include "xiroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Formula compiler ===========================================================
+
+class ScRangeList;
+class XclImpFmlaCompImpl;
+
+/** The formula compiler to create Calc token arrays from Excel token arrays. */
+class XclImpFormulaCompiler : protected XclImpRoot
+{
+public:
+ explicit XclImpFormulaCompiler( const XclImpRoot& rRoot );
+ virtual ~XclImpFormulaCompiler();
+
+ /** Creates a range list from the passed Excel token array.
+ @param rStrm Stream pointing to additional formula data (e.g. constant array data). */
+ void CreateRangeList(
+ ScRangeList& rScRanges, XclFormulaType eType,
+ const XclTokenArray& rXclTokArr, XclImpStream& rStrm );
+
+ /**
+ * Creates a formula token array from the Excel token array. Note that
+ * the caller must create a copy of the token array instance returend by
+ * this function if the caller needs to persistently store the array,
+ * because the pointer points to an array instance on the stack.
+ */
+ const ScTokenArray* CreateFormula( XclFormulaType eType, const XclTokenArray& rXclTokArr );
+
+private:
+ typedef boost::shared_ptr< XclImpFmlaCompImpl > XclImpFmlaCompImplRef;
+ XclImpFmlaCompImplRef mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xihelper.hxx b/sc/source/filter/inc/xihelper.hxx
new file mode 100644
index 000000000000..90b9d8c88c50
--- /dev/null
+++ b/sc/source/filter/inc/xihelper.hxx
@@ -0,0 +1,355 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIHELPER_HXX
+#define SC_XIHELPER_HXX
+
+#include <editeng/editdata.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include "scmatrix.hxx"
+#include "xladdress.hxx"
+#include "xiroot.hxx"
+#include "xistring.hxx"
+
+// Excel->Calc cell address/range conversion ==================================
+
+/** Provides functions to convert Excel cell addresses to Calc cell addresses. */
+class XclImpAddressConverter : public XclAddressConverterBase
+{
+public:
+ explicit XclImpAddressConverter( const XclImpRoot& rRoot );
+
+ // cell address -----------------------------------------------------------
+
+ /** Checks if the passed Excel cell address is valid.
+ @param rXclPos The Excel cell address to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is not valid.
+ @return true = Cell address in rXclPos is valid. */
+ bool CheckAddress( const XclAddress& rXclPos, bool bWarn );
+
+ /** Converts the passed Excel cell address to a Calc cell address.
+ @param rScPos (Out) The converted Calc cell address, if valid.
+ @param rXclPos The Excel cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return true = Cell address returned in rScPos is valid. */
+ bool ConvertAddress( ScAddress& rScPos,
+ const XclAddress& rXclPos, SCTAB nScTab, bool bWarn );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+ @param rXclPos The Excel cell address to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell address is invalid.
+ @return The converted Calc cell address. */
+ ScAddress CreateValidAddress( const XclAddress& rXclPos,
+ SCTAB nScTab, bool bWarn );
+
+ // cell range -------------------------------------------------------------
+
+ /** Converts the passed Excel cell range to a Calc cell range.
+ @param rScRange (Out) The converted Calc cell range, if valid.
+ @param rXclRange The Excel cell range to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the cell range contains invalid cells.
+ @return true = Cell range returned in rScRange is valid (original or cropped). */
+ bool ConvertRange( ScRange& rScRange, const XclRange& rXclRange,
+ SCTAB nScTab1, SCTAB nScTab2, bool bWarn );
+
+ // cell range list --------------------------------------------------------
+
+ /** Converts the passed Excel cell range list to a Calc cell range list.
+ @descr The start position of the ranges will not be modified. Cell
+ ranges that fit partly into valid dimensions are cropped
+ accordingly. Cell ranges that do not fit at all, are not inserted
+ into the Calc cell range list.
+ @param rScRanges (Out) The converted Calc cell range list.
+ @param rXclRanges The Excel cell range list to convert.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if at least one of the cell ranges
+ contains invalid cells. */
+ void ConvertRangeList( ScRangeList& rScRanges,
+ const XclRangeList& rXclRanges, SCTAB nScTab, bool bWarn );
+};
+
+// String->EditEngine conversion ==============================================
+
+class ScBaseCell;
+class EditTextObject;
+
+/** This class provides methods to convert an XclImpString.
+ @The string can be converted to an edit engine text object or directly
+ to a Calc edit cell. */
+class XclImpStringHelper : boost::noncopyable
+{
+public:
+ /** Returns a new edit engine text object.
+ @param nXFIndex Index to XF for first text portion (for escapement). */
+ static EditTextObject* CreateTextObject(
+ const XclImpRoot& rRoot,
+ const XclImpString& rString );
+
+ /** Creates a new text cell or edit cell for a Calc document.
+ @param nXFIndex Index to XF for first text portion (for escapement). */
+ static ScBaseCell* CreateCell(
+ const XclImpRoot& rRoot,
+ const XclImpString& rString,
+ sal_uInt16 nXFIndex = 0 );
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclImpStringHelper();
+};
+
+// Header/footer conversion ===================================================
+
+class EditEngine;
+class EditTextObject;
+class SfxItemSet;
+class SvxFieldItem;
+struct XclFontData;
+
+/** Converts an Excel header/footer string into three edit engine text objects.
+ @descr Header/footer content is divided into three parts: Left, center and
+ right portion. All formatting information is encoded in the Excel string
+ using special character seuences. A control sequence starts with the ampersand
+ character.
+
+ Supported control sequences:
+ &L start of left portion
+ &C start of center portion
+ &R start of right portion
+ &P current page number
+ &N page count
+ &D current date
+ &T current time
+ &A table name
+ &F file name without path (see also &Z&F)
+ &Z file path without file name (converted to full file name, see also &Z&F)
+ &Z&F file path and name
+ &U underlining on/off
+ &E double underlining on/off
+ &S strikeout characters on/off
+ &X superscript on/off
+ &Y subscript on/off
+ &"fontname,fontstyle" use font with name 'fontname' and style 'fontstyle'
+ &fontheight set font height in points ('fontheight' is a decimal value)
+
+ Known but unsupported control sequences:
+ &G picture
+ */
+class XclImpHFConverter : protected XclImpRoot, private boost::noncopyable
+{
+public:
+ explicit XclImpHFConverter( const XclImpRoot& rRoot );
+ ~XclImpHFConverter();
+
+ /** Parses the passed string and creates three new edit engine text objects. */
+ void ParseString( const String& rHFString );
+
+ /** Creates a ScPageHFItem and inserts it into the passed item set. */
+ void FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId ) const;
+ /** Returns the total height of the converted header or footer in twips. */
+ sal_Int32 GetTotalHeight() const;
+
+private: // types
+ typedef ::std::auto_ptr< XclFontData > XclFontDataPtr;
+
+ /** Enumerates the supported header/footer portions. */
+ enum XclImpHFPortion { EXC_HF_LEFT, EXC_HF_CENTER, EXC_HF_RIGHT, EXC_HF_PORTION_COUNT };
+
+ /** Contains all information about a header/footer portion. */
+ struct XclImpHFPortionInfo
+ {
+ typedef boost::shared_ptr< EditTextObject > EditTextObjectRef;
+ EditTextObjectRef mxObj; /// Edit engine text object.
+ ESelection maSel; /// Edit engine selection.
+ sal_Int32 mnHeight; /// Height of previous lines in twips.
+ sal_uInt16 mnMaxLineHt; /// Maximum font height for the current text line.
+ explicit XclImpHFPortionInfo();
+ };
+ typedef ::std::vector< XclImpHFPortionInfo > XclImpHFPortionInfoVec;
+
+private:
+ /** Returns the current edit engine text object. */
+ inline XclImpHFPortionInfo& GetCurrInfo() { return maInfos[ meCurrObj ]; }
+ /** Returns the current edit engine text object. */
+ inline XclImpHFPortionInfo::EditTextObjectRef& GetCurrObj() { return GetCurrInfo().mxObj; }
+ /** Returns the current selection. */
+ inline ESelection& GetCurrSel() { return GetCurrInfo().maSel; }
+
+ /** Returns the maximum line height of the specified portion. */
+ sal_uInt16 GetMaxLineHeight( XclImpHFPortion ePortion ) const;
+ /** Returns the current maximum line height. */
+ sal_uInt16 GetCurrMaxLineHeight() const;
+
+ /** Updates the maximum line height of the specified portion, using the current font size. */
+ void UpdateMaxLineHeight( XclImpHFPortion ePortion );
+ /** Updates the current maximum line height, using the current font size. */
+ void UpdateCurrMaxLineHeight();
+
+ /** Sets the font attributes at the current selection.
+ @descr After that, the start position of the current selection object is
+ adjusted to the end of the selection. */
+ void SetAttribs();
+ /** Resets font data to application default font. */
+ void ResetFontData();
+
+ /** Inserts maCurrText into edit engine and adjusts the current selection object.
+ @descr The text shall not contain a newline character.
+ The text will be cleared after insertion. */
+ void InsertText();
+ /** Inserts the passed text field and adjusts the current selection object. */
+ void InsertField( const SvxFieldItem& rFieldItem );
+ /** Inserts a line break and adjusts the current selection object. */
+ void InsertLineBreak();
+
+ /** Creates the edit engine text object of current portion from edit engine. */
+ void CreateCurrObject();
+ /** Changes current header/footer portion to eNew.
+ @descr Creates text object of current portion and reinitializes edit engine. */
+ void SetNewPortion( XclImpHFPortion eNew );
+
+private:
+ EditEngine& mrEE; /// The header/footer edit engine.
+ XclImpHFPortionInfoVec maInfos; /// Edit engine text objects for all portions.
+ String maCurrText; /// Current text to insert into edit engine.
+ XclFontDataPtr mxFontData; /// Font data of current text.
+ XclImpHFPortion meCurrObj; /// The current portion.
+};
+
+// URL conversion =============================================================
+
+/** This class contains static methods to decode an URL stored in an Excel file.
+ @descr Excel URLs can contain a sheet name, for instance: path\[test.xls]Sheet1
+ This sheet name will be extracted automatically. */
+class XclImpUrlHelper : boost::noncopyable
+{
+public:
+ /** Decodes an encoded external document URL with optional sheet name.
+ @param rUrl Returns the decoded file name incl. path.
+ @param rTabName Returns the decoded sheet name.
+ @param rbSameWb Returns true, if the URL is a reference to the own workbook.
+ @param rEncodedUrl An encoded URL from Excel. */
+ static void DecodeUrl(
+ String& rUrl,
+ String& rTabName,
+ bool& rbSameWb,
+ const XclImpRoot& rRoot,
+ const String& rEncodedUrl );
+
+ /** Decodes an encoded external document URL without sheet name.
+ @param rUrl Returns the decoded file name incl. path.
+ @param rbSameWb Returns true, if the URL is a reference to the own workbook.
+ @param rEncodedUrl An encoded URL from Excel. */
+ static void DecodeUrl(
+ String& rUrl,
+ bool& rbSameWb,
+ const XclImpRoot& rRoot,
+ const String& rEncodedUrl );
+
+ /** Decodes the passed URL to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ static bool DecodeLink( String& rApplic, String& rTopic, const String rEncUrl );
+
+private:
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static methods. To enforce this, the default constructor
+ is made private */
+ XclImpUrlHelper();
+};
+
+// Cached values ==============================================================
+
+class ScTokenArray;
+
+/** This class stores one cached value of a cached value list (used for instance in
+ CRN, EXTERNNAME, tArray). */
+class XclImpCachedValue : boost::noncopyable
+{
+public:
+ /** Creates a cached value and reads contents from stream and stores it with its array address. */
+ explicit XclImpCachedValue( XclImpStream& rStrm );
+ virtual ~XclImpCachedValue();
+
+ /** Returns the type of the cached value (EXC_CACHEDVAL_*). */
+ inline sal_uInt8 GetType() const { return mnType; }
+ /** Returns the cached string value, if this value is a string, else an empty string. */
+ inline const String& GetString() const { return mxStr.get() ? *mxStr : EMPTY_STRING; }
+ /** Returns the cached number, if this value has number type, else 0.0. */
+ inline double GetValue() const { return mfValue; }
+ /** Returns the cached Boolean value, if this value has Boolean type, else false. */
+ inline bool GetBool() const { return (mnType == EXC_CACHEDVAL_BOOL) && (mnBoolErr != 0); }
+ /** Returns the cached Calc error code, if this value has Error type, else 0. */
+ inline sal_uInt8 GetXclError() const { return (mnType == EXC_CACHEDVAL_ERROR) ? mnBoolErr : EXC_ERR_NA; }
+ /** Returns the cached Calc error code, if this value has Error type, else 0. */
+ sal_uInt16 GetScError() const;
+ /** Returns the token array if this is a Boolean value or error value, else 0. */
+ inline const ScTokenArray* GetBoolErrFmla() const { return mxTokArr.get(); }
+
+protected:
+ typedef ::std::auto_ptr< String > StringPtr;
+ typedef ::std::auto_ptr< const ScTokenArray > ScTokenArrayPtr;
+
+ StringPtr mxStr; /// Cached value is a string.
+ double mfValue; /// Cached value is a double.
+ ScTokenArrayPtr mxTokArr; /// Cached value is a formula or error code or Boolean.
+ sal_uInt8 mnBoolErr; /// Boolean value or Excel error code.
+ sal_uInt8 mnType; /// The type of the cached value (EXC_CACHEDVAL_*).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains cached values in a 2-dimensional array. */
+class XclImpCachedMatrix
+{
+public:
+ explicit XclImpCachedMatrix( XclImpStream& rStrm );
+ ~XclImpCachedMatrix();
+
+ /** Creates a new ScMatrix object and fills it with the contained values. */
+ ScMatrixRef CreateScMatrix() const;
+
+private:
+ typedef boost::ptr_vector< XclImpCachedValue > XclImpValueList;
+
+ XclImpValueList maValueList; /// List of cached cell values.
+ SCSIZE mnScCols; /// Number of cached columns.
+ SCSIZE mnScRows; /// Number of cached rows.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xilink.hxx b/sc/source/filter/inc/xilink.hxx
new file mode 100644
index 000000000000..2b2e9ac8a03c
--- /dev/null
+++ b/sc/source/filter/inc/xilink.hxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XILINK_HXX
+#define SC_XILINK_HXX
+
+#include <map>
+#include "xllink.hxx"
+#include "xiroot.hxx"
+#include "scmatrix.hxx"
+
+/* ============================================================================
+Classes for import of different kinds of internal/external references.
+- 3D cell and cell range links
+- External cell and cell range links
+- External defined names
+- Add-in functions
+- DDE links
+- OLE object links
+============================================================================ */
+
+// Excel sheet indexes ========================================================
+
+/** A buffer containing information about names and creation order of sheets.
+
+ The first purpose of this buffer is to translate original Excel
+ sheet names into Calc sheet indexes. This is not trivial because the filter
+ may rename the Calc sheets during creation. This buffer stores the original
+ Excel sheet names with the corresponding Calc sheet indexes.
+
+ The second purpose is to store the creation order of all sheets inside the
+ Excel workbook. The creation order list is contained in the TABID record
+ and needed to import the change log. Example: If the list contains 3;1;2
+ this means that the second sheet in the file was created first, than the
+ third sheet in the file was created and finally the first sheet.
+ */
+class XclImpTabInfo
+{
+public:
+ // original Excel sheet names ---------------------------------------------
+
+ /** Appends an original Excel sheet name with corresponding Calc sheet index. */
+ void AppendXclTabName( const String& rXclTabName, SCTAB nScTab );
+ /** Inserts a Calc sheet index (increases all following sheet indexes). */
+ void InsertScTab( SCTAB nScTab );
+
+ /** Returns the Calc sheet index from the passed original Excel sheet name. */
+ SCTAB GetScTabFromXclName( const String& rXclTabName ) const;
+
+ // record creation order - TABID record -----------------------------------
+
+ /** Reads the TABID record. */
+ void ReadTabid( XclImpStream& rStrm );
+
+ /** Returns the current sheet index calculated from creation index.
+ @param nCreatedId The creation index of the sheet (1-based).
+ @param nMaxTabId All values greater than this parameter are not used to find the index.
+ @return The 0-based index of the sheet nCreatedId if it is contained in the list.
+ Example: The buffer is 3;5;2;4;1, nCreatedId is 1 and nMaxTabId is 3. The function will
+ return 2 which is the 0-based index of sheet 1 in the list 3;2;1. */
+ sal_uInt16 GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMaxTabId = 0xFFFF ) const;
+
+private:
+ typedef ::std::map< String, SCTAB > XclTabNameMap;
+
+ XclTabNameMap maTabNames; /// All Excel sheet names with Calc sheet index.
+ ScfUInt16Vec maTabIdVec; /// The vector with sheet indexes.
+};
+
+// External names =============================================================
+
+/** Type of an external name. */
+enum XclImpExtNameType
+{
+ xlExtName, /// An external defined name.
+ xlExtAddIn, /// An add-in function name.
+ xlExtDDE, /// A DDE link range.
+ xlExtOLE, /// An OLE object link.
+ xlExtEuroConvert /// An external in Excel, but internal in OO function name.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclImpCachedMatrix;
+class ScTokenArray;
+class XclImpSupbook;
+
+/** Stores contents of an external name.
+ @descr Supported: External defined names, AddIn names, DDE links and OLE objects. */
+class XclImpExtName
+{
+ /**
+ * MOper, multiple operands, stores cached values of external range
+ * specified in the record.
+ */
+ class MOper
+ {
+ public:
+ MOper(XclImpStream& rStrm);
+ const ScMatrix& GetCache() const;
+ private:
+ ScMatrixRef mxCached;
+ };
+
+public:
+ /** Reads the external name from the stream. */
+ explicit XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm,
+ XclSupbookType eSubType, ExcelToSc* pFormulaConv );
+ ~XclImpExtName();
+
+ /** Create and apply the cached list of this DDE Link to the document. */
+ void CreateDdeData( ScDocument& rDoc,
+ const String& rApplc, const String& rExtDoc ) const;
+
+ void CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const;
+
+ /**
+ * Create OLE link data. OLE link data is converted to external
+ * reference, since OLE link doesn't work cross-platform, and is not very
+ * reliable even on Windows.
+ */
+ bool CreateOleData(ScDocument& rDoc, const ::rtl::OUString& rUrl,
+ sal_uInt16& rFileId, ::rtl::OUString& rTabName, ScRange& rRange) const;
+
+ bool HasFormulaTokens() const;
+
+ inline XclImpExtNameType GetType() const { return meType; }
+ inline const String& GetName() const { return maName; }
+ inline sal_uInt32 GetStorageId() const { return mnStorageId; }
+
+private:
+ typedef ::std::auto_ptr< XclImpCachedMatrix > XclImpCachedMatrixPtr;
+ typedef ::std::auto_ptr< ScTokenArray > TokenArrayPtr;
+
+ XclImpCachedMatrixPtr mxDdeMatrix; /// Cached results of the DDE link.
+ MOper* mpMOper; /// Cached values for OLE link
+ TokenArrayPtr mxArray; /// Formula tokens for external name.
+ String maName; /// The name of the external name.
+ sal_uInt32 mnStorageId; /// Storage ID for OLE object storages.
+ XclImpExtNameType meType; /// Type of the external name.
+};
+
+// Import link manager ========================================================
+
+class XclImpLinkManagerImpl;
+
+/** This is the central class for the import of all internal/external links.
+ @descr This manager stores all data about external documents with their sheets
+ and cached cell contents. Additionally it handles external names, such as add-in
+ function names, DDE links, and OLE object links.
+ File contents in BIFF8:
+ - Record SUPBOOK: Contains the name of an external document and the names of its sheets.
+ This record is optionally followed by NAME, EXTERNNAME, XCT and CRN records.
+ - Record XCT: Contains the number and sheet index of the following CRN records.
+ - Record CRN: Contains addresses (row and column) and values of external referenced cells.
+ - Record NAME: Contains defined names of the own workbook.
+ - Record EXTERNNAME: Contains external defined names, DDE links, or OLE object links.
+ - Record EXTERNSHEET: Contains indexes to URLs of external documents (SUPBOOKs)
+ and sheet indexes for each external reference used anywhere in the workbook.
+ This record follows a list of SUPBOOK records (with their attached records).
+*/
+class XclImpLinkManager : protected XclImpRoot
+{
+public:
+ explicit XclImpLinkManager( const XclImpRoot& rRoot );
+ ~XclImpLinkManager();
+
+ /** Reads the EXTERNSHEET record. */
+ void ReadExternsheet( XclImpStream& rStrm );
+ /** Reads a SUPBOOK record. */
+ void ReadSupbook( XclImpStream& rStrm );
+ /** Reads an XCT record and appends it to the current SUPBOOK. */
+ void ReadXct( XclImpStream& rStrm );
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+ /** Returns the Calc sheet index range of the specified XTI entry.
+ @return true = XTI data found, returned sheet index range is valid. */
+ bool GetScTabRange(
+ SCTAB& rnFirstScTab, SCTAB& rnLastScTab,
+ sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified external name or 0 on error. */
+ const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
+
+ const String* GetSupbookUrl( sal_uInt16 nXtiIndex ) const;
+
+ const String& GetSupbookTabName( sal_uInt16 nXti, sal_uInt16 nXtiTab ) const;
+
+ /** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
+ @descr For DDE links: Decodes to application name and topic.
+ For OLE object links: Decodes to class name and document URL.
+ @return true = decoding was successful, returned strings are valid (not empty). */
+ bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
+ /** Returns the specified macro name or an empty string on error. */
+ const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
+
+private:
+ typedef ::std::auto_ptr< XclImpLinkManagerImpl > XclImpLinkMgrImplPtr;
+ XclImpLinkMgrImplPtr mxImpl;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xiname.hxx b/sc/source/filter/inc/xiname.hxx
new file mode 100644
index 000000000000..8d05d680d690
--- /dev/null
+++ b/sc/source/filter/inc/xiname.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XINAME_HXX
+#define SC_XINAME_HXX
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include "xlname.hxx"
+#include "xiroot.hxx"
+
+//class ScDocument;
+//class ScTokenArray;
+
+// ============================================================================
+
+class ScRangeData;
+
+/** Represents a defined name. It may be related to a single sheet or global. */
+class XclImpName : protected XclImpRoot
+{
+public:
+ explicit XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx );
+
+ inline const String& GetXclName() const { return maXclName; }
+ inline const String& GetScName() const { return maScName; }
+ inline SCTAB GetScTab() const { return mnScTab; }
+ inline const ScRangeData* GetScRangeData() const { return mpScData; }
+ inline bool IsGlobal() const { return mnScTab == SCTAB_MAX; }
+ inline bool IsFunction() const { return mbFunction; }
+ inline bool IsVBName() const { return mbVBName; }
+
+private:
+ String maXclName; /// Original name read from the file.
+ String maScName; /// Name inserted into the Calc document.
+ const ScRangeData* mpScData; /// Pointer to Calc defined name (no ownership).
+ sal_Unicode mcBuiltIn; /// Excel built-in name index.
+ SCTAB mnScTab; /// Calc sheet index of local names.
+ bool mbFunction; /// true = Name refers to a function (add-in or VBA).
+ bool mbVBName; /// true = Visual Basic procedure or function.
+};
+
+// ----------------------------------------------------------------------------
+
+/** This buffer contains all internal defined names of the document.
+ @descr It manages the position of the names in the document, means if they are
+ global or attached to a specific sheet. While inserting the names into the Calc
+ document this buffer resolves conflicts caused by equal names from different
+ sheets. */
+class XclImpNameManager : protected XclImpRoot
+{
+public:
+ explicit XclImpNameManager( const XclImpRoot& rRoot );
+
+ /** Reads a NAME record and creates an entry in this buffer. */
+ void ReadName( XclImpStream& rStrm );
+
+ /** Tries to find the name used in Calc, based on the original Excel defined name.
+ @param nScTab The sheet index for local names or SCTAB_MAX for global names.
+ If no local name is found, tries to find a matching global name.
+ @return Pointer to the defined name or 0 on error. */
+ const XclImpName* FindName( const String& rXclName, SCTAB nScTab = SCTAB_MAX ) const;
+
+ /** Returns the defined name specified by its Excel index.
+ @param nXclNameIdx The index of the internal defined name.
+ @return Pointer to the defined name or 0 on error. */
+ const XclImpName* GetName( sal_uInt16 nXclNameIdx ) const;
+
+private:
+ typedef boost::ptr_vector< XclImpName > XclImpNameList;
+ XclImpNameList maNameList;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xipage.hxx b/sc/source/filter/inc/xipage.hxx
new file mode 100644
index 000000000000..5f8e7c6b3f70
--- /dev/null
+++ b/sc/source/filter/inc/xipage.hxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIPAGE_HXX
+#define SC_XIPAGE_HXX
+
+#include "xlpage.hxx"
+#include "xiroot.hxx"
+
+// Page settings ==============================================================
+
+/** Contains all page (print) settings for a single sheet.
+ @descr Supports reading all related records and creating a page style sheet. */
+class XclImpPageSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpPageSettings( const XclImpRoot& rRoot );
+
+ /** Returns read-only access to the page data. */
+ inline const XclPageData& GetPageData() const { return maData; }
+
+ /** Initializes the object to be used for a new sheet. */
+ void Initialize();
+
+ /** Reads a SETUP record and inserts contained data. */
+ void ReadSetup( XclImpStream& rStrm );
+ /** Reads a ***MARGIN record (reads all 4 margin records). */
+ void ReadMargin( XclImpStream& rStrm );
+ /** Reads a HCENTER or VCENTER record. */
+ void ReadCenter( XclImpStream& rStrm );
+ /** Reads a HEADER or FOOTER record. */
+ void ReadHeaderFooter( XclImpStream& rStrm );
+ /** Reads a HORIZONTALPAGEBREAKS or VERTICALPAGEBREAKS record. */
+ void ReadPageBreaks( XclImpStream& rStrm );
+ /** Reads a PRINTHEADERS record. */
+ void ReadPrintHeaders( XclImpStream& rStrm );
+ /** Reads a PRINTGRIDLINES record. */
+ void ReadPrintGridLines( XclImpStream& rStrm );
+ /** Reads an IMGDATA record and creates the SvxBrushItem. */
+ void ReadImgData( XclImpStream& rStrm );
+
+ /** Overrides paper size and orientation (used in sheet-charts). */
+ void SetPaperSize( sal_uInt16 nXclPaperSize, bool bPortrait );
+ /** Sets or clears the fit-to-pages setting (contained in WSBOOL record). */
+ inline void SetFitToPages( bool bFitToPages ) { maData.mbFitToPages = bFitToPages; }
+
+ /** Creates a page stylesheet from current settings and sets it at current sheet. */
+ void Finalize();
+
+private:
+ XclPageData maData; /// Page settings data.
+ bool mbValidPaper; /// true = Paper size and orientation valid.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx
new file mode 100644
index 000000000000..8a8e6b7696dd
--- /dev/null
+++ b/sc/source/filter/inc/xipivot.hxx
@@ -0,0 +1,467 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIPIVOT_HXX
+#define SC_XIPIVOT_HXX
+
+#include <list>
+#include "xlpivot.hxx"
+#include "xiroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+class ScDPSaveData;
+class ScDPSaveDimension;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item in a pivot cache. */
+class XclImpPCItem : public XclPCItem
+{
+public:
+ explicit XclImpPCItem( XclImpStream& rStrm );
+
+ /** Inserts the item data into the passed document. */
+ void WriteToSource( const XclImpRoot& rRoot, const ScAddress& rScPos ) const;
+
+private:
+ /** Reads an SXDOUBLE record describing a floating-point item. */
+ void ReadSxdouble( XclImpStream& rStrm );
+ /** Reads an SXBOOLEAN record describing a boolean item. */
+ void ReadSxboolean( XclImpStream& rStrm );
+ /** Reads an SXERROR record describing an error code item. */
+ void ReadSxerror( XclImpStream& rStrm );
+ /** Reads an SXINTEGER record describing an integer item. */
+ void ReadSxinteger( XclImpStream& rStrm );
+ /** Reads an SXSTRING record describing a text item. */
+ void ReadSxstring( XclImpStream& rStrm );
+ /** Reads an SXDATETIME record describing a date/time item. */
+ void ReadSxdatetime( XclImpStream& rStrm );
+ /** Reads an SXEMPTY record describing an empty item. */
+ void ReadSxempty( XclImpStream& rStrm );
+};
+
+typedef boost::shared_ptr< XclImpPCItem > XclImpPCItemRef;
+
+// ============================================================================
+
+struct ScDPNumGroupInfo;
+class XclImpPivotCache;
+
+/** Represents a field in a pivot cache (a column of data items in the source area). */
+class XclImpPCField : public XclPCField, protected XclImpRoot
+{
+public:
+ /** Creates a pivot cache field by reading an SXFIELD record. */
+ explicit XclImpPCField( const XclImpRoot& rRoot,
+ XclImpPivotCache& rPCache, sal_uInt16 nFieldIdx );
+ virtual ~XclImpPCField();
+
+ // general field/item access ----------------------------------------------
+
+ /** Returns the name of the field, uses the passed visible name if supported. */
+ const String& GetFieldName( const ScfStringVec& rVisNames ) const;
+
+ /** Returns the base field if this is a grouping field. */
+ const XclImpPCField* GetGroupBaseField() const;
+
+ /** Returns the item at the specified position or 0 on error. */
+ const XclImpPCItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the item representing a limit value in numeric/date/time grouping fields.
+ @param nItemIdx One of EXC_SXFIELD_INDEX_MIN, EXC_SXFIELD_INDEX_MAX, or EXC_SXFIELD_INDEX_STEP. */
+ const XclImpPCItem* GetLimitItem( sal_uInt16 nItemIdx ) const;
+
+ /** Inserts the field name into the document. */
+ void WriteFieldNameToSource( SCCOL nScCol, SCTAB nScTab ) const;
+ /** Inserts the specified item data into the document. */
+ void WriteOrigItemToSource( SCROW nScRow, SCTAB nScTab, sal_uInt16 nItemIdx ) const;
+ /** Inserts the data of the last inserted item into the document. */
+ void WriteLastOrigItemToSource( SCROW nScRow, SCTAB nScTab ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads the SXFIELD record describing the field. */
+ void ReadSxfield( XclImpStream& rStrm );
+ /** Reads an item data record describing a new item. */
+ void ReadItem( XclImpStream& rStrm );
+ /** Reads the SXNUMGROUP record describing numeric grouping fields. */
+ void ReadSxnumgroup( XclImpStream& rStrm );
+ /** Reads the SXGROUPINFO record describing the item order in grouping fields. */
+ void ReadSxgroupinfo( XclImpStream& rStrm );
+
+ // grouping ---------------------------------------------------------------
+
+ /** Inserts grouping information of this field into the passed ScDPSaveData. */
+ void ConvertGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ /** Inserts standard grouping information of this field into the passed ScDPSaveData. */
+ void ConvertStdGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+ /** Inserts numeric grouping information of this field into the passed ScDPSaveData. */
+ void ConvertNumGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+ /** Inserts date grouping information of this field into the passed ScDPSaveData. */
+ void ConvertDateGroupField( ScDPSaveData& rSaveData, const ScfStringVec& rVisNames ) const;
+
+ /** Returns a Calc struct with numeric grouping data. */
+ ScDPNumGroupInfo GetScNumGroupInfo() const;
+ /** Returns a Calc struct with date grouping data. */
+ ScDPNumGroupInfo GetScDateGroupInfo() const;
+
+ /** Returns a limit value for numeric grouping fields. */
+ const double* GetNumGroupLimit( sal_uInt16 nLimitIdx ) const;
+ /** Returns a limit value for date grouping fields (minimum/maximum only). */
+ const DateTime* GetDateGroupLimit( sal_uInt16 nLimitIdx ) const;
+ /** Returns the step value for date grouping fields. */
+ const sal_Int16* GetDateGroupStep() const;
+
+private:
+ typedef ::std::vector< XclImpPCItemRef > XclImpPCItemVec;
+
+ XclImpPivotCache& mrPCache; /// Parent pivot cache containing this field.
+ XclImpPCItemVec maItems; /// List of all displayed data items.
+ XclImpPCItemVec maOrigItems; /// List of all source data items.
+ XclImpPCItemVec maNumGroupItems; /// List of items containing numeric grouping limits.
+ mutable SCCOL mnSourceScCol; /// Column index of source data for this field.
+ bool mbNumGroupInfoRead; /// true = Numeric grouping info read (SXNUMGROUP record).
+};
+
+typedef boost::shared_ptr< XclImpPCField > XclImpPCFieldRef;
+
+// ============================================================================
+
+class XclImpPivotCache : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotCache( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotCache();
+
+ // data access ------------------------------------------------------------
+
+ /** Returns the data source range read from the DCONREF record. */
+ inline const ScRange& GetSourceRange() const { return maSrcRange; }
+
+ const ::rtl::OUString& GetSourceRangeName() const { return maSrcRangeName; }
+
+ /** Returns the number of pivot cache fields. */
+ sal_uInt16 GetFieldCount() const;
+ /** Returns read-only access to a pivot cache field. */
+ const XclImpPCField* GetField( sal_uInt16 nFieldIdx ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXIDSTM record containing a pivot cache stream identifier and the pivot cache. */
+ void ReadSxidstm( XclImpStream& rStrm );
+ /** Reads an SXVS record containing the source type of the pivot cache. */
+ void ReadSxvs( XclImpStream& rStrm );
+ /** Reads a DCONREF record containing the source range of the pivot cache. */
+ void ReadDconref( XclImpStream& rStrm );
+ /**
+ * Read DECONNAME record which contains the defined name of the source
+ * range.
+ */
+ void ReadDConName( XclImpStream& rStrm );
+ /** Reads the entire pivot cache stream. Uses decrypter from passed stream. */
+ void ReadPivotCacheStream( XclImpStream& rStrm );
+
+ bool HasCacheRecords() const;
+ bool IsRefreshOnLoad() const;
+ bool IsValid() const;
+
+private:
+ typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec;
+
+ XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record).
+ XclImpPCFieldVec maFields; /// List of pivot cache fields.
+ ScRange maSrcRange; /// Source range in the spreadsheet.
+ String maUrl; /// URL of the source data.
+ String maTabName; /// Sheet name of the source data.
+ ::rtl::OUString maSrcRangeName; /// Name of the source data range.
+ sal_uInt16 mnStrmId; /// Pivot cache stream identifier.
+ sal_uInt16 mnSrcType; /// Source data type.
+ bool mbSelfRef; /// true = Source data from own document.
+};
+
+typedef boost::shared_ptr< XclImpPivotCache > XclImpPivotCacheRef;
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+class XclImpPivotTable;
+
+// ============================================================================
+
+class XclImpPTItem
+{
+public:
+ explicit XclImpPTItem( const XclImpPCField* pCacheField );
+
+ /** Returns the internal name of the item or 0, if no name could be found. */
+ const String* GetItemName() const;
+ /** Returns the displayed name of the item or 0, if no name could be found. */
+ const String* GetVisItemName() const;
+
+ /** Reads an SXVI record containing data of this item. */
+ void ReadSxvi( XclImpStream& rStrm );
+
+ /** Inserts this item into the passed ScDPSaveDimension. */
+ void ConvertItem( ScDPSaveDimension& rSaveDim ) const;
+
+private:
+ XclPTItemInfo maItemInfo; /// General data for this item.
+ const XclImpPCField* mpCacheField; /// Corresponding pivot cache field.
+};
+
+typedef boost::shared_ptr< XclImpPTItem > XclImpPTItemRef;
+
+// ============================================================================
+
+class XclImpPTField
+{
+public:
+ explicit XclImpPTField( const XclImpPivotTable& rPTable, sal_uInt16 nCacheIdx );
+
+ // general field/item access ----------------------------------------------
+
+ /** Returns the corresponding pivot cache field of this field. */
+ const XclImpPCField* GetCacheField() const;
+ /** Returns the name of this field that is used to create the Calc dimensions. */
+ const String& GetFieldName() const;
+ /** Returns the internally set visible name of this field. */
+ const String& GetVisFieldName() const;
+
+ /** Returns the specified item. */
+ const XclImpPTItem* GetItem( sal_uInt16 nItemIdx ) const;
+ /** Returns the internal name of the specified item. */
+ const String* GetItemName( sal_uInt16 nItemIdx ) const;
+
+ /** Returns the flags of the axes this field is part of. */
+ inline sal_uInt16 GetAxes() const { return maFieldInfo.mnAxes; }
+ /** Sets the flags of the axes this field is part of. */
+ inline void SetAxes( sal_uInt16 nAxes ) { maFieldInfo.mnAxes = nAxes; }
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXVD record describing the field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of the field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of this field. */
+ void ReadSxvi( XclImpStream& rStrm );
+
+ // row/column fields ------------------------------------------------------
+
+ void ConvertRowColField( ScDPSaveData& rSaveData ) const;
+
+ // page fields ------------------------------------------------------------
+
+ void SetPageFieldInfo( const XclPTPageFieldInfo& rPageInfo );
+ void ConvertPageField( ScDPSaveData& rSaveData ) const;
+
+ // hidden fields ----------------------------------------------------------
+
+ void ConvertHiddenField( ScDPSaveData& rSaveData ) const;
+
+ // data fields ------------------------------------------------------------
+
+ bool HasDataFieldInfo() const;
+ void AddDataFieldInfo( const XclPTDataFieldInfo& rDataInfo );
+ void ConvertDataField( ScDPSaveData& rSaveData ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ ScDPSaveDimension* ConvertRCPField( ScDPSaveData& rSaveData ) const;
+ void ConvertFieldInfo( ScDPSaveDimension& rSaveDim ) const;
+
+ void ConvertDataField( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const;
+ void ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const;
+ void ConvertItems( ScDPSaveDimension& rSaveDim ) const;
+
+private:
+ typedef ::std::list< XclPTDataFieldInfo > XclPTDataFieldInfoList;
+ typedef ::std::vector< XclImpPTItemRef > XclImpPTItemVec;
+
+ const XclImpPivotTable& mrPTable; /// Parent pivot table containing this field.
+ XclPTFieldInfo maFieldInfo; /// General field info (SXVD record).
+ XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record).
+ XclPTPageFieldInfo maPageInfo; /// Page field info (entry from SXPI record).
+ XclPTDataFieldInfoList maDataInfoList; /// List of extended data field info (SXDI records).
+ XclImpPTItemVec maItems; /// List of all items of this field.
+};
+
+typedef boost::shared_ptr< XclImpPTField > XclImpPTFieldRef;
+
+// ============================================================================
+
+class XclImpPivotTable : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotTable( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotTable();
+
+ // cache/field access, misc. ----------------------------------------------
+
+ inline XclImpPivotCacheRef GetPivotCache() const { return mxPCache; }
+ inline const ScfStringVec& GetVisFieldNames() const { return maVisFieldNames; }
+
+ sal_uInt16 GetFieldCount() const;
+ const XclImpPTField* GetField( sal_uInt16 nFieldIdx ) const;
+ XclImpPTField* GetFieldAcc( sal_uInt16 nFieldIdx );
+ const String& GetFieldName( sal_uInt16 nFieldIdx ) const;
+
+ const XclImpPTField* GetDataField( sal_uInt16 nDataFieldIdx ) const;
+ const String& GetDataFieldName( sal_uInt16 nDataFieldIdx ) const;
+
+ // records ----------------------------------------------------------------
+
+ /** Reads an SXVIEW record starting a new pivot table. */
+ void ReadSxview( XclImpStream& rStrm );
+ /** Reads an SXVD record describing a new field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of the current field. */
+ void ReadSxvi( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of the current field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXIVD record containing the row field or column field order. */
+ void ReadSxivd( XclImpStream& rStrm );
+ /** Reads an SXPI record containing page field data. */
+ void ReadSxpi( XclImpStream& rStrm );
+ /** Reads an SXDI record containing data field data. */
+ void ReadSxdi( XclImpStream& rStrm );
+ /** Reads an SXEX record containing additional settings for the pivot table. */
+ void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+
+ /** Inserts the pivot table into the Calc document. */
+ void Convert();
+
+ void MaybeRefresh();
+
+ void ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData);
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec;
+
+ XclImpPivotCacheRef mxPCache; /// Pivot cache containing field/item names.
+
+ XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record).
+ XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record)
+ XclImpPTFieldVec maFields; /// Vector containing all fields.
+ XclImpPTFieldRef mxCurrField; /// Current field for importing additional info.
+ ScfStringVec maVisFieldNames; /// Vector containing all visible field names.
+ ScfUInt16Vec maRowFields; /// Row field indexes.
+ ScfUInt16Vec maColFields; /// Column field indexes.
+ ScfUInt16Vec maPageFields; /// Page field indexes.
+ ScfUInt16Vec maOrigDataFields; /// Original data field indexes.
+ ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes.
+ XclImpPTField maDataOrientField; /// Special data field orientation field.
+ ScRange maOutScRange; /// Output range in the Calc document.
+ ScDPObject* mpDPObj;
+};
+
+typedef boost::shared_ptr< XclImpPivotTable > XclImpPivotTableRef;
+
+// ============================================================================
+// ============================================================================
+
+/** The main class for pivot table import.
+
+ This class contains functions to read all records related to pivot tables
+ and pivot caches.
+ */
+class XclImpPivotTableManager : protected XclImpRoot
+{
+public:
+ explicit XclImpPivotTableManager( const XclImpRoot& rRoot );
+ virtual ~XclImpPivotTableManager();
+
+ // pivot cache records ----------------------------------------------------
+
+ /** Returns the pivot cache with the specified 0-based index. */
+ XclImpPivotCacheRef GetPivotCache( sal_uInt16 nCacheIdx );
+
+ /** Reads an SXIDSTM record containing a pivot cache stream identifier and the pivot cache. */
+ void ReadSxidstm( XclImpStream& rStrm );
+ /** Reads an SXVS record containing the source type of a pivot cache. */
+ void ReadSxvs( XclImpStream& rStrm );
+ /** Reads a DCONREF record containing the source range of a pivot cache. */
+ void ReadDconref( XclImpStream& rStrm );
+ void ReadDConName( XclImpStream& rStrm );
+
+ // pivot table records ----------------------------------------------------
+
+ /** Reads an SXVIEW record describing a new pivot table. */
+ void ReadSxview( XclImpStream& rStrm );
+ /** Reads an SXVD record describing a new field. */
+ void ReadSxvd( XclImpStream& rStrm );
+ /** Reads an SXVDEX record describing extended options of a field. */
+ void ReadSxvdex( XclImpStream& rStrm );
+ /** Reads an SXIVD record containing the row field or column field order. */
+ void ReadSxivd( XclImpStream& rStrm );
+ /** Reads an SXPI record containing page field data. */
+ void ReadSxpi( XclImpStream& rStrm );
+ /** Reads an SXDI record containing data field data. */
+ void ReadSxdi( XclImpStream& rStrm );
+ /** Reads an SXVI record describing a new item of the current field. */
+ void ReadSxvi( XclImpStream& rStrm );
+ /** Reads an SXEX record containing additional settings for a pivot table. */
+ void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
+
+ // ------------------------------------------------------------------------
+
+ /** Reads all used pivot caches and creates additional sheets for external data sources. */
+ void ReadPivotCaches( XclImpStream& rStrm );
+ /** Inserts all pivot tables into the Calc document. */
+ void ConvertPivotTables();
+
+ void MaybeRefreshPivotTables();
+
+private:
+ typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec;
+ typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec;
+
+ XclImpPivotCacheVec maPCaches; /// List of all pivot caches.
+ XclImpPivotTableVec maPTables; /// List of all pivot tables.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx
new file mode 100644
index 000000000000..653d39c7e1d0
--- /dev/null
+++ b/sc/source/filter/inc/xiroot.hxx
@@ -0,0 +1,228 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIROOT_HXX
+#define SC_XIROOT_HXX
+
+#include "xlroot.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Forward declarations of objects in public use ==============================
+
+class XclImpStream;
+class XclImpString;
+
+typedef boost::shared_ptr< XclImpString > XclImpStringRef;
+
+// Global data ================================================================
+
+class XclImpAddressConverter;
+class XclImpFormulaCompiler;
+class XclImpSst;
+class XclImpPalette;
+class XclImpFontBuffer;
+class XclImpNumFmtBuffer;
+class XclImpXFBuffer;
+class XclImpXFRangeBuffer;
+class XclImpTabInfo;
+class XclImpNameManager;
+class XclImpLinkManager;
+class XclImpObjectManager;
+class XclImpSheetDrawing;
+class XclImpCondFormatManager;
+class XclImpValidationManager;
+class XclImpAutoFilterBuffer;
+class XclImpWebQueryBuffer;
+class XclImpPivotTableManager;
+class XclImpPageSettings;
+class XclImpDocViewSettings;
+class XclImpTabViewSettings;
+class XclImpSheetProtectBuffer;
+class XclImpDocProtectBuffer;
+
+class _ScRangeListTabs;
+class ExcelToSc;
+
+/** Stores global buffers and data needed for Excel import filter. */
+struct XclImpRootData : public XclRootData
+{
+ typedef boost::shared_ptr< XclImpAddressConverter > XclImpAddrConvRef;
+ typedef boost::shared_ptr< XclImpFormulaCompiler > XclImpFmlaCompRef;
+
+ typedef boost::shared_ptr< XclImpSst > XclImpSstRef;
+ typedef boost::shared_ptr< XclImpPalette > XclImpPaletteRef;
+ typedef boost::shared_ptr< XclImpFontBuffer > XclImpFontBfrRef;
+ typedef boost::shared_ptr< XclImpNumFmtBuffer > XclImpNumFmtBfrRef;
+ typedef boost::shared_ptr< XclImpXFBuffer > XclImpXFBfrRef;
+ typedef boost::shared_ptr< XclImpXFRangeBuffer > XclImpXFRangeBfrRef;
+ typedef boost::shared_ptr< XclImpTabInfo > XclImpTabInfoRef;
+ typedef boost::shared_ptr< XclImpNameManager > XclImpNameMgrRef;
+ typedef boost::shared_ptr< XclImpLinkManager > XclImpLinkMgrRef;
+ typedef boost::shared_ptr< XclImpObjectManager > XclImpObjectMgrRef;
+ typedef boost::shared_ptr< XclImpCondFormatManager > XclImpCondFmtMgrRef;
+ typedef boost::shared_ptr< XclImpValidationManager > XclImpValidationMgrRef;
+ typedef boost::shared_ptr< XclImpWebQueryBuffer > XclImpWebQueryBfrRef;
+ typedef boost::shared_ptr< XclImpPivotTableManager > XclImpPTableMgrRef;
+ typedef boost::shared_ptr< XclImpPageSettings > XclImpPageSettRef;
+ typedef boost::shared_ptr< XclImpDocViewSettings > XclImpDocViewSettRef;
+ typedef boost::shared_ptr< XclImpTabViewSettings > XclImpTabViewSettRef;
+ typedef boost::shared_ptr< XclImpSheetProtectBuffer > XclImpTabProtectRef;
+ typedef boost::shared_ptr< XclImpDocProtectBuffer > XclImpDocProtectRef;
+
+ XclImpAddrConvRef mxAddrConv; /// The address converter.
+ XclImpFmlaCompRef mxFmlaComp; /// The formula compiler.
+
+ XclImpSstRef mxSst; /// The shared string table.
+ XclImpPaletteRef mxPalette; /// The color buffer.
+ XclImpFontBfrRef mxFontBfr; /// All fonts in the file.
+ XclImpNumFmtBfrRef mxNumFmtBfr; /// All number formats in the file.
+ XclImpXFBfrRef mpXFBfr; /// All XF record data in the file.
+ XclImpXFRangeBfrRef mxXFRangeBfr; /// Buffer of XF index ranges in a sheet.
+
+ XclImpTabInfoRef mxTabInfo; /// Sheet creation order list.
+ XclImpNameMgrRef mxNameMgr; /// Internal defined names.
+ XclImpLinkMgrRef mxLinkMgr; /// Manager for internal/external links.
+
+ XclImpObjectMgrRef mxObjMgr; /// All drawing objects.
+ XclImpCondFmtMgrRef mxCondFmtMgr; /// Conditional formattings.
+ XclImpValidationMgrRef mxValidMgr; /// Data validation
+ XclImpWebQueryBfrRef mxWebQueryBfr; /// All web queries.
+ XclImpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
+
+ XclImpPageSettRef mxPageSett; /// Page settings for current sheet.
+ XclImpDocViewSettRef mxDocViewSett; /// View settings for entire document.
+ XclImpTabViewSettRef mxTabViewSett; /// View settings for current sheet.
+ XclImpTabProtectRef mxTabProtect; /// Sheet protection options for current sheet.
+ XclImpDocProtectRef mxDocProtect; /// Document protection options.
+
+ bool mbHasCodePage; /// true = CODEPAGE record exists.
+ bool mbHasBasic; /// true = document contains VB project.
+
+ explicit XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc );
+ virtual ~XclImpRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Access to global data from other classes. */
+class XclImpRoot : public XclRoot
+{
+public:
+ explicit XclImpRoot( XclImpRootData& rImpRootData );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclImpRoot& GetRoot() const { return *this; }
+
+ /** Sets a code page read from a CODEPAGE record for byte string import. */
+ void SetCodePage( sal_uInt16 nCodePage );
+ /** Sets text encoding from the default application font (in case of missing CODEPAGE record). */
+ void SetAppFontEncoding( rtl_TextEncoding eAppFontEnc );
+
+ /** Is called when import filter starts importing a single sheet (all BIFF versions). */
+ void InitializeTable( SCTAB nScTab );
+ /** Is called when import filter stops importing a single sheet (all BIFF versions). */
+ void FinalizeTable();
+
+ /** Returns the address converter. */
+ XclImpAddressConverter& GetAddressConverter() const;
+ /** Returns the formula converter. */
+ XclImpFormulaCompiler& GetFormulaCompiler() const;
+ /** Returns the old formula converter. */
+ ExcelToSc& GetOldFmlaConverter() const;
+
+ /** Returns the shared string table. */
+ XclImpSst& GetSst() const;
+ /** Returns the color buffer. */
+ XclImpPalette& GetPalette() const;
+ /** Returns the font buffer. */
+ XclImpFontBuffer& GetFontBuffer() const;
+ /** Returns the number format buffer. */
+ XclImpNumFmtBuffer& GetNumFmtBuffer() const;
+ /** Returns the cell formatting attributes buffer. */
+ XclImpXFBuffer& GetXFBuffer() const;
+ /** Returns the buffer of XF index ranges for a sheet. */
+ XclImpXFRangeBuffer& GetXFRangeBuffer() const;
+
+ /** Returns the buffer that contains all print areas in the document. */
+ _ScRangeListTabs& GetPrintAreaBuffer() const;
+ /** Returns the buffer that contains all print titles in the document. */
+ _ScRangeListTabs& GetTitleAreaBuffer() const;
+
+ /** Returns the buffer that contains the sheet creation order. */
+ XclImpTabInfo& GetTabInfo() const;
+ /** Returns the buffer that contains internal defined names. */
+ XclImpNameManager& GetNameManager() const;
+ /** Returns the link manager. */
+ XclImpLinkManager& GetLinkManager() const;
+
+ /** Returns the drawing object manager. */
+ XclImpObjectManager& GetObjectManager() const;
+ /** Returns the drawing container of the current sheet. */
+ XclImpSheetDrawing& GetCurrSheetDrawing() const;
+ /** Returns the conditional formattings manager. */
+ XclImpCondFormatManager& GetCondFormatManager() const;
+
+ XclImpValidationManager& GetValidationManager() const;
+ /** Returns the filter manager. */
+ XclImpAutoFilterBuffer& GetFilterManager() const;
+ /** Returns the web query buffer. */
+ XclImpWebQueryBuffer& GetWebQueryBuffer() const;
+ /** Returns the pivot table manager. */
+ XclImpPivotTableManager& GetPivotTableManager() const;
+ /** Returns the sheet protection options of the current sheet. */
+ XclImpSheetProtectBuffer& GetSheetProtectBuffer() const;
+ /** Returns the document protection options. */
+ XclImpDocProtectBuffer& GetDocProtectBuffer() const;
+
+ /** Returns the page settings of the current sheet. */
+ XclImpPageSettings& GetPageSettings() const;
+ /** Returns the view settings of the entire document. */
+ XclImpDocViewSettings& GetDocViewSettings() const;
+ /** Returns the view settings of the current sheet. */
+ XclImpTabViewSettings& GetTabViewSettings() const;
+
+ /** Returns the Calc add-in function name for an Excel function name. */
+ String GetScAddInName( const String& rXclName ) const;
+
+ /** Returns true, if the document contains a VB project. */
+ inline bool HasBasic() const { return mrImpData.mbHasBasic; }
+ /** Called to indicate that the document contains a VB project. */
+ inline void SetHasBasic() { mrImpData.mbHasBasic = true; }
+ /** Reads the CODENAME record and inserts the codename into the document. */
+ void ReadCodeName( XclImpStream& rStrm, bool bGlobals );
+
+private:
+ XclImpRootData& mrImpData; /// Reference to the global import data struct.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
new file mode 100644
index 000000000000..238997e7a000
--- /dev/null
+++ b/sc/source/filter/inc/xistream.hxx
@@ -0,0 +1,532 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTREAM_HXX
+#define SC_XISTREAM_HXX
+
+#include <comphelper/docpasswordhelper.hxx>
+#include <filter/msfilter/mscodec.hxx>
+#include <boost/shared_ptr.hpp>
+#include "xlstream.hxx"
+#include "xlconst.hxx"
+
+class XclImpRoot;
+
+/* ============================================================================
+Input stream class for Excel import
+- CONTINUE record handling
+- ByteString and UniString support
+- Decryption
+============================================================================ */
+
+// ============================================================================
+// Decryption
+// ============================================================================
+
+class XclImpDecrypter;
+typedef boost::shared_ptr< XclImpDecrypter > XclImpDecrypterRef;
+
+/** Base class for BIFF stream decryption. */
+class XclImpDecrypter : public ::comphelper::IDocPasswordVerifier
+{
+public:
+ explicit XclImpDecrypter();
+ virtual ~XclImpDecrypter();
+
+ /** Returns the current error code of the decrypter. */
+ inline ErrCode GetError() const { return mnError; }
+ /** Returns true, if the decoder has been initialized correctly. */
+ inline bool IsValid() const { return mnError == ERRCODE_NONE; }
+
+ /** Creates a (ref-counted) copy of this decrypter object. */
+ XclImpDecrypterRef Clone() const;
+
+ /** 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 >& rEncryptionData );
+
+ /** Updates the decrypter on start of a new record or after seeking stream. */
+ void Update( SvStream& rStrm, sal_uInt16 nRecSize );
+ /** Reads and decrypts nBytes bytes and stores data into the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_uInt16 Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes );
+
+protected:
+ /** Protected copy c'tor for OnClone(). */
+ explicit XclImpDecrypter( const XclImpDecrypter& rSrc );
+
+private:
+ /** Implementation of cloning this object. */
+ virtual XclImpDecrypter* OnClone() const = 0;
+ /** Derived classes implement password verification and initialization of
+ the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
+ OnVerifyPassword( const ::rtl::OUString& rPassword ) = 0;
+ virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0;
+
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) = 0;
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ) = 0;
+
+private:
+ ErrCode mnError; /// Decrypter error code.
+ sal_Size mnOldPos; /// Last known stream position.
+ sal_uInt16 mnRecSize; /// Current record size.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Decrypts BIFF5 stream contents. */
+class XclImpBiff5Decrypter : public XclImpDecrypter
+{
+public:
+ explicit XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash );
+
+private:
+ /** Private copy c'tor for OnClone(). */
+ explicit XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc );
+
+ /** Implementation of cloning this object. */
+ virtual XclImpBiff5Decrypter* OnClone() const;
+ /** Implements password verification and initialization of the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
+ OnVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize );
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes );
+
+private:
+ ::msfilter::MSCodec_XorXLS95 maCodec; /// Crypto algorithm implementation.
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData;
+ sal_uInt16 mnKey;
+ sal_uInt16 mnHash;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Decrypts BIFF8 stream contents using the given document identifier. */
+class XclImpBiff8Decrypter : public XclImpDecrypter
+{
+public:
+ explicit XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
+ sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] );
+
+private:
+ /** Private copy c'tor for OnClone(). */
+ explicit XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc );
+
+ /** Implementation of cloning this object. */
+ virtual XclImpBiff8Decrypter* OnClone() const;
+ /** Implements password verification and initialization of the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
+ OnVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
+ /** Implementation of updating the decrypter. */
+ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize );
+ /** Implementation of the decryption. */
+ virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes );
+
+ /** Returns the block number corresponding to the passed stream position. */
+ sal_uInt32 GetBlock( sal_Size nStrmPos ) const;
+ /** Returns the block offset corresponding to the passed stream position. */
+ sal_uInt16 GetOffset( sal_Size nStrmPos ) const;
+
+private:
+ ::msfilter::MSCodec_Std97 maCodec; /// Crypto 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;
+};
+
+// ============================================================================
+// Stream
+// ============================================================================
+
+/** This class represents an Excel stream position.
+ @descr It contains the relevant data for a stream position inside of a record
+ (including CONTINUE records). */
+class XclImpStreamPos
+{
+public:
+ /** Constructs an invalid stream position data object. */
+ explicit XclImpStreamPos();
+
+ /** Sets the stream position data to the passed values. */
+ void Set( const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
+ sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
+ bool bValid );
+
+ /** Writes the contained stream position data to the given variables. */
+ void Get( SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
+ sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
+ bool& rbValid ) const;
+
+private:
+ sal_Size mnPos; /// Absolute position of the stream.
+ sal_Size mnNextPos; /// Absolute position of next record.
+ sal_Size mnCurrSize; /// Current calculated size of the record.
+ sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs).
+ sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs).
+ sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs).
+ bool mbValid; /// Read state: false = record overread.
+};
+
+// ============================================================================
+
+/** This class is used to import record oriented streams.
+ @descr An instance is constructed with an SvStream. The SvStream 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 (i.e. 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 with returning false. From now on it is
+ undefined what data the read functions will return. The error state will be
+ reset, if the record is reset (with the method 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 i.e. on import of Escher objects,
+ 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 (i.e. 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 SetDecrypter(),
+ EnableDecryption(), and DisableDecryption() control the usage of the
+ decryption algorithms. SetDecrypter() sets a new decryption algorithm and
+ initially enables it. DisableDecryption() may be used to stop the usage of
+ the decryption temporarily (sometimes record contents are never encrypted,
+ i.e. all BOF records or the stream position in BOUNDSHEET). Decryption will
+ be reenabled automatically, if a new record is started with the function
+ StartNextRecord().
+
+ It is possible to store several stream positions inside a record (including
+ its CONTINUE records). The positions are stored on a stack, which can be
+ controlled with the functions PushPosition(), PopPosition() and
+ RejectPosition(). The stack will be cleared whenever a new record is
+ started with the function StartNextRecord().
+
+ Additionally a single global stream position can be stored which keeps
+ valid during the whole import process (methods StoreGlobalPosition(),
+ SeekGlobalPosition() and DeleteGlobalPosition()). This is the only way to
+ jump back to a previous record (that is a real jump without return).
+*/
+class XclImpStream
+{
+public:
+ /** Detects the BIFF version of the passed workbook stream. */
+ static XclBiff DetectBiffVersion( SvStream& rStrm );
+
+ /** Constructs the Excel record import stream using a TOOLS stream object.
+ @param rInStrm The system input stream. Will be set to its start position.
+ Must exist as long as this object exists.
+ @param bContLookup Automatic CONTINUE lookup on/off. */
+ explicit XclImpStream(
+ SvStream& rInStrm,
+ const XclImpRoot& rRoot,
+ bool bContLookup = true );
+
+ ~XclImpStream();
+
+ /** Returns the filter root data. */
+ inline const XclImpRoot& GetRoot() const { return mrRoot; }
+
+ /** Sets stream pointer to the start of the next record content.
+ @descr 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 record content for the record
+ at the passed absolute stream position.
+ @return false = no record found (end of stream). */
+ bool StartNextRecord( sal_Size nNextRecPos );
+ /** 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 ID for content
+ continuation. This value is reset automatically when a new record is
+ started with StartNextRecord(). */
+ void ResetRecord( bool bContLookup,
+ sal_uInt16 nAltContId = EXC_ID_UNKNOWN );
+
+ /** Enables decryption of record contents for the rest of the stream. */
+ void SetDecrypter( XclImpDecrypterRef xDecrypter );
+ /** Sets decrypter from another stream. */
+ void CopyDecrypterFrom( const XclImpStream& rStrm );
+ /** Returns true, if a valid decrypter is set at the stream. */
+ bool HasValidDecrypter() const;
+ /** Switches usage of current decryption algorithm on/off.
+ @descr Encryption is re-enabled automatically, if a new record is
+ started using the function StartNextRecord(). */
+ void EnableDecryption( bool bEnable = true );
+ /** Switches usage of current decryption algorithm off.
+ @descr This is a record-local setting. The function StartNextRecord()
+ always enables decryption. */
+ inline void DisableDecryption() { EnableDecryption( false ); }
+
+ /** Pushes current position on user position stack.
+ @descr This stack is emptied when starting a new record with
+ StartNextRecord(). The decryption state (enabled/disabled) is not
+ pushed onto the stack. */
+ void PushPosition();
+ /** Seeks to last position from user position stack.
+ @descr This position will be removed from the stack. */
+ void PopPosition();
+
+ /** Stores current position. This position keeps valid in all records. */
+ void StoreGlobalPosition();
+ /** Seeks to the stored global user position. */
+ void SeekGlobalPosition();
+ /** Invalidates global user position. */
+ inline void DeleteGlobalPosition() { mbHasGlobPos = false; }
+
+ /** Returns record reading state: false = record overread. */
+ inline bool IsValid() const { return mbValid; }
+ /** Returns the current record ID. */
+ inline sal_uInt16 GetRecId() const { return mnRecId; }
+ /** Returns the position inside of the whole record content. */
+ sal_Size GetRecPos() const;
+ /** Returns the data size of the whole record without record headers. */
+ sal_Size GetRecSize();
+ /** Returns remaining data size of the whole record without record headers. */
+ sal_Size GetRecLeft();
+ /** Returns the record ID of the following record. */
+ sal_uInt16 GetNextRecId();
+
+ XclImpStream& operator>>( sal_Int8& rnValue );
+ XclImpStream& operator>>( sal_uInt8& rnValue );
+ XclImpStream& operator>>( sal_Int16& rnValue );
+ XclImpStream& operator>>( sal_uInt16& rnValue );
+ XclImpStream& operator>>( sal_Int32& rnValue );
+ XclImpStream& operator>>( sal_uInt32& rnValue );
+ XclImpStream& operator>>( float& rfValue );
+ XclImpStream& operator>>( double& rfValue );
+
+ sal_uInt8 ReaduInt8();
+ sal_Int16 ReadInt16();
+ sal_uInt16 ReaduInt16();
+ sal_Int32 ReadInt32();
+ sal_uInt32 ReaduInt32();
+ double ReadDouble();
+
+ /** Reads nBytes bytes to the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_Size Read( void* pData, sal_Size nBytes );
+ /** Copies nBytes bytes to rOutStrm.
+ @return Count of bytes really written. */
+ sal_Size CopyToStream( SvStream& rOutStrm, sal_Size nBytes );
+
+ /** Copies the entire record to rOutStrm. The current record position keeps unchanged.
+ @return Count of bytes really written. */
+ sal_Size CopyRecordToStream( SvStream& rOutStrm );
+
+ /** Seeks absolute in record content to the specified position.
+ @descr The value 0 means start of record, independent from physical stream position. */
+ void Seek( sal_Size nPos );
+ /** Seeks forward inside the current record. */
+ void Ignore( sal_Size nBytes );
+
+ // *** special string functions *** ---------------------------------------
+
+ // *** read/ignore unicode strings *** ------------------------------------
+ /* - look for CONTINUE records even if CONTINUE handling disabled
+ (only if inside of a CONTINUE record - for TXO import)
+ - no overread assertions (for Applix wrong string length export bug)
+
+ structure of an Excel unicode string:
+ (1) 2 byte character count
+ (2) 1 byte flags (16-bit-characters, rich string, far east string)
+ (3) [2 byte rich string format run count]
+ (4) [4 byte far east data size]
+ (5) character array
+ (6) [4 * (rich string format run count) byte]
+ (7) [(far east data size) byte]
+ header = (1), (2)
+ ext. header = (3), (4)
+ ext. data = (6), (7)
+ */
+
+ /** Reads ext. header, detects 8/16 bit mode, sets all ext. info.
+ @return Total size of ext. data. */
+ sal_Size ReadUniStringExtHeader(
+ bool& rb16Bit, bool& rbRich, bool& rbFareast,
+ sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags );
+ /** Seeks to begin of character array, detects 8/16 bit mode.
+ @return Total size of ext. data. */
+ sal_Size ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags );
+
+ /** Sets a replacement character for NUL characters.
+ @descr NUL characters must be replaced, because Tools strings cannot
+ handle them. The substitution character is reset to '?' automatically,
+ if a new record is started using the function StartNextRecord().
+ @param cNulSubst The character to use for NUL replacement. It is
+ possible to specify NUL here. in this case strings are terminated when
+ the first NUL occurs during string import. */
+ inline void SetNulSubstChar( sal_Unicode cNulSubst = '?' ) { mcNulSubst = cNulSubst; }
+
+ /** Reads nChars characters and returns the string. */
+ String ReadRawUniString( sal_uInt16 nChars, bool b16Bit );
+ /** Reads ext. header, nChar characters, ext. data and returns the string. */
+ String ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags );
+ /** Reads 8 bit flags, ext. header, nChar characters, ext. data and returns the string. */
+ String ReadUniString( sal_uInt16 nChars );
+ /** Reads 16 bit character count, 8 bit flags, ext. header, character array,
+ ext. data and returns the string. */
+ String ReadUniString();
+
+ /** Ignores nChars characters. */
+ void IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit );
+ /** Ignores ext. header, nChar characters, ext. data. */
+ void IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags );
+ /** Ignores 8 bit flags, ext. header, nChar characters, ext. data. */
+ void IgnoreUniString( sal_uInt16 nChars );
+
+ // *** read/ignore 8-bit-strings, store in String *** ---------------------
+
+ /** Reads nChar byte characters and returns the string. */
+ String ReadRawByteString( sal_uInt16 nChars );
+ /** Reads 8/16 bit string length, character array and returns the string. */
+ String ReadByteString( bool b16BitLen );
+
+ // *** SvStream functions *** ---------------------------------------------
+
+ /** Returns the absolute stream position. */
+ inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); }
+ /** Returns the stream size. */
+ inline sal_Size GetSvStreamSize() const { return mnStreamSize; }
+
+private:
+ /** Stores current stream position into rPos. */
+ void StorePosition( XclImpStreamPos& rPos );
+ /** Restores stream position contained in rPos. */
+ void RestorePosition( const XclImpStreamPos& rPos );
+
+ /** Seeks to next raw record header and reads record ID and size.
+ @descr This is a "raw" function, means that stream members are
+ inconsistent after return. Does only change mnRawRecId, mnRawRecSize,
+ and the base stream position, but no other members.
+ @return false = No record header found (end of stream). */
+ bool ReadNextRawRecHeader();
+
+ /** Initializes the decrypter to read a new record. */
+ void SetupDecrypter();
+ /** Initializes all members after base stream has been seeked to new raw record. */
+ void SetupRawRecord();
+ /** Initializes all members after base stream has been seeked to new record. */
+ void SetupRecord();
+
+ /** 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 Copy of mbValid. */
+ 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 rb16Bit.
+ @return Copy of mbValid. */
+ bool JumpToNextStringContinue( bool& rb16Bit );
+
+ /** 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 Copy of mbValid. */
+ bool EnsureRawReadSize( sal_uInt16 nBytes );
+ /** Returns the maximum size of raw data possible to read in one block. */
+ sal_uInt16 GetMaxRawReadSize( sal_Size nBytes ) const;
+
+ /** Reads and decrypts nBytes bytes to the existing(!) buffer pData.
+ @return Count of bytes really read. */
+ sal_uInt16 ReadRawData( void* pData, sal_uInt16 nBytes );
+
+ /** Reads 8 bit/16 bit string length. */
+ inline sal_uInt16 ReadByteStrLen( bool b16BitLen )
+ { return b16BitLen ? ReaduInt16() : ReaduInt8(); }
+
+private:
+ typedef ::std::vector< XclImpStreamPos > XclImpStreamPosStack;
+
+ SvStream& mrStrm; /// Reference to the system input stream.
+ const XclImpRoot& mrRoot; /// Filter root data.
+
+ XclImpDecrypterRef mxDecrypter; /// Provides methods to decrypt data.
+
+ XclImpStreamPos maFirstRec; /// Start position of current record.
+ XclImpStreamPosStack maPosStack; /// Stack for record positions.
+
+ XclImpStreamPos maGlobPos; /// User defined position elsewhere in stream.
+ sal_uInt16 mnGlobRecId; /// Record ID for user defined position.
+ bool mbGlobValidRec; /// Was user position a valid record?
+ bool mbHasGlobPos; /// Is user position defined?
+
+ sal_Size mnStreamSize; /// Size of system stream.
+ sal_Size mnNextRecPos; /// Start of next record header.
+ sal_Size mnCurrRecSize; /// Helper for record position.
+ sal_Size mnComplRecSize; /// Size of complete record data (with CONTINUEs).
+ bool mbHasComplRec; /// true = mnComplRecSize is valid.
+
+ sal_uInt16 mnRecId; /// Current record ID (not the CONTINUE ID).
+ sal_uInt16 mnAltContId; /// Alternative record ID for content continuation.
+
+ sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs).
+ sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs).
+ sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs).
+
+ sal_Unicode mcNulSubst; /// Replacement for NUL characters.
+
+ bool mbCont; /// Automatic CONTINUE lookup on/off.
+ bool mbUseDecr; /// Usage of decryption.
+ bool mbValidRec; /// false = No more records to read.
+ bool mbValid; /// false = Record overread.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xistring.hxx b/sc/source/filter/inc/xistring.hxx
new file mode 100644
index 000000000000..f76e3af4321c
--- /dev/null
+++ b/sc/source/filter/inc/xistring.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTRING_HXX
+#define SC_XISTRING_HXX
+
+#include "xlstring.hxx"
+
+// Byte/Unicode strings =======================================================
+
+class XclImpStream;
+
+/** This class represents an unformatted or formatted string and provides importing from stream. */
+class XclImpString
+{
+public:
+ /** Constructs an empty string. */
+ explicit XclImpString();
+ /** Constructs an unformatted string. */
+ explicit XclImpString( const String& rString );
+
+ ~XclImpString();
+
+ /** Reads a complete string from the passed stream. */
+ void Read( XclImpStream& rStrm, XclStrFlags nFlags = EXC_STR_DEFAULT );
+
+ /** Sets the passed string data. */
+ inline void SetText( const String& rText ) { maString = rText; }
+ /** Sets the passed formatting buffer. */
+ inline void SetFormats( const XclFormatRunVec& rFormats ) { maFormats = rFormats; }
+ /** Insert a formatting run to the format buffer. */
+ inline void AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx ) { AppendFormat( maFormats, nChar, nFontIdx ); }
+ /** Reads and appends the formatting information (run count and runs) from stream. */
+ inline void ReadFormats( XclImpStream& rStrm ) { ReadFormats( rStrm, maFormats ); }
+ /** Reads and appends nRunCount formatting runs from stream. */
+ inline void ReadFormats( XclImpStream& rStrm, sal_uInt16 nRunCount ) { ReadFormats( rStrm, maFormats, nRunCount ); }
+ /** Reads and appends formatting runs from an OBJ or TXO record. */
+ inline void ReadObjFormats( XclImpStream& rStrm, sal_uInt16 nFormatSize ) { ReadObjFormats( rStrm, maFormats, nFormatSize ); }
+
+ /** Returns true, if the string is empty. */
+ inline bool IsEmpty() const { return maString.Len() == 0; }
+ /** Returns the pure text data of the string. */
+ inline const String& GetText() const { return maString; }
+
+ /** Returns true, if the string contains formatting information. */
+ inline bool IsRich() const { return !maFormats.empty(); }
+ /** Returns the formatting run vector. */
+ inline const XclFormatRunVec& GetFormats() const { return maFormats; }
+
+ /** Insert a formatting run to the passed format buffer. */
+ static void AppendFormat( XclFormatRunVec& rFormats, sal_uInt16 nChar, sal_uInt16 nFontIdx );
+ /** Reads and appends the formatting information (run count and runs) from stream. */
+ static void ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats );
+ /** Reads and appends nRunCount formatting runs from stream. */
+ static void ReadFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nRunCount );
+ /** Reads and appends formatting runs from an OBJ or TXO record. */
+ static void ReadObjFormats( XclImpStream& rStrm, XclFormatRunVec& rFormats, sal_uInt16 nFormatSize );
+
+private:
+ String maString; /// The text data of the string.
+ XclFormatRunVec maFormats; /// All formatting runs.
+};
+
+// String iterator ============================================================
+
+/** Iterates over formatted string portions. */
+class XclImpStringIterator
+{
+public:
+ explicit XclImpStringIterator( const XclImpString& rString );
+
+ /** Returns true, if the iterator references a valid text portion. */
+ inline bool Is() const { return mnTextBeg < mrText.Len(); }
+ /** Returns the index of the current text portion. */
+ inline size_t GetPortionIndex() const { return mnPortion; }
+ /** Returns the string of the current text portion. */
+ String GetPortionText() const;
+ /** Returns the font index of the current text portion. */
+ sal_uInt16 GetPortionFont() const;
+
+ /** Moves iterator to next text portion. */
+ XclImpStringIterator& operator++();
+
+private:
+ const String& mrText; /// The processed string.
+ const XclFormatRunVec& mrFormats; /// The vector of formatting runs.
+ size_t mnPortion; /// Current text portion.
+ xub_StrLen mnTextBeg; /// First character of current portion.
+ xub_StrLen mnTextEnd; /// First character of next portion.
+ size_t mnFormatsBeg; /// Formatting run index for current portion.
+ size_t mnFormatsEnd; /// Formatting run index for next portion.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx
new file mode 100644
index 000000000000..5c74d82ee295
--- /dev/null
+++ b/sc/source/filter/inc/xistyle.hxx
@@ -0,0 +1,683 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XISTYLE_HXX
+#define SC_XISTYLE_HXX
+
+#include <list>
+#include <tools/mempool.hxx>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include "rangelst.hxx"
+#include "patattr.hxx"
+#include "xladdress.hxx"
+#include "xlstyle.hxx"
+#include "xiroot.hxx"
+
+class ScDocumentPool;
+struct ScAttrEntry;
+
+/* ============================================================================
+- Buffers for style records (PALETTE, FONT, FORMAT, XF)
+ and a container for XF indexes for every used cell in a sheet.
+============================================================================ */
+
+// PALETTE record - color information =========================================
+
+/** Stores the default colors for the current BIFF version and the contents of
+ a PALETTE record. */
+class XclImpPalette : public XclDefaultPalette
+{
+public:
+ explicit XclImpPalette( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
+ @descr First looks for a color read from file, then looks for a default color.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ ColorData GetColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the color for a (non-zero-based) Excel palette entry.
+ @descr First looks for a color read from file, then looks for a default color.
+ @return The color from current or default palette or COL_AUTO, if nothing else found. */
+ inline Color GetColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetColorData( nXclIndex ) ); }
+ /** Returns the palette colors as UNO sequence. */
+ ::com::sun::star::uno::Sequence< sal_Int32 >
+ CreateColorSequence() const;
+
+ /** Reads a PALETTE record. */
+ void ReadPalette( XclImpStream& rStrm );
+
+private:
+ void ExportPalette();
+ typedef ::std::vector< ColorData > ColorDataVec;
+ ColorDataVec maColorTable; /// Colors read from file.
+ const XclImpRoot& mrRoot;
+};
+
+// FONT record - font information =============================================
+
+/** Stores all data of an Excel font and provides import of FONT records. */
+class XclImpFont : protected XclImpRoot
+{
+public:
+ explicit XclImpFont( const XclImpRoot& rRoot );
+
+ /** Constructs a font from font data.
+ @descr Special handling for font style (bold, italic) in font name,
+ overwrites settings in rFontData. */
+ explicit XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData );
+
+ /** Sets all font attributes to used or unused. */
+ void SetAllUsedFlags( bool bUsed );
+ /** Sets the passed font data and all used flags to 'used'. */
+ void SetFontData( const XclFontData& rFontData, bool bHasCharSet );
+
+ /** Returns read-only access to font data. */
+ inline const XclFontData& GetFontData() const { return maData; }
+ /** Returns true, if the font character set is valid. */
+ inline bool HasCharSet() const { return mbHasCharSet; }
+ /** Returns true, if the font contains superscript or subscript. */
+ inline bool HasEscapement() const { return maData.mnEscapem != EXC_FONTESC_NONE; }
+ /** Returns the text encoding for strings used with this font. */
+ rtl_TextEncoding GetFontEncoding() const;
+
+ /** Returns true, if this font contains characters for Western scripts. */
+ inline bool HasWesternChars() const { return mbHasWstrn; }
+ /** Returns true, if this font contains characters for Asian scripts (CJK). */
+ inline bool HasAsianChars() const { return mbHasAsian; }
+ /** Returns true, if this font contains characters for Complex scripts (CTL). */
+ inline bool HasComplexChars() const { return mbHasCmplx; }
+
+ /** Reads a FONT record for all BIFF versions. */
+ void ReadFont( XclImpStream& rStrm );
+ /** Reads an EFONT record (BIFF2 font color). */
+ void ReadEfont( XclImpStream& rStrm );
+ /** Reads the font block from a CF (conditional format) record. */
+ void ReadCFFontBlock( XclImpStream& rStrm );
+
+ /** Fills all font properties to the item set.
+ @param rItemSet The destination item set.
+ @param eType The type of Which-IDs.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType,
+ bool bSkipPoolDefs = false ) const;
+ /** Writes all font properties to the passed property set.
+ @param pFontColor If set, overrides internal stored font color. */
+ void WriteFontProperties( ScfPropertySet& rPropSet,
+ XclFontPropSetType eType, const Color* pFontColor = 0 ) const;
+
+private:
+ /** Reads and sets height and flags. */
+ void ReadFontData2( XclImpStream& rStrm );
+ /** Reads and sets height, flags, color, boldness, script, family and charset. */
+ void ReadFontData5( XclImpStream& rStrm );
+
+ /** Reads and sets the font color. */
+ void ReadFontColor( XclImpStream& rStrm );
+
+ /** Reads and sets a byte string as font name. */
+ void ReadFontName2( XclImpStream& rStrm );
+ /** Reads and sets a Unicode string as font name. */
+ void ReadFontName8( XclImpStream& rStrm );
+
+ /** Tests whether the font contains CJK or CTL characters.
+ @descr This is only a weak guess using preselected characters. */
+ void GuessScriptType();
+
+private:
+ XclFontData maData; /// All font attributes.
+ bool mbHasCharSet; /// true = Font contains own character set info.
+ bool mbHasWstrn; /// true = Font contains Western script characters.
+ bool mbHasAsian; /// true = Font contains Asian script characters.
+ bool mbHasCmplx; /// true = Font contains Complex script characters.
+ bool mbFontNameUsed; /// true = Font name, family, charset used.
+ bool mbHeightUsed; /// true = Font height used.
+ bool mbColorUsed; /// true = Color used.
+ bool mbWeightUsed; /// true = Weight used.
+ bool mbEscapemUsed; /// true = Escapement type used.
+ bool mbUnderlUsed; /// true = Underline style used.
+ bool mbItalicUsed; /// true = Italic used.
+ bool mbStrikeUsed; /// true = Strikeout used.
+ bool mbOutlineUsed; /// true = Outlined used.
+ bool mbShadowUsed; /// true = Shadowed used.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores the data of all fonts occurred in an Excel file. */
+class XclImpFontBuffer : protected XclImpRoot, private boost::noncopyable
+{
+public:
+ explicit XclImpFontBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Returns the object that stores all contents of a FONT record. */
+ const XclImpFont* GetFont( sal_uInt16 nFontIndex ) const;
+ /** Returns the application font data of this file, needed i.e. for column width. */
+ inline const XclFontData& GetAppFontData() const { return maAppFont; }
+
+ /** Reads a FONT record. */
+ void ReadFont( XclImpStream& rStrm );
+ /** Reads an EFONT record (BIFF2 font color). */
+ void ReadEfont( XclImpStream& rStrm );
+
+ /** Fills all font properties from a FONT record to the item set.
+ @param rItemSet The destination item set.
+ @param eType The type of Which-IDs.
+ @param nFontIdx The Excel index of the font.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType,
+ sal_uInt16 nFontIdx, bool bSkipPoolDefs = false ) const;
+ /** Writes all font properties to the passed property set.
+ @param pFontColor If set, overrides internal stored font color. */
+ void WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ sal_uInt16 nFontIdx, const Color* pFontColor = 0 ) const;
+ /** Writes default font properties for form controls to the passed property set. */
+ void WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const;
+
+private:
+ /** Updates the application default font. */
+ void UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet );
+
+private:
+ boost::ptr_vector< XclImpFont > maFontList; /// List of all FONT records in the Excel file.
+ XclFontData maAppFont; /// Application font (for column width).
+ XclImpFont maFont4; /// Built-in font with index 4.
+ XclImpFont maCtrlFont; /// BIFF5 default form controls font (Helv,8pt,bold).
+};
+
+// FORMAT record - number formats =============================================
+
+/** Stores all user defined number formats occurred in the file. */
+class XclImpNumFmtBuffer : public XclNumFmtBuffer, protected XclImpRoot
+{
+public:
+ explicit XclImpNumFmtBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Reads a FORMAT record. */
+ void ReadFormat( XclImpStream& rStrm );
+ /** Creates the number formats in the Calc document. */
+ void CreateScFormats();
+
+ /** Returns the format key with the passed Excel index or NUMBERFORMAT_ENTRY_NOT_FOUND on error. */
+ sal_uLong GetScFormat( sal_uInt16 nXclNumFmt ) const;
+
+ /** Fills an Excel number format to the passed item set.
+ @param rItemSet The destination item set.
+ @param nXclNumFmt The Excel number format index.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt,
+ bool bSkipPoolDefs = false ) const;
+ /** Fills a Calc number format to the passed item set.
+ @param rItemSet The destination item set.
+ @param nScNumFmt The Calc number formatter index of the format.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillScFmtToItemSet(
+ SfxItemSet& rItemSet, sal_uLong nScNumFmt,
+ bool bSkipPoolDefs = false ) const;
+
+private:
+ typedef ::std::map< sal_uInt16, sal_uLong > XclImpIndexMap;
+
+ XclImpIndexMap maIndexMap; /// Maps Excel format indexes to Calc formats.
+ sal_uInt16 mnNextXclIdx; /// Index counter for BIFF2-BIFF4.
+};
+
+// XF, STYLE record - Cell formatting =========================================
+
+/** Extends the XclCellProt struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellProt : public XclCellProt
+{
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nNumFmt );
+ /** Fills this struct with BIFF3-BIFF8 XF record data. */
+ void FillFromXF3( sal_uInt16 nProt );
+
+ /** Inserts items representing this protection style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellAlign struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellAlign : public XclCellAlign
+{
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3 XF record data. */
+ void FillFromXF3( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF4 XF record data. */
+ void FillFromXF4( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt16 nAlign );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib );
+
+ /** Inserts items representing this alignment style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellBorder struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellBorder : public XclCellBorder
+{
+ bool mbLeftUsed; /// true = Left line style used.
+ bool mbRightUsed; /// true = Right line style used.
+ bool mbTopUsed; /// true = Top line style used.
+ bool mbBottomUsed; /// true = Bottom line style used.
+ bool mbDiagUsed; /// true = Diagonal line style used.
+
+ explicit XclImpCellBorder();
+
+ /** Sets outer line states and diagonal line states to used or unused. */
+ void SetUsedFlags( bool bOuterUsed, bool bDiagUsed );
+
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3/BIFF4 XF record data. */
+ void FillFromXF3( sal_uInt32 nBorder );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 );
+
+ /** Fills this struct with BIFF8 CF (conditional format) record data. */
+ void FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags );
+
+ /** Returns true, if any of the outer border lines is visible. */
+ bool HasAnyOuterBorder() const;
+
+ /** Inserts a box item representing this border style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet,
+ const XclImpPalette& rPalette,
+ bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Extends the XclCellArea struct for import.
+ @descr Provides functions to fill from Excel record data and to fill to item sets. */
+struct XclImpCellArea : public XclCellArea
+{
+ bool mbForeUsed; /// true = Foreground color used.
+ bool mbBackUsed; /// true = Background color used.
+ bool mbPattUsed; /// true = Pattern used.
+
+ explicit XclImpCellArea();
+
+ /** Sets colors and pattern state to used or unused. */
+ void SetUsedFlags( bool bUsed );
+
+ /** Fills this struct with BIFF2 XF record data. */
+ void FillFromXF2( sal_uInt8 nFlags );
+ /** Fills this struct with BIFF3/BIFF4 XF record data. */
+ void FillFromXF3( sal_uInt16 nArea );
+ /** Fills this struct with BIFF5/BIFF7 XF record data. */
+ void FillFromXF5( sal_uInt32 nArea );
+ /** Fills this struct with BIFF8 XF record data. */
+ void FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea );
+
+ /** Fills this struct with BIFF8 CF (conditional format) record data. */
+ void FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags );
+
+ /** Inserts a brush item representing this area style into the item set.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */
+ void FillToItemSet(
+ SfxItemSet& rItemSet,
+ const XclImpPalette& rPalette,
+ bool bSkipPoolDefs = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents an XF record index with additional information. */
+class XclImpXFIndex
+{
+public:
+ inline explicit XclImpXFIndex( sal_uInt16 nXFIndex, bool bBoolCell = false ) :
+ mnXFIndex( nXFIndex ), mbBoolCell( bBoolCell ) {}
+
+ inline sal_uInt16 GetXFIndex() const { return mnXFIndex; }
+ inline bool IsBoolCell() const { return mbBoolCell; }
+
+private:
+ sal_uInt16 mnXFIndex; /// The XF record index.
+ bool mbBoolCell; /// true = A Boolean value cell.
+};
+
+inline bool operator==( const XclImpXFIndex& rLeft, const XclImpXFIndex& rRight )
+{ return (rLeft.GetXFIndex() == rRight.GetXFIndex()) && (rLeft.IsBoolCell() == rRight.IsBoolCell()); }
+
+inline bool operator!=( const XclImpXFIndex& rLeft, const XclImpXFIndex& rRight )
+{ return !(rLeft == rRight); }
+
+// ----------------------------------------------------------------------------
+
+/** Contains all data of a XF record and a Calc item set. */
+class XclImpXF : public XclXFBase, protected XclImpRoot, private boost::noncopyable
+{
+public:
+ explicit XclImpXF( const XclImpRoot& rRoot );
+ virtual ~XclImpXF();
+
+ /** Reads an XF record. */
+ void ReadXF( XclImpStream& rStrm );
+
+ inline sal_uInt8 GetHorAlign() const { return maAlignment.mnHorAlign; }
+ inline sal_uInt8 GetVerAlign() const { return maAlignment.mnVerAlign; }
+ inline sal_uInt16 GetFontIndex() const { return mnXclFont; }
+
+ /** Creates a Calc item set containing an item set with all cell properties.
+ @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items.
+ @return A read-only reference to the item set stored internally. */
+ const ScPatternAttr& CreatePattern( bool bSkipPoolDefs = false );
+
+ void ApplyPatternToAttrList(
+ ::std::list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2,
+ sal_uInt32 nForceScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND);
+
+private:
+ void ReadXF2( XclImpStream& rStrm );
+ void ReadXF3( XclImpStream& rStrm );
+ void ReadXF4( XclImpStream& rStrm );
+ void ReadXF5( XclImpStream& rStrm );
+ void ReadXF8( XclImpStream& rStrm );
+
+ /** Sets all "attribute used" flags according to the passed mask.
+ @descr In cell XFs, a set bit represents "used", in style XFs it is a cleared bit.
+ Therefore mbCellXF must be set correctly before calling this method. */
+ void SetUsedFlags( sal_uInt8 nUsedFlags );
+
+private:
+ typedef ::std::auto_ptr< ScPatternAttr > ScPatternAttrPtr;
+
+ ScPatternAttrPtr mpPattern; /// Calc item set.
+ ScStyleSheet* mpStyleSheet; /// Calc cell style sheet.
+
+ XclImpCellProt maProtection; /// Cell protection flags.
+ XclImpCellAlign maAlignment; /// All alignment attributes.
+ XclImpCellBorder maBorder; /// Border line style.
+ XclImpCellArea maArea; /// Background area style.
+ sal_uInt16 mnXclNumFmt; /// Index to number format.
+ sal_uInt16 mnXclFont; /// Index to font record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all data of a cell style associated with an XF record. */
+class XclImpStyle : protected XclImpRoot
+{
+public:
+ explicit XclImpStyle( const XclImpRoot& rRoot );
+
+ /** Reads a STYLE record. */
+ void ReadStyle( XclImpStream& rStrm );
+
+ inline const String& GetName() const { return maName; }
+ inline sal_uInt16 GetXfId() const { return mnXfId; }
+ inline bool IsBuiltin() const { return mbBuiltin && (mnBuiltinId != EXC_STYLE_USERDEF); }
+ inline sal_uInt8 GetBuiltinId() const { return mnBuiltinId; }
+ inline sal_uInt8 GetLevel() const { return mnLevel; }
+
+ /** Creates a cell style sheet and inserts it into the Calc document.
+ @return The pointer to the cell style sheet, or 0, if there is no style sheet. */
+ ScStyleSheet* CreateStyleSheet();
+ /** Creates the Calc style sheet, if this is a user-defined style. */
+ void CreateUserStyle( const String& rFinalName );
+
+private:
+ String maName; /// Cell style name.
+ sal_uInt16 mnXfId; /// Formatting for this cell style.
+ sal_uInt8 mnBuiltinId; /// Identifier for builtin styles.
+ sal_uInt8 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.
+
+ String maFinalName; /// Final name used in the Calc document.
+ ScStyleSheet* mpStyleSheet; /// Calc cell style sheet.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all XF records occurred in the file.
+ @descr This class is able to read XF records (BIFF2 - BIFF8) and STYLE records (BIFF8). */
+class XclImpXFBuffer : protected XclImpRoot, private boost::noncopyable
+{
+public:
+ explicit XclImpXFBuffer( const XclImpRoot& rRoot );
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Reads an XF record. */
+ void ReadXF( XclImpStream& rStrm );
+ /** Reads a STYLE record. */
+ void ReadStyle( XclImpStream& rStrm );
+
+ /** Returns the object that stores all contents of an XF record. */
+ inline XclImpXF* GetXF( sal_uInt16 nXFIndex )
+ { return (nXFIndex >= maXFList.size()) ? NULL : &maXFList.at(nXFIndex); }
+
+ inline const XclImpXF* GetXF( sal_uInt16 nXFIndex ) const
+ { return (nXFIndex >= maXFList.size()) ? NULL : &maXFList.at(nXFIndex); }
+
+ /** Returns the index to the Excel font used in the specified XF record. */
+ sal_uInt16 GetFontIndex( sal_uInt16 nXFIndex ) const;
+ /** Returns the Excel font used in the specified XF record. */
+ const XclImpFont* GetFont( sal_uInt16 nXFIndex ) const;
+
+ /** Creates all user defined style sheets. */
+ void CreateUserStyles();
+ /** Creates a cell style sheet of the passed XF and inserts it into the Calc document.
+ @return The pointer to the cell style sheet, or 0, if there is no style sheet. */
+ ScStyleSheet* CreateStyleSheet( sal_uInt16 nXFIndex );
+
+private:
+ typedef boost::ptr_vector< XclImpStyle > XclImpStyleList;
+ typedef ::std::map< sal_uInt16, XclImpStyle* > XclImpStyleMap;
+
+ boost::ptr_vector< XclImpXF > maXFList; /// List of contents of all XF record.
+ XclImpStyleList maBuiltinStyles; /// List of built-in cell styles.
+ XclImpStyleList maUserStyles; /// List of user defined cell styles.
+ XclImpStyleMap maStylesByXf; /// Maps XF records to cell styles.
+};
+
+// Buffer for XF indexes in cells =============================================
+
+/** Contains an (encoded) XF index for a range of rows in a single column. */
+class XclImpXFRange
+{
+ DECL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange )
+
+public:
+ SCROW mnScRow1; /// The first row of an equal-formatted range.
+ SCROW mnScRow2; /// The last row of an equal-formatted range.
+ XclImpXFIndex maXFIndex; /// Extended XF index.
+
+ inline explicit XclImpXFRange( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+ inline explicit XclImpXFRange( SCROW nFirstScRow, SCROW nLastScRow, const XclImpXFIndex& rXFIndex );
+
+ /** Returns true, if nScRow is contained in own row range. */
+ inline bool Contains( SCROW nScRow ) const;
+
+ /** Returns true, if the range has been expanded. */
+ bool Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+ /** Returns true, if the range has been expanded. */
+ bool Expand( const XclImpXFRange& rNextRange );
+};
+
+inline XclImpXFRange::XclImpXFRange( SCROW nScRow, const XclImpXFIndex& rXFIndex ) :
+ mnScRow1( nScRow ),
+ mnScRow2( nScRow ),
+ maXFIndex( rXFIndex )
+{
+}
+
+inline XclImpXFRange::XclImpXFRange( SCROW nFirstScRow, SCROW nLastScRow, const XclImpXFIndex& rXFIndex ) :
+ mnScRow1( nFirstScRow ),
+ mnScRow2( nLastScRow ),
+ maXFIndex( rXFIndex )
+{
+}
+
+inline bool XclImpXFRange::Contains( SCROW nScRow ) const
+{
+ return (mnScRow1 <= nScRow) && (nScRow <= mnScRow2);
+}
+
+// ----------------------------------------------------------------------------
+
+/** Contains the XF indexes for every used cell in a column. */
+class XclImpXFRangeColumn : private boost::noncopyable
+{
+public:
+ typedef ::boost::ptr_vector<XclImpXFRange> IndexList;
+
+ inline explicit XclImpXFRangeColumn() {}
+
+ IndexList::iterator begin() { return maIndexList.begin(); }
+ IndexList::iterator end() { return maIndexList.end(); }
+
+ /** Inserts a single row range into the list. */
+ void SetDefaultXF( const XclImpXFIndex& rXFIndex );
+
+ /** Inserts a new (encoded) XF index (first try to expand the last range). */
+ void SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex );
+
+private:
+ /** Finds the previous and next row range from row position nScRow.
+ @descr If an XF still exists, it is contained in rpPrevRange. */
+ void Find(
+ XclImpXFRange*& rpPrevRange,
+ XclImpXFRange*& rpNextRange,
+ sal_uLong& rnNextIndex,
+ SCROW nScRow );
+
+ /** Tries to concatenate a range with its predecessor.
+ @descr The ranges must have the same XF index and must not have a gap.
+ The resulting range has the index nIndex-1. */
+ void TryConcatPrev( sal_uLong nIndex );
+
+ /** Insert a range into the list at the specified index. */
+ void Insert(XclImpXFRange* pXFRange, sal_uLong nIndex);
+
+private:
+ IndexList maIndexList; /// The list of XF index range.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains the XF indexes for every used cell in a single sheet. */
+class XclImpXFRangeBuffer : protected XclImpRoot, private boost::noncopyable
+{
+public:
+ explicit XclImpXFRangeBuffer( const XclImpRoot& rRoot );
+ virtual ~XclImpXFRangeBuffer();
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void Initialize();
+
+ /** Inserts a new XF index. */
+ void SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for blank cells. */
+ void SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for boolean cells. */
+ void SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for all cells in a row. */
+ void SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex );
+ /** Inserts a new XF index for all cells in a column. */
+ void SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex );
+
+ /** Inserts a range of hyperlink cells. */
+ void SetHyperlink( const XclRange& rXclRange, const String& rUrl );
+
+ /** Inserts the first cell of a merged cell range. */
+ void SetMerge( SCCOL nScCol, SCROW nScRow );
+ /** Inserts a complete merged cell range. */
+ void SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 );
+
+ /** Applies styles and cell merging to the current sheet in the document. */
+ void Finalize();
+
+private:
+ /** Insertion mode of an XF index. */
+ enum XclImpXFInsertMode
+ {
+ xlXFModeCell, /// Filled cell.
+ xlXFModeBoolCell, /// Cell with a single Boolean value.
+ xlXFModeBlank, /// Blank cell.
+ xlXFModeRow /// Row default XF.
+ };
+
+private:
+ /** Inserts a new XF index for the specified cell type. */
+ void SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode );
+
+ /** Copies border of the last cell of the range to the first cell to keep it visible
+ when the range is merged.
+ @param nLine
+ BOX_LINE_RIGHT = copy most-right border of top row;
+ BOX_LINE_BOTTOM = copy most-bottom border of first column. */
+ void SetBorderLine( const ScRange& rRange, SCTAB nScTab, sal_uInt16 nLine );
+
+private:
+ typedef boost::shared_ptr< XclImpXFRangeColumn > XclImpXFRangeColumnRef;
+ typedef ::std::vector< XclImpXFRangeColumnRef > XclImpXFRangeColumnVec;
+ typedef ::std::pair< XclRange, String > XclImpHyperlinkRange;
+ typedef ::std::list< XclImpHyperlinkRange > XclImpHyperlinkList;
+
+ XclImpXFRangeColumnVec maColumns; /// Array of column XF index buffers.
+ XclImpHyperlinkList maHyperlinks; /// Maps URLs to hyperlink cells.
+ ScRangeList maMergeList; /// List of merged cell ranges.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xiview.hxx b/sc/source/filter/inc/xiview.hxx
new file mode 100644
index 000000000000..29c3f98bbb04
--- /dev/null
+++ b/sc/source/filter/inc/xiview.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XIVIEW_HXX
+#define SC_XIVIEW_HXX
+
+#include "xlview.hxx"
+#include "xiroot.hxx"
+
+// Document view settings =====================================================
+
+/** Contains document view settings (WINDOW1 record). */
+class XclImpDocViewSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpDocViewSettings( const XclImpRoot& rRoot );
+
+ /** Reads a WINDOW1 record. */
+ void ReadWindow1( XclImpStream& rStrm );
+
+ /** Returns the Calc index of the displayed sheet. */
+ SCTAB GetDisplScTab() const;
+
+ /** Sets the view settings at the document. */
+ void Finalize();
+
+private:
+ XclDocViewData maData; /// Document view settings data.
+};
+
+// Sheet view settings ========================================================
+
+/** Contains all view settings for a single sheet.
+
+ Usage:
+ 1) When import filter starts reading a worksheet substream, inizialize an
+ instance of this class with the Initialize() function. This will set
+ all view options to Excel default values.
+ 2) Read all view related records using the Read*() functions.
+ 3) When import filter ends reading a worksheet substream, call Finalize()
+ to set all view settings to the current sheet of the Calc document.
+ */
+class XclImpTabViewSettings : protected XclImpRoot
+{
+public:
+ explicit XclImpTabViewSettings( const XclImpRoot& rRoot );
+
+ /** Initializes the object to be used for a new sheet. */
+ void Initialize();
+
+ /** Reads a WINDOW2 record. */
+ void ReadWindow2( XclImpStream& rStrm, bool bChart );
+ /** Reads an SCL record. */
+ void ReadScl( XclImpStream& rStrm );
+ /** Reads a PANE record. */
+ void ReadPane( XclImpStream& rStrm );
+ /** Reads a SELECTION record. */
+ void ReadSelection( XclImpStream& rStrm );
+ /** Reads a SHEETEXT record (Tab Color). */
+ void ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal );
+ /** Sets the view settings at the current sheet or the extended sheet options object. */
+ void Finalize();
+
+private:
+ XclTabViewData maData; /// Sheet view settings data.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xladdress.hxx b/sc/source/filter/inc/xladdress.hxx
new file mode 100644
index 000000000000..9722b3dbe1ff
--- /dev/null
+++ b/sc/source/filter/inc/xladdress.hxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLADDRESS_HXX
+#define SC_XLADDRESS_HXX
+
+#include <vector>
+#include "address.hxx"
+
+class ScRangeList;
+class XclImpStream;
+class XclExpStream;
+
+// ============================================================================
+
+/** A 2D cell address struct with Excel column and row indexes. */
+struct XclAddress
+{
+ sal_uInt16 mnCol;
+ sal_uInt32 mnRow;
+
+ inline explicit XclAddress( ScAddress::Uninitialized ) {}
+ inline explicit XclAddress() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit XclAddress( sal_uInt16 nCol, sal_uInt32 nRow ) : mnCol( nCol ), mnRow( nRow ) {}
+
+ inline void Set( sal_uInt16 nCol, sal_uInt32 nRow ) { mnCol = nCol; mnRow = nRow; }
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+};
+
+inline bool operator==( const XclAddress& rL, const XclAddress& rR )
+{
+ return (rL.mnCol == rR.mnCol) && (rL.mnRow == rR.mnRow);
+}
+
+inline bool operator<( const XclAddress& rL, const XclAddress& rR )
+{
+ return (rL.mnCol < rR.mnCol) || ((rL.mnCol == rR.mnCol) && (rL.mnRow < rR.mnRow));
+}
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclAddress& rXclPos )
+{
+ rXclPos.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclAddress& rXclPos )
+{
+ rXclPos.Write( rStrm );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell range address struct with Excel column and row indexes. */
+struct XclRange
+{
+ XclAddress maFirst;
+ XclAddress maLast;
+
+ inline explicit XclRange( ScAddress::Uninitialized e ) : maFirst( e ), maLast( e ) {}
+ inline explicit XclRange() {}
+ inline explicit XclRange( const XclAddress& rPos ) : maFirst( rPos ), maLast( rPos ) {}
+ inline explicit XclRange( const XclAddress& rFirst, const XclAddress& rLast ) : maFirst( rFirst ), maLast( rLast ) {}
+ inline explicit XclRange( sal_uInt16 nCol1, sal_uInt32 nRow1, sal_uInt16 nCol2, sal_uInt32 nRow2 ) :
+ maFirst( nCol1, nRow1 ), maLast( nCol2, nRow2 ) {}
+
+ inline void Set( const XclAddress& rFirst, const XclAddress& rLast )
+ { maFirst = rFirst; maLast = rLast; }
+ inline void Set( sal_uInt16 nCol1, sal_uInt32 nRow1, sal_uInt16 nCol2, sal_uInt32 nRow2 )
+ { maFirst.Set( nCol1, nRow1 ); maLast.Set( nCol2, nRow2 ); }
+
+ inline sal_uInt16 GetColCount() const { return maLast.mnCol - maFirst.mnCol + 1; }
+ inline sal_uInt32 GetRowCount() const { return maLast.mnRow - maFirst.mnRow + 1; }
+ bool Contains( const XclAddress& rPos ) const;
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+};
+
+inline bool operator==( const XclRange& rL, const XclRange& rR )
+{
+ return (rL.maFirst == rR.maFirst) && (rL.maLast == rR.maLast);
+}
+
+inline bool operator<( const XclRange& rL, const XclRange& rR )
+{
+ return (rL.maFirst < rR.maFirst) || ((rL.maFirst == rR.maFirst) && (rL.maLast < rR.maLast));
+}
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclRange& rXclRange )
+{
+ rXclRange.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclRange& rXclRange )
+{
+ rXclRange.Write( rStrm );
+ return rStrm;
+}
+
+// ----------------------------------------------------------------------------
+
+/** A 2D cell range address list with Excel column and row indexes. */
+class XclRangeList : public ::std::vector< XclRange >
+{
+public:
+ inline explicit XclRangeList() {}
+
+ XclRange GetEnclosingRange() const;
+
+ void Read( XclImpStream& rStrm, bool bCol16Bit = true );
+ void Write( XclExpStream& rStrm, bool bCol16Bit = true ) const;
+ void WriteSubList( XclExpStream& rStrm,
+ size_t nBegin, size_t nCount, bool bCol16Bit = true ) const;
+};
+
+inline XclImpStream& operator>>( XclImpStream& rStrm, XclRangeList& rXclRanges )
+{
+ rXclRanges.Read( rStrm );
+ return rStrm;
+}
+
+inline XclExpStream& operator<<( XclExpStream& rStrm, const XclRangeList& rXclRanges )
+{
+ rXclRanges.Write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+class XclTracer;
+
+/** Base class for import/export address converters. */
+class XclAddressConverterBase
+{
+public:
+ explicit XclAddressConverterBase( XclTracer& rTracer, const ScAddress& rMaxPos );
+ virtual ~XclAddressConverterBase();
+
+ /** Returns whether the "some columns have been cut" warning box should be shown. */
+ inline bool IsColTruncated() const { return mbColTrunc; }
+ /** Returns whether the "some rows have been cut" warning box should be shown. */
+ inline bool IsRowTruncated() const { return mbRowTrunc; }
+ /** Returns whether the "some sheets have been cut" warning box should be shown. */
+ inline bool IsTabTruncated() const { return mbTabTrunc; }
+
+ // ------------------------------------------------------------------------
+
+ /** Checks if the passed sheet index is valid.
+ @param nScTab The sheet index to check.
+ @param bWarn true = Sets the internal flag that produces a warning box
+ after loading/saving the file, if the sheet index is not valid.
+ @return true = Sheet index in nScTab is valid. */
+ bool CheckScTab( SCTAB nScTab, bool bWarn );
+
+ // ------------------------------------------------------------------------
+protected:
+ XclTracer& mrTracer; /// Tracer for invalid addresses.
+ ScAddress maMaxPos; /// Default maximum position.
+ sal_uInt16 mnMaxCol; /// Maximum column index, as 16-bit value.
+ sal_uInt32 mnMaxRow; /// Maximum row index.
+ bool mbColTrunc; /// Flag for "columns truncated" warning box.
+ bool mbRowTrunc; /// Flag for "rows truncated" warning box.
+ bool mbTabTrunc; /// Flag for "tables truncated" warning box.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx
new file mode 100644
index 000000000000..51fe688a857e
--- /dev/null
+++ b/sc/source/filter/inc/xlchart.hxx
@@ -0,0 +1,1525 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCHART_HXX
+#define SC_XLCHART_HXX
+
+// disable/enable support for varied point colors property
+#define EXC_CHART2_VARYCOLORSBY_PROP 0
+// disable/enable restriction to hair lines in 3D bar charts (#i83151#)
+#define EXC_CHART2_3DBAR_HAIRLINES_ONLY 1
+
+#include <map>
+#include <tools/gen.hxx>
+#include "fapihelper.hxx"
+#include <boost/shared_ptr.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace chart { class XChartDocument; }
+ namespace chart2 { class XChartDocument; }
+ namespace drawing { class XShape; }
+} } }
+
+class XclRoot;
+
+// Property names =============================================================
+
+// service names
+#define SERVICE_DRAWING_BITMAPTABLE CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" )
+#define SERVICE_DRAWING_DASHTABLE CREATE_OUSTRING( "com.sun.star.drawing.DashTable" )
+#define SERVICE_DRAWING_GRADIENTTABLE CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" )
+#define SERVICE_DRAWING_HATCHTABLE CREATE_OUSTRING( "com.sun.star.drawing.HatchTable" )
+
+#define SERVICE_CHART2_AXIS CREATE_OUSTRING( "com.sun.star.chart2.Axis" )
+#define SERVICE_CHART2_CARTESIANCOORDSYS2D CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem2d" )
+#define SERVICE_CHART2_CARTESIANCOORDSYS3D CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem3d" )
+#define SERVICE_CHART2_DATAPROVIDER CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" )
+#define SERVICE_CHART2_DATASERIES CREATE_OUSTRING( "com.sun.star.chart2.DataSeries" )
+#define SERVICE_CHART2_DIAGRAM CREATE_OUSTRING( "com.sun.star.chart2.Diagram" )
+#define SERVICE_CHART2_ERRORBAR CREATE_OUSTRING( "com.sun.star.chart2.ErrorBar" )
+#define SERVICE_CHART2_EXPREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.ExponentialRegressionCurve" )
+#define SERVICE_CHART2_FORMATTEDSTRING CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" )
+#define SERVICE_CHART2_LABELEDDATASEQ CREATE_OUSTRING( "com.sun.star.chart2.data.LabeledDataSequence" )
+#define SERVICE_CHART2_LEGEND CREATE_OUSTRING( "com.sun.star.chart2.Legend" )
+#define SERVICE_CHART2_LINEARREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.LinearRegressionCurve" )
+#define SERVICE_CHART2_LINEARSCALING CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" )
+#define SERVICE_CHART2_LOGREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicRegressionCurve" )
+#define SERVICE_CHART2_LOGSCALING CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicScaling" )
+#define SERVICE_CHART2_POLARCOORDSYS2D CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem2d" )
+#define SERVICE_CHART2_POLARCOORDSYS3D CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem3d" )
+#define SERVICE_CHART2_POTREGCURVE CREATE_OUSTRING( "com.sun.star.chart2.PotentialRegressionCurve" )
+#define SERVICE_CHART2_TITLE CREATE_OUSTRING( "com.sun.star.chart2.Title" )
+
+// property names
+#define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" )
+#define EXC_CHPROP_ANCHORPOSITION CREATE_OUSTRING( "AnchorPosition" )
+#define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" )
+#define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" )
+#define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" )
+#define EXC_CHPROP_BLACKDAY CREATE_OUSTRING( "BlackDay" )
+#define EXC_CHPROP_COLOR CREATE_OUSTRING( "Color" )
+#define EXC_CHPROP_CONNECTBARS CREATE_OUSTRING( "ConnectBars" )
+#define EXC_CHPROP_CROSSOVERPOSITION CREATE_OUSTRING( "CrossoverPosition" )
+#define EXC_CHPROP_CROSSOVERVALUE CREATE_OUSTRING( "CrossoverValue" )
+#define EXC_CHPROP_CURVESTYLE CREATE_OUSTRING( "CurveStyle" )
+#define EXC_CHPROP_D3DCAMERAGEOMETRY CREATE_OUSTRING( "D3DCameraGeometry" )
+#define EXC_CHPROP_D3DSCENEAMBIENTCOLOR CREATE_OUSTRING( "D3DSceneAmbientColor" )
+#define EXC_CHPROP_D3DSCENELIGHTON1 CREATE_OUSTRING( "D3DSceneLightOn1" )
+#define EXC_CHPROP_D3DSCENELIGHTCOLOR2 CREATE_OUSTRING( "D3DSceneLightColor2" )
+#define EXC_CHPROP_D3DSCENELIGHTDIR2 CREATE_OUSTRING( "D3DSceneLightDirection2" )
+#define EXC_CHPROP_D3DSCENELIGHTON2 CREATE_OUSTRING( "D3DSceneLightOn2" )
+#define EXC_CHPROP_D3DSCENEPERSPECTIVE CREATE_OUSTRING( "D3DScenePerspective" )
+#define EXC_CHPROP_D3DSCENESHADEMODE CREATE_OUSTRING( "D3DSceneShadeMode" )
+#define EXC_CHPROP_D3DTRANSFORMMATRIX CREATE_OUSTRING( "D3DTransformMatrix" )
+#define EXC_CHPROP_DISPLAYLABELS CREATE_OUSTRING( "DisplayLabels" )
+#define EXC_CHPROP_ERRORBARSTYLE CREATE_OUSTRING( "ErrorBarStyle" )
+#define EXC_CHPROP_ERRORBARX CREATE_OUSTRING( "ErrorBarX" )
+#define EXC_CHPROP_ERRORBARY CREATE_OUSTRING( "ErrorBarY" )
+#define EXC_CHPROP_EXPANSION CREATE_OUSTRING( "Expansion" )
+#define EXC_CHPROP_EXPTIMEINCREMENT CREATE_OUSTRING( "ExplicitTimeIncrement" )
+#define EXC_CHPROP_FILLBITMAPMODE CREATE_OUSTRING( "FillBitmapMode" )
+#define EXC_CHPROP_FILLSTYLE CREATE_OUSTRING( "FillStyle" )
+#define EXC_CHPROP_GAPWIDTHSEQ CREATE_OUSTRING( "GapwidthSequence" )
+#define EXC_CHPROP_GEOMETRY3D CREATE_OUSTRING( "Geometry3D" )
+#define EXC_CHPROP_HASMAINTITLE CREATE_OUSTRING( "HasMainTitle" )
+#define EXC_CHPROP_INCLUDEHIDDENCELLS CREATE_OUSTRING( "IncludeHiddenCells" )
+#define EXC_CHPROP_JAPANESE CREATE_OUSTRING( "Japanese" )
+#define EXC_CHPROP_LABEL CREATE_OUSTRING( "Label" )
+#define EXC_CHPROP_LABELPLACEMENT CREATE_OUSTRING( "LabelPlacement" )
+#define EXC_CHPROP_LABELPOSITION CREATE_OUSTRING( "LabelPosition" )
+#define EXC_CHPROP_LABELSEPARATOR CREATE_OUSTRING( "LabelSeparator" )
+#define EXC_CHPROP_MAJORTICKS CREATE_OUSTRING( "MajorTickmarks" )
+#define EXC_CHPROP_MARKPOSITION CREATE_OUSTRING( "MarkPosition" )
+#define EXC_CHPROP_MINORTICKS CREATE_OUSTRING( "MinorTickmarks" )
+#define EXC_CHPROP_MISSINGVALUETREATMENT CREATE_OUSTRING( "MissingValueTreatment" )
+#define EXC_CHPROP_NEGATIVEERROR CREATE_OUSTRING( "NegativeError" )
+#define EXC_CHPROP_NUMBERFORMAT CREATE_OUSTRING( "NumberFormat" )
+#define EXC_CHPROP_OFFSET CREATE_OUSTRING( "Offset" )
+#define EXC_CHPROP_OVERLAPSEQ CREATE_OUSTRING( "OverlapSequence" )
+#define EXC_CHPROP_PERCENTAGENUMFMT CREATE_OUSTRING( "PercentageNumberFormat" )
+#define EXC_CHPROP_PERCENTDIAGONAL CREATE_OUSTRING( "PercentDiagonal" )
+#define EXC_CHPROP_PERSPECTIVE CREATE_OUSTRING( "Perspective" )
+#define EXC_CHPROP_POSITIVEERROR CREATE_OUSTRING( "PositiveError" )
+#define EXC_CHPROP_RELATIVEPOSITION CREATE_OUSTRING( "RelativePosition" )
+#define EXC_CHPROP_RELATIVESIZE CREATE_OUSTRING( "RelativeSize" )
+#define EXC_CHPROP_RIGHTANGLEDAXES CREATE_OUSTRING( "RightAngledAxes" )
+#define EXC_CHPROP_ROLE CREATE_OUSTRING( "Role" )
+#define EXC_CHPROP_ROTATIONHORIZONTAL CREATE_OUSTRING( "RotationHorizontal" )
+#define EXC_CHPROP_ROTATIONVERTICAL CREATE_OUSTRING( "RotationVertical" )
+#define EXC_CHPROP_SHOW CREATE_OUSTRING( "Show" )
+#define EXC_CHPROP_SHOWCORRELATION CREATE_OUSTRING( "ShowCorrelationCoefficient" )
+#define EXC_CHPROP_SHOWEQUATION CREATE_OUSTRING( "ShowEquation" )
+#define EXC_CHPROP_SHOWFIRST CREATE_OUSTRING( "ShowFirst" )
+#define EXC_CHPROP_SHOWHIGHLOW CREATE_OUSTRING( "ShowHighLow" )
+#define EXC_CHPROP_SHOWNEGATIVEERROR CREATE_OUSTRING( "ShowNegativeError" )
+#define EXC_CHPROP_SHOWPOSITIVEERROR CREATE_OUSTRING( "ShowPositiveError" )
+#define EXC_CHPROP_STACKCHARACTERS CREATE_OUSTRING( "StackCharacters" )
+#define EXC_CHPROP_STACKINGDIR CREATE_OUSTRING( "StackingDirection" )
+#define EXC_CHPROP_STARTINGANGLE CREATE_OUSTRING( "StartingAngle" )
+#define EXC_CHPROP_SWAPXANDYAXIS CREATE_OUSTRING( "SwapXAndYAxis" )
+#define EXC_CHPROP_SYMBOL CREATE_OUSTRING( "Symbol" )
+#define EXC_CHPROP_TEXTBREAK CREATE_OUSTRING( "TextBreak" )
+#define EXC_CHPROP_TEXTOVERLAP CREATE_OUSTRING( "TextOverlap" )
+#define EXC_CHPROP_TEXTROTATION CREATE_OUSTRING( "TextRotation" )
+#define EXC_CHPROP_USERINGS CREATE_OUSTRING( "UseRings" )
+#define EXC_CHPROP_VARYCOLORSBY CREATE_OUSTRING( "VaryColorsByPoint" )
+#define EXC_CHPROP_WEIGHT CREATE_OUSTRING( "Weight" )
+#define EXC_CHPROP_WHITEDAY CREATE_OUSTRING( "WhiteDay" )
+
+// data series roles
+#define EXC_CHPROP_ROLE_CATEG CREATE_OUSTRING( "categories" )
+#define EXC_CHPROP_ROLE_ERRORBARS_NEGX CREATE_OUSTRING( "error-bars-x-negative" )
+#define EXC_CHPROP_ROLE_ERRORBARS_NEGY CREATE_OUSTRING( "error-bars-y-negative" )
+#define EXC_CHPROP_ROLE_ERRORBARS_POSX CREATE_OUSTRING( "error-bars-x-positive" )
+#define EXC_CHPROP_ROLE_ERRORBARS_POSY CREATE_OUSTRING( "error-bars-y-positive" )
+#define EXC_CHPROP_ROLE_LABEL CREATE_OUSTRING( "label" )
+#define EXC_CHPROP_ROLE_SIZES CREATE_OUSTRING( "sizes" )
+#define EXC_CHPROP_ROLE_XVALUES CREATE_OUSTRING( "values-x" )
+#define EXC_CHPROP_ROLE_YVALUES CREATE_OUSTRING( "values-y" )
+#define EXC_CHPROP_ROLE_OPENVALUES CREATE_OUSTRING( "values-first" )
+#define EXC_CHPROP_ROLE_CLOSEVALUES CREATE_OUSTRING( "values-last" )
+#define EXC_CHPROP_ROLE_LOWVALUES CREATE_OUSTRING( "values-min" )
+#define EXC_CHPROP_ROLE_HIGHVALUES CREATE_OUSTRING( "values-max" )
+#define EXC_CHPROP_ROLE_SIZEVALUES CREATE_OUSTRING( "values-size" )
+
+// Constants and Enumerations =================================================
+
+const sal_Size EXC_CHART_PROGRESS_SIZE = 10;
+const sal_uInt16 EXC_CHART_AUTOROTATION = 0xFFFF; /// Automatic rotation, e.g. axis labels (internal use only).
+
+const sal_Int32 EXC_CHART_AXIS_NONE = -1; /// For internal use only.
+const sal_Int32 EXC_CHART_AXIS_X = 0; /// API X axis index.
+const sal_Int32 EXC_CHART_AXIS_Y = 1; /// API Y axis index.
+const sal_Int32 EXC_CHART_AXIS_Z = 2; /// API Z axis index.
+const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use only.
+const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index.
+const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index.
+
+const sal_Int32 EXC_CHART_TOTALUNITS = 4000; /// Most chart objects are positioned in 1/4000 of chart area.
+const sal_Int32 EXC_CHART_PLOTAREAUNITS = 1000; /// For objects that are positioned in 1/1000 of plot area.
+
+// (0x0850) CHFRINFO ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRINFO = 0x0850;
+
+const sal_uInt8 EXC_CHFRINFO_EXCEL2000 = 9;
+const sal_uInt8 EXC_CHFRINFO_EXCELXP2003 = 10;
+const sal_uInt8 EXC_CHFRINFO_EXCEL2007 = 11;
+
+// (0x0852, 0x0853) CHFRBLOCKBEGIN, CHFRBLOCKEND ------------------------------
+
+const sal_uInt16 EXC_ID_CHFRBLOCKBEGIN = 0x0852;
+const sal_uInt16 EXC_ID_CHFRBLOCKEND = 0x0853;
+
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_AXESSET = 0;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_TEXT = 2;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_AXIS = 4;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_TYPEGROUP = 5;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DATATABLE = 6;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_FRAME = 7;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_LEGEND = 9;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_LEGENDEX = 10;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_SERIES = 12;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_CHART = 13;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DATAFORMAT = 14;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_DROPBAR = 15;
+const sal_uInt16 EXC_CHFRBLOCK_TYPE_UNKNOWN = 0xFFFF; /// For internal use only.
+
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_TITLE = 0;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_DEFTEXT = 2;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_AXISTITLE = 4;
+const sal_uInt16 EXC_CHFRBLOCK_TEXT_DATALABEL = 5;
+
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_STANDARD = 0;
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_PLOTFRAME = 1;
+const sal_uInt16 EXC_CHFRBLOCK_FRAME_BACKGROUND = 2;
+
+// (0x086B) CHFRLABELPROPS ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRLABELPROPS = 0x086B;
+
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWSERIES = 0x0001;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWCATEG = 0x0002;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWVALUE = 0x0004;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWPERCENT = 0x0008;
+const sal_uInt16 EXC_CHFRLABELPROPS_SHOWBUBBLE = 0x0010;
+
+// (0x1001) CHUNITS -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHUNITS = 0x1001;
+
+const sal_uInt16 EXC_CHUNITS_TWIPS = 0;
+const sal_uInt16 EXC_CHUNITS_PIXELS = 1;
+
+// (0x1002) CHCHART -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHART = 0x1002;
+
+// (0x1003) CHSERIES ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERIES = 0x1003;
+
+const sal_uInt16 EXC_CHSERIES_DATE = 0;
+const sal_uInt16 EXC_CHSERIES_NUMERIC = 1;
+const sal_uInt16 EXC_CHSERIES_SEQUENCE = 2;
+const sal_uInt16 EXC_CHSERIES_TEXT = 3;
+
+const sal_uInt16 EXC_CHSERIES_MAXSERIES = 255; /// Maximum valid series index.
+const sal_uInt16 EXC_CHSERIES_INVALID = 0xFFFF; /// Invalid series index (for internal use).
+
+// (0x1006) CHDATAFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDATAFORMAT = 0x1006;
+
+const sal_uInt16 EXC_CHDATAFORMAT_MAXPOINTCOUNT = 32000; /// Maximum number of data points.
+const sal_uInt16 EXC_CHDATAFORMAT_DEFAULT = 0xFFFD; /// As format index: global default for an axes set.
+const sal_uInt16 EXC_CHDATAFORMAT_UNKNOWN = 0xFFFE; /// As point index: unknown format, don't use.
+const sal_uInt16 EXC_CHDATAFORMAT_ALLPOINTS = 0xFFFF; /// As point index: default for a series.
+
+const sal_uInt16 EXC_CHDATAFORMAT_OLDCOLORS = 0x0001;
+
+// (0x1007) CHLINEFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLINEFORMAT = 0x1007;
+
+const sal_uInt16 EXC_CHLINEFORMAT_SOLID = 0;
+const sal_uInt16 EXC_CHLINEFORMAT_DASH = 1;
+const sal_uInt16 EXC_CHLINEFORMAT_DOT = 2;
+const sal_uInt16 EXC_CHLINEFORMAT_DASHDOT = 3;
+const sal_uInt16 EXC_CHLINEFORMAT_DASHDOTDOT = 4;
+const sal_uInt16 EXC_CHLINEFORMAT_NONE = 5;
+const sal_uInt16 EXC_CHLINEFORMAT_DARKTRANS = 6;
+const sal_uInt16 EXC_CHLINEFORMAT_MEDTRANS = 7;
+const sal_uInt16 EXC_CHLINEFORMAT_LIGHTTRANS = 8;
+
+const sal_Int16 EXC_CHLINEFORMAT_HAIR = -1;
+const sal_Int16 EXC_CHLINEFORMAT_SINGLE = 0;
+const sal_Int16 EXC_CHLINEFORMAT_DOUBLE = 1;
+const sal_Int16 EXC_CHLINEFORMAT_TRIPLE = 2;
+
+const sal_uInt16 EXC_CHLINEFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHLINEFORMAT_SHOWAXIS = 0x0004;
+
+// (0x1009) CHMARKERFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHMARKERFORMAT = 0x1009;
+
+const sal_uInt16 EXC_CHMARKERFORMAT_NOSYMBOL = 0;
+const sal_uInt16 EXC_CHMARKERFORMAT_SQUARE = 1;
+const sal_uInt16 EXC_CHMARKERFORMAT_DIAMOND = 2;
+const sal_uInt16 EXC_CHMARKERFORMAT_TRIANGLE = 3;
+const sal_uInt16 EXC_CHMARKERFORMAT_CROSS = 4;
+const sal_uInt16 EXC_CHMARKERFORMAT_STAR = 5;
+const sal_uInt16 EXC_CHMARKERFORMAT_DOWJ = 6;
+const sal_uInt16 EXC_CHMARKERFORMAT_STDDEV = 7;
+const sal_uInt16 EXC_CHMARKERFORMAT_CIRCLE = 8;
+const sal_uInt16 EXC_CHMARKERFORMAT_PLUS = 9;
+
+const sal_uInt32 EXC_CHMARKERFORMAT_HAIRSIZE = 60; /// Automatic symbol size for hair lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_SINGLESIZE = 100; /// Automatic symbol size for single lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_DOUBLESIZE = 140; /// Automatic symbol size for double lines.
+const sal_uInt32 EXC_CHMARKERFORMAT_TRIPLESIZE = 180; /// Automatic symbol size for triple lines.
+
+const sal_uInt16 EXC_CHMARKERFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHMARKERFORMAT_NOFILL = 0x0010;
+const sal_uInt16 EXC_CHMARKERFORMAT_NOLINE = 0x0020;
+
+// (0x100A) CHAREAFORMAT ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAREAFORMAT = 0x100A;
+
+const sal_uInt16 EXC_CHAREAFORMAT_AUTO = 0x0001;
+const sal_uInt16 EXC_CHAREAFORMAT_INVERTNEG = 0x0002;
+
+// (0x100B) CHPIEFORMAT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIEFORMAT = 0x100B;
+
+// (0x100C) CHATTACHEDLABEL ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHATTACHEDLABEL = 0x100C;
+
+const sal_uInt16 EXC_CHATTLABEL_SHOWVALUE = 0x0001;
+const sal_uInt16 EXC_CHATTLABEL_SHOWPERCENT = 0x0002;
+const sal_uInt16 EXC_CHATTLABEL_SHOWCATEGPERC = 0x0004;
+const sal_uInt16 EXC_CHATTLABEL_SMOOTHED = 0x0008; /// Smoothed line.
+const sal_uInt16 EXC_CHATTLABEL_SHOWCATEG = 0x0010;
+const sal_uInt16 EXC_CHATTLABEL_SHOWBUBBLE = 0x0020;
+
+// (0x100D) CHSTRING ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSTRING = 0x100D;
+
+// (0x1014) CHTYPEGROUP -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTYPEGROUP = 0x1014;
+
+const sal_uInt16 EXC_CHTYPEGROUP_VARIEDCOLORS = 0x0001; /// Varied colors for points.
+
+// (0x1015) CHLEGEND ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLEGEND = 0x1015;
+
+const sal_uInt8 EXC_CHLEGEND_BOTTOM = 0;
+const sal_uInt8 EXC_CHLEGEND_CORNER = 1;
+const sal_uInt8 EXC_CHLEGEND_TOP = 2;
+const sal_uInt8 EXC_CHLEGEND_RIGHT = 3;
+const sal_uInt8 EXC_CHLEGEND_LEFT = 4;
+const sal_uInt8 EXC_CHLEGEND_NOTDOCKED = 7;
+
+const sal_uInt8 EXC_CHLEGEND_CLOSE = 0;
+const sal_uInt8 EXC_CHLEGEND_MEDIUM = 1;
+const sal_uInt8 EXC_CHLEGEND_OPEN = 2;
+
+const sal_uInt16 EXC_CHLEGEND_DOCKED = 0x0001;
+const sal_uInt16 EXC_CHLEGEND_AUTOSERIES = 0x0002;
+const sal_uInt16 EXC_CHLEGEND_AUTOPOSX = 0x0004;
+const sal_uInt16 EXC_CHLEGEND_AUTOPOSY = 0x0008;
+const sal_uInt16 EXC_CHLEGEND_STACKED = 0x0010;
+const sal_uInt16 EXC_CHLEGEND_DATATABLE = 0x0020;
+
+// (0x1017) CHBAR, CHCOLUMN ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHBAR = 0x1017;
+
+const sal_uInt16 EXC_CHBAR_HORIZONTAL = 0x0001;
+const sal_uInt16 EXC_CHBAR_STACKED = 0x0002;
+const sal_uInt16 EXC_CHBAR_PERCENT = 0x0004;
+const sal_uInt16 EXC_CHBAR_SHADOW = 0x0008;
+
+// (0x1018, 0x101A) CHLINE, CHAREA --------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLINE = 0x1018;
+const sal_uInt16 EXC_ID_CHAREA = 0x101A;
+
+const sal_uInt16 EXC_CHLINE_STACKED = 0x0001;
+const sal_uInt16 EXC_CHLINE_PERCENT = 0x0002;
+const sal_uInt16 EXC_CHLINE_SHADOW = 0x0004;
+
+// (0x1019) CHPIE -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIE = 0x1019;
+
+const sal_uInt16 EXC_CHPIE_SHADOW = 0x0001;
+const sal_uInt16 EXC_CHPIE_LINES = 0x0002;
+
+// (0x101B) CHSCATTER ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSCATTER = 0x101B;
+
+const sal_uInt16 EXC_CHSCATTER_AREA = 1; /// Bubble area refers to value.
+const sal_uInt16 EXC_CHSCATTER_WIDTH = 2; /// Bubble width refers to value.
+
+const sal_uInt16 EXC_CHSCATTER_BUBBLES = 0x0001;
+const sal_uInt16 EXC_CHSCATTER_SHOWNEG = 0x0002;
+const sal_uInt16 EXC_CHSCATTER_SHADOW = 0x0004;
+
+// (0x001C) CHCHARTLINE -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHARTLINE = 0x101C;
+
+const sal_uInt16 EXC_CHCHARTLINE_DROP = 0; /// Drop lines.
+const sal_uInt16 EXC_CHCHARTLINE_HILO = 1; /// Hi-lo lines.
+const sal_uInt16 EXC_CHCHARTLINE_CONNECT = 2; /// Connector lines in stacked bar charts.
+
+// (0x101D) CHAXIS ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXIS = 0x101D;
+
+const sal_uInt16 EXC_CHAXIS_X = 0;
+const sal_uInt16 EXC_CHAXIS_Y = 1;
+const sal_uInt16 EXC_CHAXIS_Z = 2;
+const sal_uInt16 EXC_CHAXIS_NONE = 0xFFFF; /// For internal use only.
+
+// (0x101E) CHTICK ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTICK = 0x101E;
+
+const sal_uInt8 EXC_CHTICK_INSIDE = 0x01;
+const sal_uInt8 EXC_CHTICK_OUTSIDE = 0x02;
+
+const sal_uInt8 EXC_CHTICK_NOLABEL = 0;
+const sal_uInt8 EXC_CHTICK_LOW = 1; /// Below diagram/right of diagram.
+const sal_uInt8 EXC_CHTICK_HIGH = 2; /// Above diagram/left of diagram.
+const sal_uInt8 EXC_CHTICK_NEXT = 3; /// Next to axis.
+
+const sal_uInt8 EXC_CHTICK_TRANSPARENT = 1;
+const sal_uInt8 EXC_CHTICK_OPAQUE = 2;
+
+const sal_uInt16 EXC_CHTICK_AUTOCOLOR = 0x0001;
+const sal_uInt16 EXC_CHTICK_AUTOFILL = 0x0002;
+const sal_uInt16 EXC_CHTICK_AUTOROT = 0x0020;
+
+// (0x101F) CHVALUERANGE ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHVALUERANGE = 0x101F;
+
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMIN = 0x0001;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMAX = 0x0002;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMAJOR = 0x0004;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOMINOR = 0x0008;
+const sal_uInt16 EXC_CHVALUERANGE_AUTOCROSS = 0x0010;
+const sal_uInt16 EXC_CHVALUERANGE_LOGSCALE = 0x0020;
+const sal_uInt16 EXC_CHVALUERANGE_REVERSE = 0x0040; /// Axis direction reversed.
+const sal_uInt16 EXC_CHVALUERANGE_MAXCROSS = 0x0080; /// Other axis crosses at own maximum.
+const sal_uInt16 EXC_CHVALUERANGE_BIT8 = 0x0100; /// This bit is always set in BIFF5+.
+
+// (0x1020) CHLABELRANGE -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHLABELRANGE = 0x1020;
+
+const sal_uInt16 EXC_CHLABELRANGE_BETWEEN = 0x0001; /// Axis between categories.
+const sal_uInt16 EXC_CHLABELRANGE_MAXCROSS = 0x0002; /// Other axis crosses at own maximum.
+const sal_uInt16 EXC_CHLABELRANGE_REVERSE = 0x0004; /// Axis direction reversed.
+
+// (0x1021) CHAXISLINE --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXISLINE = 0x1021;
+
+const sal_uInt16 EXC_CHAXISLINE_AXISLINE = 0; /// Axis line itself.
+const sal_uInt16 EXC_CHAXISLINE_MAJORGRID = 1; /// Major grid line.
+const sal_uInt16 EXC_CHAXISLINE_MINORGRID = 2; /// Minor grid line.
+const sal_uInt16 EXC_CHAXISLINE_WALLS = 3; /// Walls (X, Z axis), floor (Y axis).
+
+// (0x1024) CHDEFAULTTEXT -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDEFAULTTEXT = 0x1024;
+
+const sal_uInt16 EXC_CHDEFTEXT_TEXTLABEL = 0; /// Default for text data labels (not used?).
+const sal_uInt16 EXC_CHDEFTEXT_NUMLABEL = 1; /// Default for numeric data labels (not used?).
+const sal_uInt16 EXC_CHDEFTEXT_GLOBAL = 2; /// Default text for all chart objects.
+const sal_uInt16 EXC_CHDEFTEXT_AXESSET = 3; /// Default text for axes and data points (BIFF8 only).
+const sal_uInt16 EXC_CHDEFTEXT_NONE = 0xFFFF; /// No default text available.
+
+// (0x1025) CHTEXT ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHTEXT = 0x1025;
+
+const sal_uInt8 EXC_CHTEXT_ALIGN_TOPLEFT = 1; /// Horizontal: left, vertical: top.
+const sal_uInt8 EXC_CHTEXT_ALIGN_CENTER = 2;
+const sal_uInt8 EXC_CHTEXT_ALIGN_BOTTOMRIGHT = 3; /// Horizontal: right, vertical: bottom.
+const sal_uInt8 EXC_CHTEXT_ALIGN_JUSTIFY = 4;
+const sal_uInt8 EXC_CHTEXT_ALIGN_DISTRIBUTE = 5;
+
+const sal_uInt16 EXC_CHTEXT_TRANSPARENT = 1;
+const sal_uInt16 EXC_CHTEXT_OPAQUE = 2;
+
+const sal_uInt16 EXC_CHTEXT_AUTOCOLOR = 0x0001; /// Automatic text color.
+const sal_uInt16 EXC_CHTEXT_SHOWSYMBOL = 0x0002; /// Legend symbol for data point caption.
+const sal_uInt16 EXC_CHTEXT_SHOWVALUE = 0x0004; /// Data point caption is the value.
+const sal_uInt16 EXC_CHTEXT_VERTICAL = 0x0008;
+const sal_uInt16 EXC_CHTEXT_AUTOTEXT = 0x0010; /// Label text generated from chart data.
+const sal_uInt16 EXC_CHTEXT_AUTOGEN = 0x0020; /// Text object is inserted automatically.
+const sal_uInt16 EXC_CHTEXT_DELETED = 0x0040; /// Text object is removed.
+const sal_uInt16 EXC_CHTEXT_AUTOFILL = 0x0080; /// Automatic text background mode (transparent/opaque).
+const sal_uInt16 EXC_CHTEXT_SHOWCATEGPERC = 0x0800; /// Data point caption is category and percent.
+const sal_uInt16 EXC_CHTEXT_SHOWPERCENT = 0x1000; /// Data point caption as percent.
+const sal_uInt16 EXC_CHTEXT_SHOWBUBBLE = 0x2000; /// Show bubble size.
+const sal_uInt16 EXC_CHTEXT_SHOWCATEG = 0x4000; /// Data point caption is category name.
+
+const sal_uInt16 EXC_CHTEXT_POS_DEFAULT = 0;
+const sal_uInt16 EXC_CHTEXT_POS_OUTSIDE = 1;
+const sal_uInt16 EXC_CHTEXT_POS_INSIDE = 2;
+const sal_uInt16 EXC_CHTEXT_POS_CENTER = 3;
+const sal_uInt16 EXC_CHTEXT_POS_AXIS = 4;
+const sal_uInt16 EXC_CHTEXT_POS_ABOVE = 5;
+const sal_uInt16 EXC_CHTEXT_POS_BELOW = 6;
+const sal_uInt16 EXC_CHTEXT_POS_LEFT = 7;
+const sal_uInt16 EXC_CHTEXT_POS_RIGHT = 8;
+const sal_uInt16 EXC_CHTEXT_POS_AUTO = 9;
+const sal_uInt16 EXC_CHTEXT_POS_MOVED = 10;
+
+// (0x1026) CHFONT ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFONT = 0x1026;
+
+// (0x1027) CHOBJECTLINK ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHOBJECTLINK = 0x1027;
+
+// link targets
+const sal_uInt16 EXC_CHOBJLINK_NONE = 0; /// No link target.
+const sal_uInt16 EXC_CHOBJLINK_TITLE = 1; /// Chart title.
+const sal_uInt16 EXC_CHOBJLINK_YAXIS = 2; /// Value axis (Y axis).
+const sal_uInt16 EXC_CHOBJLINK_XAXIS = 3; /// Category axis (X axis).
+const sal_uInt16 EXC_CHOBJLINK_DATA = 4; /// Data series/point.
+const sal_uInt16 EXC_CHOBJLINK_ZAXIS = 7; /// Series axis (Z axis).
+const sal_uInt16 EXC_CHOBJLINK_AXISUNIT = 12; /// Unit name for axis labels.
+
+// (0x1032) CHFRAME -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRAME = 0x1032;
+
+const sal_uInt16 EXC_CHFRAME_STANDARD = 0;
+const sal_uInt16 EXC_CHFRAME_SHADOW = 4;
+
+const sal_uInt16 EXC_CHFRAME_AUTOSIZE = 0x0001;
+const sal_uInt16 EXC_CHFRAME_AUTOPOS = 0x0002;
+
+// (0x1033, 0x1034) CHBEGIN, CHEND --------------------------------------------
+
+const sal_uInt16 EXC_ID_CHBEGIN = 0x1033;
+const sal_uInt16 EXC_ID_CHEND = 0x1034;
+
+// (0x1035) CHPLOTFRAME -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPLOTFRAME = 0x1035;
+
+// (0x103A) CHCHART3D ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHCHART3D = 0x103A;
+
+const sal_uInt16 EXC_CHCHART3D_REAL3D = 0x0001; /// true = real 3d perspective.
+const sal_uInt16 EXC_CHCHART3D_CLUSTER = 0x0002; /// false = Z axis, true = clustered/stacked.
+const sal_uInt16 EXC_CHCHART3D_AUTOHEIGHT = 0x0004; /// true = automatic height to width ratio.
+const sal_uInt16 EXC_CHCHART3D_HASWALLS = 0x0010; /// true = 3d chart has walls/floor.
+const sal_uInt16 EXC_CHCHART3D_2DWALLS = 0x0020; /// true = 2d wall/gridlines, no floor.
+
+// (0x103C) CHPICFORMAT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPICFORMAT = 0x103C;
+
+const sal_uInt16 EXC_CHPICFORMAT_NONE = 0; /// For internal use only.
+const sal_uInt16 EXC_CHPICFORMAT_STRETCH = 1; /// Bitmap stretched to area.
+const sal_uInt16 EXC_CHPICFORMAT_STACK = 2; /// Bitmap stacked.
+const sal_uInt16 EXC_CHPICFORMAT_SCALE = 3; /// Bitmap scaled to axis scale.
+
+const sal_uInt16 EXC_CHPICFORMAT_WMF = 2;
+const sal_uInt16 EXC_CHPICFORMAT_BMP = 9;
+const sal_uInt16 EXC_CHPICFORMAT_DEFAULT = 19;
+
+const sal_uInt16 EXC_CHPICFORMAT_WINDOWS = 0x0001;
+const sal_uInt16 EXC_CHPICFORMAT_MACOS = 0x0002;
+const sal_uInt16 EXC_CHPICFORMAT_FORMATONLY = 0x0100;
+const sal_uInt16 EXC_CHPICFORMAT_DEFAULTFLAGS = 0x0E00; /// Default flags for export.
+
+// (0x103D) CHDROPBAR ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDROPBAR = 0x103D;
+
+const sal_uInt16 EXC_CHDROPBAR_UP = 0;
+const sal_uInt16 EXC_CHDROPBAR_DOWN = 1;
+const sal_uInt16 EXC_CHDROPBAR_NONE = 0xFFFF;
+
+// (0x103E, 0x1040) CHRADARLINE, CHRADARAREA ----------------------------------
+
+const sal_uInt16 EXC_ID_CHRADARLINE = 0x103E;
+const sal_uInt16 EXC_ID_CHRADARAREA = 0x1040;
+
+const sal_uInt16 EXC_CHRADAR_AXISLABELS = 0x0001;
+const sal_uInt16 EXC_CHRADAR_SHADOW = 0x0002;
+
+// (0x103F) CHSURFACE ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSURFACE = 0x103F;
+
+const sal_uInt16 EXC_CHSURFACE_FILLED = 0x0001;
+const sal_uInt16 EXC_CHSURFACE_SHADING = 0x0002;
+
+// (0x1041) CHAXESSET ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHAXESSET = 0x1041;
+
+const sal_uInt16 EXC_CHAXESSET_PRIMARY = 0;
+const sal_uInt16 EXC_CHAXESSET_SECONDARY = 1;
+const sal_uInt16 EXC_CHAXESSET_NONE = 0xFFFF; /// For internal use.
+
+// (0x1044) CHPROPERTIES ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPROPERTIES = 0x1044;
+
+const sal_uInt16 EXC_CHPROPS_MANSERIES = 0x0001; /// Manual series allocation.
+const sal_uInt16 EXC_CHPROPS_SHOWVISIBLEONLY = 0x0002; /// Show visible cells only.
+const sal_uInt16 EXC_CHPROPS_NORESIZE = 0x0004; /// Do not resize chart with window.
+const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Manual plot area mode.
+const sal_uInt16 EXC_CHPROPS_USEMANPLOTAREA = 0x0010; /// Manual plot area layout in CHFRAMEPOS record.
+
+const sal_uInt8 EXC_CHPROPS_EMPTY_SKIP = 0; /// Skip empty values.
+const sal_uInt8 EXC_CHPROPS_EMPTY_ZERO = 1; /// Plot empty values as zero.
+const sal_uInt8 EXC_CHPROPS_EMPTY_INTERPOLATE = 2; /// Interpolate empty values.
+
+// (0x1045) CHSERGROUP --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERGROUP = 0x1045;
+
+const sal_uInt16 EXC_CHSERGROUP_NONE = 0xFFFF; /// For internal use: no chart type group.
+
+// (0x1048, 0x0858) CHPIVOTREF ------------------------------------------------
+
+const sal_uInt16 EXC_ID5_CHPIVOTREF = 0x1048;
+const sal_uInt16 EXC_ID8_CHPIVOTREF = 0x0858;
+
+// (0x104A) CHSERPARENT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERPARENT = 0x104A;
+
+// (0x104B) CHSERTRENDLINE ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERTRENDLINE = 0x104B;
+
+const sal_uInt8 EXC_CHSERTREND_POLYNOMIAL = 0; /// If order is 1, trend line is linear.
+const sal_uInt8 EXC_CHSERTREND_EXPONENTIAL = 1;
+const sal_uInt8 EXC_CHSERTREND_LOGARITHMIC = 2;
+const sal_uInt8 EXC_CHSERTREND_POWER = 3;
+const sal_uInt8 EXC_CHSERTREND_MOVING_AVG = 4;
+
+// (0x104E) CHFORMAT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFORMAT = 0x104E;
+
+// (0x104F) CHFRAMEPOS --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFRAMEPOS = 0x104F;
+
+const sal_uInt16 EXC_CHFRAMEPOS_POINTS = 0;
+const sal_uInt16 EXC_CHFRAMEPOS_ABSSIZE_POINTS = 1;
+const sal_uInt16 EXC_CHFRAMEPOS_PARENT = 2;
+const sal_uInt16 EXC_CHFRAMEPOS_DEFOFFSET_PLOT = 3;
+const sal_uInt16 EXC_CHFRAMEPOS_CHARTSIZE = 5;
+
+// (0x1050) CHFORMATRUNS ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHFORMATRUNS = 0x1050;
+
+// (0x1051) CHSOURCELINK ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSOURCELINK = 0x1051;
+
+const sal_uInt8 EXC_CHSRCLINK_TITLE = 0;
+const sal_uInt8 EXC_CHSRCLINK_VALUES = 1;
+const sal_uInt8 EXC_CHSRCLINK_CATEGORY = 2;
+const sal_uInt8 EXC_CHSRCLINK_BUBBLES = 3;
+
+const sal_uInt8 EXC_CHSRCLINK_DEFAULT = 0;
+const sal_uInt8 EXC_CHSRCLINK_DIRECTLY = 1;
+const sal_uInt8 EXC_CHSRCLINK_WORKSHEET = 2;
+
+const sal_uInt16 EXC_CHSRCLINK_NUMFMT = 0x0001;
+
+// (0x105B) CHSERERRORBAR -----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERERRORBAR = 0x105B;
+
+const sal_uInt8 EXC_CHSERERR_NONE = 0; /// For internal use only.
+const sal_uInt8 EXC_CHSERERR_XPLUS = 1;
+const sal_uInt8 EXC_CHSERERR_XMINUS = 2;
+const sal_uInt8 EXC_CHSERERR_YPLUS = 3;
+const sal_uInt8 EXC_CHSERERR_YMINUS = 4;
+
+const sal_uInt8 EXC_CHSERERR_PERCENT = 1;
+const sal_uInt8 EXC_CHSERERR_FIXED = 2;
+const sal_uInt8 EXC_CHSERERR_STDDEV = 3;
+const sal_uInt8 EXC_CHSERERR_CUSTOM = 4;
+const sal_uInt8 EXC_CHSERERR_STDERR = 5;
+
+const sal_uInt8 EXC_CHSERERR_END_BLANK = 0; /// Line end: blank.
+const sal_uInt8 EXC_CHSERERR_END_TSHAPE = 1; /// Line end: t-shape.
+
+// (0x105D) CHSERIESFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHSERIESFORMAT = 0x105D;
+
+const sal_uInt16 EXC_CHSERIESFORMAT_SMOOTHED = 0x0001;
+const sal_uInt16 EXC_CHSERIESFORMAT_BUBBLE3D = 0x0002;
+const sal_uInt16 EXC_CHSERIESFORMAT_SHADOW = 0x0004;
+
+// (0x105F) CH3DDATAFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CH3DDATAFORMAT = 0x105F;
+
+const sal_uInt8 EXC_CH3DDATAFORMAT_RECT = 0; /// Rectangular base.
+const sal_uInt8 EXC_CH3DDATAFORMAT_CIRC = 1; /// Circular base.
+
+const sal_uInt8 EXC_CH3DDATAFORMAT_STRAIGHT = 0; /// Straight to top.
+const sal_uInt8 EXC_CH3DDATAFORMAT_SHARP = 1; /// Sharp top.
+const sal_uInt8 EXC_CH3DDATAFORMAT_TRUNC = 2; /// Shart top, truncated.
+
+// (0x1061) CHPIEEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHPIEEXT = 0x1061;
+
+// (0x1062) CHDATERANGE -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHDATERANGE = 0x1062;
+
+const sal_uInt16 EXC_CHDATERANGE_AUTOMIN = 0x0001;
+const sal_uInt16 EXC_CHDATERANGE_AUTOMAX = 0x0002;
+const sal_uInt16 EXC_CHDATERANGE_AUTOMAJOR = 0x0004;
+const sal_uInt16 EXC_CHDATERANGE_AUTOMINOR = 0x0008;
+const sal_uInt16 EXC_CHDATERANGE_DATEAXIS = 0x0010;
+const sal_uInt16 EXC_CHDATERANGE_AUTOBASE = 0x0020;
+const sal_uInt16 EXC_CHDATERANGE_AUTOCROSS = 0x0040; /// Other axis crosses at own maximum.
+const sal_uInt16 EXC_CHDATERANGE_AUTODATE = 0x0080; /// Recognize date/text automatically.
+
+const sal_uInt16 EXC_CHDATERANGE_DAYS = 0;
+const sal_uInt16 EXC_CHDATERANGE_MONTHS = 1;
+const sal_uInt16 EXC_CHDATERANGE_YEARS = 2;
+
+// (0x1066) CHESCHERFORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHESCHERFORMAT = 0x1066;
+
+// Other record IDs -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_CHWRAPPEDRECORD = 0x0851;
+const sal_uInt16 EXC_ID_CHUNITPROPERTIES = 0x0857;
+const sal_uInt16 EXC_ID_CHUSEDAXESSETS = 0x1046;
+const sal_uInt16 EXC_ID_CHLABELRANGE2 = 0x1062;
+const sal_uInt16 EXC_ID_CHPLOTGROWTH = 0x1064;
+const sal_uInt16 EXC_ID_CHSERINDEX = 0x1065;
+const sal_uInt16 EXC_ID_CHUNKNOWN = 0xFFFF;
+
+// ============================================================================
+// Structs and classes
+// ============================================================================
+
+// Common =====================================================================
+
+struct XclChRectangle
+{
+ sal_Int32 mnX; /// X position of the object in 1/4000 of chart width.
+ sal_Int32 mnY; /// Y position of the object in 1/4000 of chart height.
+ sal_Int32 mnWidth; /// Width of the object in 1/4000 of chart width.
+ sal_Int32 mnHeight; /// Height of the object in 1/4000 of chart height.
+
+ explicit XclChRectangle();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Specifies the position of a data series or data point. */
+struct XclChDataPointPos
+{
+ sal_uInt16 mnSeriesIdx; /// Series index of series or a data point.
+ sal_uInt16 mnPointIdx; /// Index of a data point inside a series.
+
+ explicit XclChDataPointPos(
+ sal_uInt16 nSeriesIdx = EXC_CHSERIES_INVALID,
+ sal_uInt16 nPointIdx = EXC_CHDATAFORMAT_ALLPOINTS );
+};
+
+bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR );
+
+// ----------------------------------------------------------------------------
+
+/** Contains the type and context of a block of future records which are
+ guarded by CHFRBLOCKBEGIN and CHFRBLOCKEND records. */
+struct XclChFrBlock
+{
+ sal_uInt16 mnType; /// Type of the future record block.
+ sal_uInt16 mnContext; /// Context dependent on type.
+ sal_uInt16 mnValue1; /// Optional primary value for current context.
+ sal_uInt16 mnValue2; /// Optional secondary value for current context.
+
+ explicit XclChFrBlock( sal_uInt16 nType );
+};
+
+// Frame formatting ===========================================================
+
+struct XclChFramePos
+{
+ XclChRectangle maRect; /// Object dependent position data.
+ sal_uInt16 mnTLMode; /// Top-left position mode.
+ sal_uInt16 mnBRMode; /// Bottom-right position mode.
+
+ explicit XclChFramePos();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChLineFormat
+{
+ Color maColor; /// Line color.
+ sal_uInt16 mnPattern; /// Line pattern (solid, dashed, ...).
+ sal_Int16 mnWeight; /// Line weight (hairline, single, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLineFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAreaFormat
+{
+ Color maPattColor; /// Pattern color.
+ Color maBackColor; /// Pattern background color.
+ sal_uInt16 mnPattern; /// Fill pattern.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChAreaFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxItemSet;
+class EscherPropertyContainer;
+
+struct XclChEscherFormat
+{
+ typedef boost::shared_ptr< SfxItemSet > SfxItemSetRef;
+ typedef boost::shared_ptr< EscherPropertyContainer > EscherPropSetRef;
+
+ SfxItemSetRef mxItemSet; /// Item set for Escher properties import.
+ EscherPropSetRef mxEscherSet; /// Container for Escher properties export.
+
+ explicit XclChEscherFormat();
+ ~XclChEscherFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChPicFormat
+{
+ sal_uInt16 mnBmpMode; /// Bitmap mode, e.g. stretched, stacked.
+ sal_uInt16 mnFormat; /// Image data format (WMF, BMP).
+ sal_uInt16 mnFlags; /// Additional flags.
+ double mfScale; /// Picture scaling (units).
+
+ explicit XclChPicFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChFrame
+{
+ sal_uInt16 mnFormat; /// Format type of the frame.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChFrame();
+};
+
+// Source links ===============================================================
+
+struct XclChSourceLink
+{
+ sal_uInt8 mnDestType; /// Type of the destination (title, values, ...).
+ sal_uInt8 mnLinkType; /// Link type (directly, linked to worksheet, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnNumFmtIdx; /// Number format index.
+
+ explicit XclChSourceLink();
+};
+
+// Text =======================================================================
+
+struct XclChObjectLink
+{
+ XclChDataPointPos maPointPos; /// Position of the data point.
+ sal_uInt16 mnTarget; /// Target of the link.
+
+ explicit XclChObjectLink();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChFrLabelProps
+{
+ String maSeparator; /// Separator between label values.
+ sal_uInt16 mnFlags; /// Flags indicating which values to be displayed.
+
+ explicit XclChFrLabelProps();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChText
+{
+ XclChRectangle maRect; /// Position of the text object.
+ Color maTextColor; /// Text color.
+ sal_uInt8 mnHAlign; /// Horizontal alignment.
+ sal_uInt8 mnVAlign; /// Vertical alignment.
+ sal_uInt16 mnBackMode; /// Background mode: transparent, opaque.
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnFlags2; /// Text object placement and text direction (BIFF8+).
+ sal_uInt16 mnRotation; /// Text object rotation (BIFF8+).
+
+ explicit XclChText();
+};
+
+// Data series ================================================================
+
+struct XclChMarkerFormat
+{
+ Color maLineColor; /// Border line color.
+ Color maFillColor; /// Fill color.
+ sal_uInt32 mnMarkerSize; /// Size of a marker
+ sal_uInt16 mnMarkerType; /// Marker type (none, diamond, ...).
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChMarkerFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclCh3dDataFormat
+{
+ sal_uInt8 mnBase; /// Base form.
+ sal_uInt8 mnTop; /// Top egde mode.
+
+ explicit XclCh3dDataFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChDataFormat
+{
+ XclChDataPointPos maPointPos; /// Position of the data point or series.
+ sal_uInt16 mnFormatIdx; /// Formatting index for automatic colors.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChDataFormat();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSerTrendLine
+{
+ double mfIntercept; /// Forced intercept.
+ double mfForecastFor; /// Counter to forecast forward.
+ double mfForecastBack; /// Counter to forecast backward.
+ sal_uInt8 mnLineType; /// Type of the trend line.
+ sal_uInt8 mnOrder; /// Polynomial order or moving average counter.
+ sal_uInt8 mnShowEquation; /// 1 = Show equation.
+ sal_uInt8 mnShowRSquared; /// 1 = Show R-squared.
+
+ explicit XclChSerTrendLine();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSerErrorBar
+{
+ double mfValue; /// Fixed value for several source types.
+ sal_uInt16 mnValueCount; /// Number of custom error values.
+ sal_uInt8 mnBarType; /// Type of the error bar (X/Y).
+ sal_uInt8 mnSourceType; /// Type of source values.
+ sal_uInt8 mnLineEnd; /// Type of the line ends.
+
+ explicit XclChSerErrorBar();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChSeries
+{
+ sal_uInt16 mnCategType; /// Data type for category entries.
+ sal_uInt16 mnValueType; /// Data type for value entries.
+ sal_uInt16 mnBubbleType; /// Data type for bubble entries.
+ sal_uInt16 mnCategCount; /// Number of category entries.
+ sal_uInt16 mnValueCount; /// Number of value entries.
+ sal_uInt16 mnBubbleCount; /// Number of bubble entries.
+
+ explicit XclChSeries();
+};
+
+// Chart type groups ==========================================================
+
+struct XclChType
+{
+ sal_Int16 mnOverlap; /// Bar overlap width (CHBAR).
+ sal_Int16 mnGap; /// Gap between bars (CHBAR).
+ sal_uInt16 mnRotation; /// Rotation angle of first pie (CHPIE).
+ sal_uInt16 mnPieHole; /// Hole size in donut chart (CHPIE).
+ sal_uInt16 mnBubbleSize; /// Bubble size in bubble chart (CHSCATTER).
+ sal_uInt16 mnBubbleType; /// Bubble type in bubble chart (CHSCATTER).
+ sal_uInt16 mnFlags; /// Additional flags (all chart types).
+
+ explicit XclChType();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChChart3d
+{
+ sal_uInt16 mnRotation; /// Rotation (0...359deg).
+ sal_Int16 mnElevation; /// Elevation (-90...+90deg).
+ sal_uInt16 mnEyeDist; /// Eye distance to chart (0...100).
+ sal_uInt16 mnRelHeight; /// Height relative to width.
+ sal_uInt16 mnRelDepth; /// Depth relative to width.
+ sal_uInt16 mnDepthGap; /// Space between series.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChChart3d();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChLegend
+{
+ XclChRectangle maRect; /// Position of the legend.
+ sal_uInt8 mnDockMode; /// Docking mode.
+ sal_uInt8 mnSpacing; /// Spacing between elements.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLegend();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChTypeGroup
+{
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnGroupIdx; /// Chart type group index.
+
+ explicit XclChTypeGroup();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChProperties
+{
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt8 mnEmptyMode; /// Plotting mode for empty cells.
+
+ explicit XclChProperties();
+};
+
+// Axes =======================================================================
+
+struct XclChLabelRange
+{
+ sal_uInt16 mnCross; /// Crossing position of other axis.
+ sal_uInt16 mnLabelFreq; /// Frequency of labels.
+ sal_uInt16 mnTickFreq; /// Frequency of ticks.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChLabelRange();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChDateRange
+{
+ sal_uInt16 mnMinDate; /// Minimum value on axis.
+ sal_uInt16 mnMaxDate; /// Maximum value on axis.
+ sal_uInt16 mnMajorStep; /// Distance for major grid lines.
+ sal_uInt16 mnMajorUnit; /// Time unit for major step.
+ sal_uInt16 mnMinorStep; /// Distance for minor grid lines.
+ sal_uInt16 mnMinorUnit; /// Time unit for minor step.
+ sal_uInt16 mnBaseUnit; /// Time unit for axis values.
+ sal_uInt16 mnCross; /// Crossing position of other axis.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChDateRange();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChValueRange
+{
+ double mfMin; /// Minimum value on axis.
+ double mfMax; /// Maximum value on axis.
+ double mfMajorStep; /// Distance for major grid lines.
+ double mfMinorStep; /// Distance for minor grid lines.
+ double mfCross; /// Crossing position of other axis.
+ sal_uInt16 mnFlags; /// Additional flags.
+
+ explicit XclChValueRange();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChTick
+{
+ Color maTextColor; /// Tick labels color.
+ sal_uInt8 mnMajor; /// Type of tick marks of major grid.
+ sal_uInt8 mnMinor; /// Type of tick marks of minor grid.
+ sal_uInt8 mnLabelPos; /// Position of labels relative to axis.
+ sal_uInt8 mnBackMode; /// Background mode: transparent, opaque.
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnRotation; /// Tick labels angle (BIFF8+).
+
+ explicit XclChTick();
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAxis
+{
+ sal_uInt16 mnType; /// Axis type.
+
+ explicit XclChAxis();
+
+ /** Returns the axis dimension index used by the chart API. */
+ sal_Int32 GetApiAxisDimension() const;
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclChAxesSet
+{
+ XclChRectangle maRect; /// Position of the axes set (inner plot area).
+ sal_uInt16 mnAxesSetId; /// Primary/secondary axes set.
+
+ explicit XclChAxesSet();
+
+ /** Returns the axes set index used by the chart API. */
+ sal_Int32 GetApiAxesSetIndex() const;
+};
+
+// Property mode ==============================================================
+
+/** Specifies the type of a formatting. This results in different property names. */
+enum XclChPropertyMode
+{
+ EXC_CHPROPMODE_COMMON, /// Common objects, no special handling.
+ EXC_CHPROPMODE_LINEARSERIES, /// Specific to data series drawn as lines.
+ EXC_CHPROPMODE_FILLEDSERIES /// Specific to data series drawn as areas.
+};
+
+// Static helper functions ====================================================
+
+/** Contains static helper functions for the chart filters. */
+class XclChartHelper
+{
+public:
+ /** Returns a palette index for automatic series line colors. */
+ static sal_uInt16 GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx );
+ /** Returns a palette index for automatic series fill colors. */
+ static sal_uInt16 GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx );
+ /** Returns a transparency value for automatic series fill colors. */
+ static sal_uInt8 GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx );
+ /** Returns an automatic symbol index for the passed format index. */
+ static sal_uInt16 GetAutoMarkerType( sal_uInt16 nFormatIdx );
+ /** Returns true, if the passed marker type is filled. */
+ static bool HasMarkerFillColor( sal_uInt16 nMarkerType );
+ /** Returns the role name for a manual data source for error bars. */
+ static ::rtl::OUString GetErrorBarValuesRole( sal_uInt8 nBarType );
+};
+
+// Chart formatting info provider =============================================
+
+/** Enumerates different object types for specific automatic formatting behaviour. */
+enum XclChObjectType
+{
+ EXC_CHOBJTYPE_BACKGROUND, /// Chart background.
+ EXC_CHOBJTYPE_PLOTFRAME, /// Wall formatting in 2d charts.
+ EXC_CHOBJTYPE_WALL3D, /// Wall formatting in 3d charts.
+ EXC_CHOBJTYPE_FLOOR3D, /// Floor formatting in 3d charts.
+ EXC_CHOBJTYPE_TEXT, /// Text boxes (titles, data point labels).
+ EXC_CHOBJTYPE_LEGEND, /// Chart legend.
+ EXC_CHOBJTYPE_LINEARSERIES, /// Series formatting in a chart supporting line formatting only.
+ EXC_CHOBJTYPE_FILLEDSERIES, /// Series formatting in a chart supporting area formatting.
+ EXC_CHOBJTYPE_AXISLINE, /// Axis line format.
+ EXC_CHOBJTYPE_GRIDLINE, /// Axis grid line format.
+ EXC_CHOBJTYPE_TRENDLINE, /// Series trend line.
+ EXC_CHOBJTYPE_ERRORBAR, /// Series error bar.
+ EXC_CHOBJTYPE_CONNECTLINE, /// Data point connector line.
+ EXC_CHOBJTYPE_HILOLINE, /// High/low lines in stock charts.
+ EXC_CHOBJTYPE_WHITEDROPBAR, /// White-day drop bar in stock charts.
+ EXC_CHOBJTYPE_BLACKDROPBAR /// Black-day drop bar in stock charts.
+};
+
+/** Enumerates different types to handle missing frame objects. */
+enum XclChFrameType
+{
+ EXC_CHFRAMETYPE_AUTO, /// Missing frame represents automatic formatting.
+ EXC_CHFRAMETYPE_INVISIBLE /// Missing frame represents invisible formatting.
+};
+
+/** Contains information about auto formatting of a specific chart object type. */
+struct XclChFormatInfo
+{
+ XclChObjectType meObjType; /// Object type for automatic format.
+ XclChPropertyMode mePropMode; /// Property mode for property set helper.
+ sal_uInt16 mnAutoLineColorIdx; /// Automatic line color index.
+ sal_Int16 mnAutoLineWeight; /// Automatic line weight (hairline, single, ...).
+ sal_uInt16 mnAutoPattColorIdx; /// Automatic fill pattern color index.
+ XclChFrameType meDefFrameType; /// Default format type for missing frame objects.
+ bool mbCreateDefFrame; /// true = Create missing frame objects on import.
+ bool mbDeleteDefFrame; /// true = Delete default frame formatting on export.
+ bool mbIsFrame; /// true = Object is a frame, false = Object is a line.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides access to chart auto formatting for all available object types. */
+class XclChFormatInfoProvider
+{
+public:
+ explicit XclChFormatInfoProvider();
+
+ /** Returns an info struct about auto formatting for the passed object type. */
+ const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
+
+private:
+ typedef ::std::map< XclChObjectType, const XclChFormatInfo* > XclFmtInfoMap;
+ XclFmtInfoMap maInfoMap; /// Maps object type to formatting data.
+};
+
+// Chart type info provider ===================================================
+
+/** Enumerates all kinds of different chart types. */
+enum XclChTypeId
+{
+ EXC_CHTYPEID_BAR, /// Vertical bar chart.
+ EXC_CHTYPEID_HORBAR, /// Horizontal bar chart.
+ EXC_CHTYPEID_LINE, /// Line chart.
+ EXC_CHTYPEID_AREA, /// Area chart.
+ EXC_CHTYPEID_STOCK, /// Stock chart.
+ EXC_CHTYPEID_RADARLINE, /// Linear radar chart.
+ EXC_CHTYPEID_RADARAREA, /// Filled radar chart.
+ EXC_CHTYPEID_PIE, /// Pie chart.
+ EXC_CHTYPEID_DONUT, /// Donut chart.
+ EXC_CHTYPEID_PIEEXT, /// Pie-to-pie or pie-to-bar chart.
+ EXC_CHTYPEID_SCATTER, /// Scatter (XY) chart.
+ EXC_CHTYPEID_BUBBLES, /// Bubble chart.
+ EXC_CHTYPEID_SURFACE, /// Surface chart.
+ EXC_CHTYPEID_UNKNOWN /// Default for unknown chart types.
+};
+
+/** Enumerates different categories of similar chart types. */
+enum XclChTypeCateg
+{
+ EXC_CHTYPECATEG_BAR, /// Bar charts (horizontal or vertical).
+ EXC_CHTYPECATEG_LINE, /// Line charts (line, area, stock charts).
+ EXC_CHTYPECATEG_RADAR, /// Radar charts (linear or filled).
+ EXC_CHTYPECATEG_PIE, /// Pie and donut charts.
+ EXC_CHTYPECATEG_SCATTER, /// Scatter and bubble charts.
+ EXC_CHTYPECATEG_SURFACE /// Surface charts.
+};
+
+/** Enumerates modes for varying point colors in a series. */
+enum XclChVarPointMode
+{
+ EXC_CHVARPOINT_NONE, /// No varied colors supported.
+ EXC_CHVARPOINT_SINGLE, /// Only supported, if type group contains only one series.
+ EXC_CHVARPOINT_MULTI /// Supported for multiple series in a chart type group.
+};
+
+/** Contains information for a chart type. */
+struct XclChTypeInfo
+{
+ XclChTypeId meTypeId; /// Unique chart type identifier.
+ XclChTypeCateg meTypeCateg; /// Chart type category this type belongs to.
+ sal_uInt16 mnRecId; /// Record identifier written to the file.
+ const sal_Char* mpcServiceName; /// Service name of the type.
+ XclChVarPointMode meVarPointMode; /// Mode for varying point colors.
+ sal_Int32 mnDefaultLabelPos; /// 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 = Series with area formatting (2d charts).
+ bool mbSeriesIsFrame3d; /// true = Series with area formatting (3d charts).
+ bool mbSingleSeriesVis; /// true = Only first series visible.
+ bool mbCategoryAxis; /// true = X axis contains categories.
+ bool mbSwappedAxesSet; /// true = X and Y axes are swapped.
+ bool mbSupportsStacking; /// true = Series can be stacked on each other.
+ bool mbReverseSeries; /// true = Insert unstacked series in reverse order.
+ bool mbTicksBetweenCateg; /// true = X axis ticks between categories.
+};
+
+/** Extended chart type information and access functions. */
+struct XclChExtTypeInfo : public XclChTypeInfo
+{
+ bool mb3dChart; /// Chart is actually a 3D chart.
+ bool mbSpline; /// Series lines are smoothed.
+
+ explicit XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo );
+
+ void Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline );
+
+ /** Returns true, if this chart type supports area formatting for its series. */
+ inline bool IsSeriesFrameFormat() const
+ { return mb3dChart ? mbSeriesIsFrame3d : mbSeriesIsFrame2d; }
+ /** Returns the correct object type identifier for series and data points. */
+ inline XclChObjectType GetSeriesObjectType() const
+ { return IsSeriesFrameFormat() ? EXC_CHOBJTYPE_FILLEDSERIES : EXC_CHOBJTYPE_LINEARSERIES; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides access to chart type info structs for all available chart types. */
+class XclChTypeInfoProvider
+{
+public:
+ explicit XclChTypeInfoProvider();
+
+ /** Returns chart type info for a unique chart type identifier. */
+ const XclChTypeInfo& GetTypeInfo( XclChTypeId eType ) const;
+ /** Returns the first fitting chart type info for an Excel chart type record identifier. */
+ const XclChTypeInfo& GetTypeInfoFromRecId( sal_uInt16 nRecId ) const;
+ /** Returns the first fitting chart type info for the passed service name. */
+ const XclChTypeInfo& GetTypeInfoFromService( const ::rtl::OUString& rServiceName ) const;
+
+private:
+ typedef ::std::map< XclChTypeId, const XclChTypeInfo* > XclChTypeInfoMap;
+ XclChTypeInfoMap maInfoMap; /// Maps chart types to type info data.
+};
+
+// Chart text and title object helpers ========================================
+
+/** Enumerates different text box types for default text formatting and title
+ positioning. */
+enum XclChTextType
+{
+ EXC_CHTEXTTYPE_TITLE, /// Chart title.
+ EXC_CHTEXTTYPE_LEGEND, /// Chart legend.
+ EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles.
+ EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels.
+ EXC_CHTEXTTYPE_DATALABEL /// Data point labels.
+};
+
+/** A map key for text and title objects. */
+struct XclChTextKey : public ::std::pair< XclChTextType, ::std::pair< sal_uInt16, sal_uInt16 > >
+{
+ inline explicit XclChTextKey( XclChTextType eTextType, sal_uInt16 nMainIdx = 0, sal_uInt16 nSubIdx = 0 )
+ { first = eTextType; second.first = nMainIdx; second.second = nSubIdx; }
+};
+
+/** Function prototype receiving a chart document and returning a title shape. */
+typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ (*XclChGetShapeFunc)( const ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument >& );
+
+// Property helpers ===========================================================
+
+class XclChObjectTable
+{
+public:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > XNameContainerRef;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > XServiceFactoryRef;
+
+public:
+ explicit XclChObjectTable( XServiceFactoryRef xFactory,
+ const ::rtl::OUString& rServiceName, const ::rtl::OUString& rObjNameBase );
+
+ /** Returns a named formatting object from the chart document. */
+ ::com::sun::star::uno::Any GetObject( const ::rtl::OUString& rObjName );
+ /** Insertes a named formatting object into the chart document. */
+ ::rtl::OUString InsertObject( const ::com::sun::star::uno::Any& rObj );
+
+private:
+ XServiceFactoryRef mxFactory; /// Factory to create the container.
+ XNameContainerRef mxContainer; /// Container for the objects.
+ ::rtl::OUString maServiceName; /// Service name to create the container.
+ ::rtl::OUString maObjNameBase; /// Base of names for inserted objects.
+ sal_Int32 mnIndex; /// Index to create unique identifiers.
+};
+
+// ----------------------------------------------------------------------------
+
+struct XclFontData;
+
+/** Helper class for usage of property sets. */
+class XclChPropSetHelper
+{
+public:
+ explicit XclChPropSetHelper();
+
+ /** Reads all line properties from the passed property set. */
+ void ReadLineProperties(
+ XclChLineFormat& rLineFmt,
+ XclChObjectTable& rDashTable,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads solid area properties from the passed property set.
+ @return true = object contains complex fill properties. */
+ bool ReadAreaProperties(
+ XclChAreaFormat& rAreaFmt,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads gradient or bitmap area properties from the passed property set. */
+ void ReadEscherProperties(
+ XclChEscherFormat& rEscherFmt,
+ XclChPicFormat& rPicFmt,
+ XclChObjectTable& rGradientTable,
+ XclChObjectTable& rHatchTable,
+ XclChObjectTable& rBitmapTable,
+ const ScfPropertySet& rPropSet,
+ XclChPropertyMode ePropMode );
+ /** Reads all marker properties from the passed property set. */
+ void ReadMarkerProperties(
+ XclChMarkerFormat& rMarkerFmt,
+ const ScfPropertySet& rPropSet,
+ sal_uInt16 nFormatIdx );
+ /** Reads rotation properties from the passed property set. */
+ sal_uInt16 ReadRotationProperties(
+ const ScfPropertySet& rPropSet,
+ bool bSupportsStacked );
+
+ /** Writes all line properties to the passed property set. */
+ void WriteLineProperties(
+ ScfPropertySet& rPropSet,
+ XclChObjectTable& rDashTable,
+ const XclChLineFormat& rLineFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes solid area properties to the passed property set. */
+ void WriteAreaProperties(
+ ScfPropertySet& rPropSet,
+ const XclChAreaFormat& rAreaFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes gradient or bitmap area properties to the passed property set. */
+ void WriteEscherProperties(
+ ScfPropertySet& rPropSet,
+ XclChObjectTable& rGradientTable,
+ XclChObjectTable& rHatchTable,
+ XclChObjectTable& rBitmapTable,
+ const XclChEscherFormat& rEscherFmt,
+ const XclChPicFormat& rPicFmt,
+ XclChPropertyMode ePropMode );
+ /** Writes all marker properties to the passed property set. */
+ void WriteMarkerProperties(
+ ScfPropertySet& rPropSet,
+ const XclChMarkerFormat& rMarkerFmt );
+ /** Writes rotation properties to the passed property set. */
+ void WriteRotationProperties(
+ ScfPropertySet& rPropSet,
+ sal_uInt16 nRotation,
+ bool bSupportsStacked );
+
+private:
+ /** Returns a line property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetLineHelper( XclChPropertyMode ePropMode );
+ /** Returns an area property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetAreaHelper( XclChPropertyMode ePropMode );
+ /** Returns a gradient property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetGradientHelper( XclChPropertyMode ePropMode );
+ /** Returns a hatch property set helper according to the passed property mode. */
+ ScfPropSetHelper& GetHatchHelper( XclChPropertyMode ePropMode );
+
+private:
+ ScfPropSetHelper maLineHlpCommon; /// Properties for lines in common objects.
+ ScfPropSetHelper maLineHlpLinear; /// Properties for lines in linear series.
+ ScfPropSetHelper maLineHlpFilled; /// Properties for lines in filled series.
+ ScfPropSetHelper maAreaHlpCommon; /// Properties for areas in common objects.
+ ScfPropSetHelper maAreaHlpFilled; /// Properties for areas in filled series.
+ ScfPropSetHelper maGradHlpCommon; /// Properties for gradients in common objects.
+ ScfPropSetHelper maGradHlpFilled; /// Properties for gradients in filled series.
+ ScfPropSetHelper maHatchHlpCommon; /// Properties for hatches in common objects.
+ ScfPropSetHelper maHatchHlpFilled; /// Properties for hatches in filled series.
+ ScfPropSetHelper maBitmapHlp; /// Properties for bitmaps.
+};
+
+// ============================================================================
+
+/** Base struct for internal root data structs for import and export. */
+struct XclChRootData
+{
+ typedef boost::shared_ptr< XclChTypeInfoProvider > XclChTypeProvRef;
+ typedef boost::shared_ptr< XclChFormatInfoProvider > XclChFmtInfoProvRef;
+ typedef boost::shared_ptr< XclChObjectTable > XclChObjectTableRef;
+ typedef ::std::map< XclChTextKey, XclChGetShapeFunc > XclChGetShapeFuncMap;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >
+ mxChartDoc; /// The chart document.
+ Rectangle maChartRect; /// Position and size of the chart shape.
+ XclChTypeProvRef mxTypeInfoProv; /// Provides info about chart types.
+ XclChFmtInfoProvRef mxFmtInfoProv; /// Provides info about auto formatting.
+ XclChObjectTableRef mxLineDashTable; /// Container for line dash styles.
+ XclChObjectTableRef mxGradientTable; /// Container for gradient fill styles.
+ XclChObjectTableRef mxHatchTable; /// Container for hatch fill styles.
+ XclChObjectTableRef mxBitmapTable; /// Container for bitmap fill styles.
+ XclChGetShapeFuncMap maGetShapeFuncs; /// Maps title shape getter functions.
+ sal_Int32 mnBorderGapX; /// Border gap to chart space in 1/100mm.
+ sal_Int32 mnBorderGapY; /// Border gap to chart space in 1/100mm.
+ double mfUnitSizeX; /// Size of a chart X unit (1/4000 of chart width) in 1/100 mm.
+ double mfUnitSizeY; /// Size of a chart Y unit (1/4000 of chart height) in 1/100 mm.
+
+ explicit XclChRootData();
+ virtual ~XclChRootData();
+
+ /** Starts the API chart document conversion. Must be called once before any API access. */
+ void InitConversion(
+ const XclRoot& rRoot,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
+ const Rectangle& rChartRect );
+ /** Finishes the API chart document conversion. Must be called once before any API access. */
+ void FinishConversion();
+
+ /** Returns the drawing shape interface of the specified title object. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ GetTitleShape( const XclChTextKey& rTitleKey ) const;
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx
new file mode 100644
index 000000000000..c86f1577f04d
--- /dev/null
+++ b/sc/source/filter/inc/xlconst.hxx
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCONST_HXX
+#define SC_XLCONST_HXX
+
+#include "address.hxx"
+
+// Common =====================================================================
+
+// BIFF versions --------------------------------------------------------------
+
+/** An enumeration for all Excel file format types (BIFF types). */
+enum XclBiff
+{
+ EXC_BIFF2 = 0, /// MS Excel 2.1
+ EXC_BIFF3, /// MS Excel 3.0
+ EXC_BIFF4, /// MS Excel 4.0
+ EXC_BIFF5, /// MS Excel 5.0, MS Excel 7.0 (95)
+ EXC_BIFF8, /// MS Excel 8.0 (97), 9.0 (2000), 10.0 (XP), 11.0 (2003)
+ EXC_BIFF_UNKNOWN /// Unknown BIFF version.
+};
+
+/** An enumeration for all Excel output format types. */
+enum XclOutput
+{
+ EXC_OUTPUT_BINARY, /// MS Excel binary .xls
+ EXC_OUTPUT_XML_2007, /// MS Excel 2007 .xlsx
+};
+
+// Excel sheet dimensions -----------------------------------------------------
+
+const SCCOL EXC_MAXCOL2 = 255;
+const SCROW EXC_MAXROW2 = 16383;
+const SCTAB EXC_MAXTAB2 = 0;
+
+const SCCOL EXC_MAXCOL3 = EXC_MAXCOL2;
+const SCROW EXC_MAXROW3 = EXC_MAXROW2;
+const SCTAB EXC_MAXTAB3 = EXC_MAXTAB2;
+
+const SCCOL EXC_MAXCOL4 = EXC_MAXCOL3;
+const SCROW EXC_MAXROW4 = EXC_MAXROW3;
+const SCTAB EXC_MAXTAB4 = 32767;
+
+const SCCOL EXC_MAXCOL5 = EXC_MAXCOL4;
+const SCROW EXC_MAXROW5 = EXC_MAXROW4;
+const SCTAB EXC_MAXTAB5 = EXC_MAXTAB4;
+
+const SCCOL EXC_MAXCOL8 = EXC_MAXCOL5;
+const SCROW EXC_MAXROW8 = 65535;
+const SCTAB EXC_MAXTAB8 = EXC_MAXTAB5;
+
+const SCCOL EXC_MAXCOL_XML_2007 = 16383;
+const SCROW EXC_MAXROW_XML_2007 = 1048575;
+const SCTAB EXC_MAXTAB_XML_2007 = 1023;
+
+const sal_uInt16 EXC_NOTAB = SAL_MAX_UINT16; /// An invalid Excel sheet index, for common use.
+const SCTAB SCTAB_INVALID = SCTAB_MAX; /// An invalid Calc sheet index, for common use.
+const SCTAB SCTAB_GLOBAL = SCTAB_MAX; /// A Calc sheet index for the workbook globals.
+
+// Storage/stream names -------------------------------------------------------
+
+#define EXC_STORAGE_OLE_LINKED CREATE_STRING( "LNK" )
+#define EXC_STORAGE_OLE_EMBEDDED CREATE_STRING( "MBD" )
+#define EXC_STORAGE_VBA_PROJECT CREATE_STRING( "_VBA_PROJECT_CUR" )
+#define EXC_STORAGE_VBA CREATE_STRING( "VBA" )
+
+#define EXC_STREAM_BOOK CREATE_STRING( "Book" )
+#define EXC_STREAM_WORKBOOK CREATE_STRING( "Workbook" )
+#define EXC_STREAM_CTLS CREATE_STRING( "Ctls" )
+
+// Encoded URLs ---------------------------------------------------------------
+
+const sal_Unicode EXC_URLSTART_ENCODED = '\x01'; /// Encoded URL.
+const sal_Unicode EXC_URLSTART_SELF = '\x02'; /// Reference to own workbook.
+const sal_Unicode EXC_URLSTART_SELFENCODED = '\x03'; /// Encoded self reference.
+const sal_Unicode EXC_URLSTART_OWNDOC = '\x04'; /// Reference to own workbook (BIFF5/BIFF7).
+
+const sal_Unicode EXC_URL_DOSDRIVE = '\x01'; /// DOS drive letter or UNC server name.
+const sal_Unicode EXC_URL_DRIVEROOT = '\x02'; /// Root directory of current drive.
+const sal_Unicode EXC_URL_SUBDIR = '\x03'; /// Directory name delimiter.
+const sal_Unicode EXC_URL_PARENTDIR = '\x04'; /// Parent directory.
+const sal_Unicode EXC_URL_RAW = '\x05'; /// Unencoded URL.
+const sal_Unicode EXC_URL_SHEETNAME = '\x09'; /// Sheet name starts here (BIFF4).
+
+const sal_Unicode EXC_DDE_DELIM = '\x03'; /// DDE application-topic delimiter
+
+// Error codes ----------------------------------------------------------------
+
+const sal_uInt8 EXC_ERR_NULL = 0x00;
+const sal_uInt8 EXC_ERR_DIV0 = 0x07;
+const sal_uInt8 EXC_ERR_VALUE = 0x0F;
+const sal_uInt8 EXC_ERR_REF = 0x17;
+const sal_uInt8 EXC_ERR_NAME = 0x1D;
+const sal_uInt8 EXC_ERR_NUM = 0x24;
+const sal_uInt8 EXC_ERR_NA = 0x2A;
+
+// Cached values list (EXTERNNAME, ptgArray, ...) -----------------------------
+
+const sal_uInt8 EXC_CACHEDVAL_EMPTY = 0x00;
+const sal_uInt8 EXC_CACHEDVAL_DOUBLE = 0x01;
+const sal_uInt8 EXC_CACHEDVAL_STRING = 0x02;
+const sal_uInt8 EXC_CACHEDVAL_BOOL = 0x04;
+const sal_uInt8 EXC_CACHEDVAL_ERROR = 0x10;
+
+// RK values ------------------------------------------------------------------
+
+const sal_Int32 EXC_RK_100FLAG = 0x00000001;
+const sal_Int32 EXC_RK_INTFLAG = 0x00000002;
+const sal_Int32 EXC_RK_VALUEMASK = 0xFFFFFFFC;
+
+const sal_Int32 EXC_RK_DBL = 0x00000000;
+const sal_Int32 EXC_RK_DBL100 = EXC_RK_100FLAG;
+const sal_Int32 EXC_RK_INT = EXC_RK_INTFLAG;
+const sal_Int32 EXC_RK_INT100 = EXC_RK_100FLAG | EXC_RK_INTFLAG;
+
+// Measures -------------------------------------------------------------------
+
+const sal_Int32 EXC_POINTS_PER_INCH = 72;
+const sal_Int32 EXC_TWIPS_PER_INCH = EXC_POINTS_PER_INCH * 20;
+
+const double EXC_POINTS_PER_HMM = static_cast< double >( EXC_POINTS_PER_INCH ) / 2540.0;
+
+const sal_uInt8 EXC_ORIENT_NONE = 0; /// Text orientation: not rotated.
+const sal_uInt8 EXC_ORIENT_STACKED = 1; /// Text orientation: vertically stacked.
+const sal_uInt8 EXC_ORIENT_90CCW = 2; /// Text orientation: 90 deg counterclockwise.
+const sal_uInt8 EXC_ORIENT_90CW = 3; /// Text orientation: 90 deg clockwise.
+
+const sal_uInt8 EXC_ROT_NONE = 0; /// Text rotation: not rotated.
+const sal_uInt8 EXC_ROT_90CCW = 90; /// Text rotation: 90 deg counterclockwise.
+const sal_uInt8 EXC_ROT_90CW = 180; /// Text rotation: 90 deg clockwise.
+const sal_uInt8 EXC_ROT_STACKED = 255; /// Text rotation: vertically stacked.
+
+// Records (ordered by lowest record ID) ======================================
+
+// (0x0009, 0x0209, 0x0409, 0x0809) BOF ---------------------------------------
+
+const sal_uInt16 EXC_ID2_BOF = 0x0009;
+const sal_uInt16 EXC_ID3_BOF = 0x0209;
+const sal_uInt16 EXC_ID4_BOF = 0x0409;
+const sal_uInt16 EXC_ID5_BOF = 0x0809;
+
+const sal_uInt16 EXC_BOF_BIFF2 = 0x0200;
+const sal_uInt16 EXC_BOF_BIFF3 = 0x0300;
+const sal_uInt16 EXC_BOF_BIFF4 = 0x0400;
+const sal_uInt16 EXC_BOF_BIFF5 = 0x0500;
+const sal_uInt16 EXC_BOF_BIFF8 = 0x0600;
+
+const sal_uInt16 EXC_BOF_GLOBALS = 0x0005; /// BIFF5-BIFF8 workbook globals.
+const sal_uInt16 EXC_BOF_VBMODULE = 0x0006; /// BIFF5-BIFF8 Visual BASIC module.
+const sal_uInt16 EXC_BOF_SHEET = 0x0010; /// Regular worksheet.
+const sal_uInt16 EXC_BOF_CHART = 0x0020; /// Chart sheet.
+const sal_uInt16 EXC_BOF_MACROSHEET = 0x0040; /// Macro sheet.
+const sal_uInt16 EXC_BOF_WORKSPACE = 0x0100; /// Workspace.
+const sal_uInt16 EXC_BOF_UNKNOWN = 0xFFFF; /// Internal use only.
+
+// (0x000A) EOF ---------------------------------------------------------------
+const sal_uInt16 EXC_ID_EOF = 0x000A;
+
+// (0x0012) PROTECT -----------------------------------------------------------
+const sal_uInt16 EXC_ID_PROTECT = 0x0012;
+
+// (0x0013) PASSWORD ----------------------------------------------------------
+const sal_uInt16 EXC_ID_PASSWORD = 0x0013;
+
+// (0x0019) WINDOWPROTECT -----------------------------------------------------
+const sal_uInt16 EXC_ID_WINDOWPROTECT = 0x0019;
+
+// (0x0042) CODEPAGE ----------------------------------------------------------
+const sal_uInt16 EXC_ID_CODEPAGE = 0x0042;
+
+// (0x0081) WSBOOL ------------------------------------------------------------
+const sal_uInt16 EXC_ID_WSBOOL = 0x0081;
+
+const sal_uInt16 EXC_WSBOOL_ROWBELOW = 0x0040;
+const sal_uInt16 EXC_WSBOOL_COLBELOW = 0x0080;
+const sal_uInt16 EXC_WSBOOL_FITTOPAGE = 0x0100;
+
+const sal_uInt16 EXC_WSBOOL_DEFAULTFLAGS = 0x04C1;
+
+// (0x0086) WRITEPROT ---------------------------------------------------------
+const sal_uInt16 EXC_ID_WRITEPROT = 0x0086;
+
+// (0x008C) COUNTRY -----------------------------------------------------------
+const sal_uInt16 EXC_ID_COUNTRY = 0x008C;
+
+// (0x009B) FILTERMODE --------------------------------------------------------
+const sal_uInt16 EXC_ID_FILTERMODE = 0x009B;
+
+// (0x009C) FNGROUPCOUNT ------------------------------------------------------
+const sal_uInt16 EXC_ID_FNGROUPCOUNT = 0x009C;
+
+// (0x009D) AUTOFILTERINFO ----------------------------------------------------
+const sal_uInt16 EXC_ID_AUTOFILTERINFO = 0x009D;
+
+// (0x009E) AUTOFILTER --------------------------------------------------------
+const sal_uInt16 EXC_ID_AUTOFILTER = 0x009E;
+
+// (0x00BF, 0x00C0, 0x00C1) TOOLBARHDR, TOOLBAREND, MMS -----------------------
+const sal_uInt16 EXC_ID_TOOLBARHDR = 0x00BF;
+const sal_uInt16 EXC_ID_TOOLBAREND = 0x00C0;
+const sal_uInt16 EXC_ID_MMS = 0x00C1;
+
+// (0x00E1, 0x00E2) INTERFACEHDR, INTERFACEEND --------------------------------
+const sal_uInt16 EXC_ID_INTERFACEHDR = 0x00E1;
+const sal_uInt16 EXC_ID_INTERFACEEND = 0x00E2;
+
+// (0x0160) USESELFS ----------------------------------------------------------
+const sal_uInt16 EXC_ID_USESELFS = 0x0160;
+
+// (0x0161) DSF ---------------------------------------------------------------
+const sal_uInt16 EXC_ID_DSF = 0x0161;
+
+// (0x01AA,0x01AB) USERSVIEWBEGIN, USERSVIEWEND -------------------------------
+const sal_uInt16 EXC_ID_USERSVIEWBEGIN = 0x01AA;
+const sal_uInt16 EXC_ID_USERSVIEWEND = 0x01AB;
+
+// (0x01BA) CODENAME ----------------------------------------------------------
+const sal_uInt16 EXC_ID_CODENAME = 0x01BA;
+
+// (0x01C0) XL9FILE -----------------------------------------------------------
+const sal_uInt16 EXC_ID_XL9FILE = 0x01C0;
+
+// (0x8xx) Future records -----------------------------------------------------
+
+/** Enumerates different header types of future records. */
+enum XclFutureRecType
+{
+ EXC_FUTUREREC_SIMPLE, /// Record identifier and empty flags field.
+ EXC_FUTUREREC_UNUSEDREF /// Record identifier, empty flags field, unused range address.
+};
+
+const sal_uInt16 EXC_FUTUREREC_EMPTYFLAGS = 0x0000;
+const sal_uInt16 EXC_FUTUREREC_HASREF = 0x0001;
+const sal_uInt16 EXC_FUTUREREC_ALERT = 0x0002;
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlcontent.hxx b/sc/source/filter/inc/xlcontent.hxx
new file mode 100644
index 000000000000..ae8f5c7dc7fd
--- /dev/null
+++ b/sc/source/filter/inc/xlcontent.hxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLCONTENT_HXX
+#define SC_XLCONTENT_HXX
+
+#include <sal/types.h>
+
+// Constants ==================================================================
+
+// (0x005B) FILESHARING -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FILESHARING = 0x005B;
+
+// (0x00E5) MERGEDCELLS -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MERGEDCELLS = 0x00E5;
+const sal_uInt16 EXC_MERGEDCELLS_MAXCOUNT = 1027;
+
+// (0x002F) FILEPASS ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_FILEPASS = 0x002F;
+
+const sal_uInt16 EXC_FILEPASS_BIFF5 = 0x0000;
+const sal_uInt16 EXC_FILEPASS_BIFF8 = 0x0001;
+const sal_uInt16 EXC_FILEPASS_BIFF8_STD = 0x0001;
+const sal_uInt16 EXC_FILEPASS_BIFF8_STRONG = 0x0002;
+
+// (0x00FC, 0x00FF) SST, EXTSST -----------------------------------------------
+
+const sal_uInt16 EXC_ID_SST = 0x00FC;
+const sal_uInt16 EXC_ID_EXTSST = 0x00FF;
+
+// (0x015F) LABELRANGES -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_LABELRANGES = 0x015F;
+
+// (0x01B0) CONDFMT, (0x01B1) CF ----------------------------------------------
+
+const sal_uInt16 EXC_ID_CONDFMT = 0x01B0;
+const sal_uInt16 EXC_ID_CF = 0x01B1;
+
+const sal_uInt8 EXC_CF_TYPE_NONE = 0x00;
+const sal_uInt8 EXC_CF_TYPE_CELL = 0x01;
+const sal_uInt8 EXC_CF_TYPE_FMLA = 0x02;
+
+const sal_uInt8 EXC_CF_CMP_NONE = 0x00;
+const sal_uInt8 EXC_CF_CMP_BETWEEN = 0x01;
+const sal_uInt8 EXC_CF_CMP_NOT_BETWEEN = 0x02;
+const sal_uInt8 EXC_CF_CMP_EQUAL = 0x03;
+const sal_uInt8 EXC_CF_CMP_NOT_EQUAL = 0x04;
+const sal_uInt8 EXC_CF_CMP_GREATER = 0x05;
+const sal_uInt8 EXC_CF_CMP_LESS = 0x06;
+const sal_uInt8 EXC_CF_CMP_GREATER_EQUAL = 0x07;
+const sal_uInt8 EXC_CF_CMP_LESS_EQUAL = 0x08;
+
+const sal_uInt32 EXC_CF_BORDER_LEFT = 0x00000400; /// Left border line modified?
+const sal_uInt32 EXC_CF_BORDER_RIGHT = 0x00000800; /// Right border line modified?
+const sal_uInt32 EXC_CF_BORDER_TOP = 0x00001000; /// Top border line modified?
+const sal_uInt32 EXC_CF_BORDER_BOTTOM = 0x00002000; /// Bottom border line modified?
+const sal_uInt32 EXC_CF_BORDER_ALL = 0x00003C00; /// Any border line modified?
+const sal_uInt32 EXC_CF_AREA_PATTERN = 0x00010000; /// Pattern modified?
+const sal_uInt32 EXC_CF_AREA_FGCOLOR = 0x00020000; /// Foreground color modified?
+const sal_uInt32 EXC_CF_AREA_BGCOLOR = 0x00040000; /// Background color modified?
+const sal_uInt32 EXC_CF_AREA_ALL = 0x00070000; /// Any area attribute modified?
+const sal_uInt32 EXC_CF_ALLDEFAULT = 0x003FFFFF; /// Default flags.
+const sal_uInt32 EXC_CF_BLOCK_FONT = 0x04000000; /// Font block present?
+const sal_uInt32 EXC_CF_BLOCK_BORDER = 0x10000000; /// Border block present?
+const sal_uInt32 EXC_CF_BLOCK_AREA = 0x20000000; /// Pattern block present?
+
+const sal_uInt32 EXC_CF_FONT_STYLE = 0x00000002; /// Font posture or weight modified?
+const sal_uInt32 EXC_CF_FONT_STRIKEOUT = 0x00000080; /// Font cancellation modified?
+const sal_uInt32 EXC_CF_FONT_ALLDEFAULT = 0x0000009A; /// Default flags.
+
+const sal_uInt32 EXC_CF_FONT_UNDERL = 0x00000001; /// Font underline type modified?
+const sal_uInt32 EXC_CF_FONT_ESCAPEM = 0x00000001; /// Font escapement type modified?
+
+// (0x01B2) DVAL --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DVAL = 0x01B2;
+const sal_uInt32 EXC_DVAL_NOOBJ = 0xFFFFFFFF;
+
+// (0x01BE) DV ----------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_DV = 0x01BE;
+
+// data validation flags
+const sal_uInt32 EXC_DV_STRINGLIST = 0x00000080;
+const sal_uInt32 EXC_DV_IGNOREBLANK = 0x00000100;
+const sal_uInt32 EXC_DV_SUPPRESSDROPDOWN = 0x00000200;
+const sal_uInt32 EXC_DV_SHOWPROMPT = 0x00040000;
+const sal_uInt32 EXC_DV_SHOWERROR = 0x00080000;
+
+// data validation data mode
+const sal_uInt32 EXC_DV_MODE_MASK = 0x0000000F;
+const sal_uInt32 EXC_DV_MODE_ANY = 0x00000000;
+const sal_uInt32 EXC_DV_MODE_WHOLE = 0x00000001;
+const sal_uInt32 EXC_DV_MODE_DECIMAL = 0x00000002;
+const sal_uInt32 EXC_DV_MODE_LIST = 0x00000003;
+const sal_uInt32 EXC_DV_MODE_DATE = 0x00000004;
+const sal_uInt32 EXC_DV_MODE_TIME = 0x00000005;
+const sal_uInt32 EXC_DV_MODE_TEXTLEN = 0x00000006;
+const sal_uInt32 EXC_DV_MODE_CUSTOM = 0x00000007;
+
+// data validation conditions
+const sal_uInt32 EXC_DV_COND_MASK = 0x00F00000;
+const sal_uInt32 EXC_DV_COND_BETWEEN = 0x00000000;
+const sal_uInt32 EXC_DV_COND_NOTBETWEEN = 0x00100000;
+const sal_uInt32 EXC_DV_COND_EQUAL = 0x00200000;
+const sal_uInt32 EXC_DV_COND_NOTEQUAL = 0x00300000;
+const sal_uInt32 EXC_DV_COND_GREATER = 0x00400000;
+const sal_uInt32 EXC_DV_COND_LESS = 0x00500000;
+const sal_uInt32 EXC_DV_COND_EQGREATER = 0x00600000;
+const sal_uInt32 EXC_DV_COND_EQLESS = 0x00700000;
+
+// data validation error style
+const sal_uInt32 EXC_DV_ERROR_MASK = 0x00000070;
+const sal_uInt32 EXC_DV_ERROR_STOP = 0x00000000;
+const sal_uInt32 EXC_DV_ERROR_WARNING = 0x00000010;
+const sal_uInt32 EXC_DV_ERROR_INFO = 0x00000020;
+
+// (0x01B8) HLINK -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_HLINK = 0x01B8;
+
+const sal_uInt32 EXC_HLINK_BODY = 0x00000001; /// Contains file link or URL.
+const sal_uInt32 EXC_HLINK_ABS = 0x00000002; /// Absolute path.
+const sal_uInt32 EXC_HLINK_DESCR = 0x00000014; /// Description.
+const sal_uInt32 EXC_HLINK_MARK = 0x00000008; /// Text mark.
+const sal_uInt32 EXC_HLINK_FRAME = 0x00000080; /// Target frame.
+const sal_uInt32 EXC_HLINK_UNC = 0x00000100; /// UNC path.
+
+// web queries ================================================================
+
+#define EXC_WEBQRY_FILTER "calc_HTML_WebQuery"
+
+// (0x00CD) WQSTRING
+const sal_uInt16 EXC_ID_WQSTRING = 0x00CD;
+
+// (0x00DC) PARAMQRY
+const sal_uInt16 EXC_ID_PQRY = 0x00DC;
+const sal_uInt16 EXC_PQRYTYPE_ODBC = 1; /// Source type: ODBC.
+const sal_uInt16 EXC_PQRYTYPE_WEBQUERY = 4; /// Source type: webquery.
+const sal_uInt16 EXC_PQRY_ODBC = 0x0008; /// ODBC connection.
+const sal_uInt16 EXC_PQRY_WEBQUERY = 0x0040; /// Web query.
+const sal_uInt16 EXC_PQRY_TABLES = 0x0100; /// All tables.
+
+// (0x01AD) QSI
+const sal_uInt16 EXC_ID_QSI = 0x01AD;
+const sal_uInt16 EXC_QSI_DEFAULTFLAGS = 0x0349; /// Flags for export.
+
+// (0x0802) unknown record
+const sal_uInt16 EXC_ID_0802 = 0x0802;
+
+// (0x0803) WEBQRYSETTINGS
+const sal_uInt16 EXC_ID_WQSETT = 0x0803;
+const sal_uInt16 EXC_WQSETT_ALL = 0x0000; /// All tables or entire document.
+const sal_uInt16 EXC_WQSETT_SPECTABLES = 0x0002; /// Specific tables.
+const sal_uInt16 EXC_WQSETT_DEFAULTFLAGS = 0x0023; /// Flags for export.
+const sal_uInt16 EXC_WQSETT_NOFORMAT = 0x0001;
+const sal_uInt16 EXC_WQSETT_FORMATRTF = 0x0002;
+const sal_uInt16 EXC_WQSETT_FORMATFULL = 0x0003;
+
+// (0x0804) WEBQRYTABLES
+const sal_uInt16 EXC_ID_WQTABLES = 0x0804;
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx
new file mode 100644
index 000000000000..04396af72009
--- /dev/null
+++ b/sc/source/filter/inc/xlescher.hxx
@@ -0,0 +1,462 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLESCHER_HXX
+#define SC_XLESCHER_HXX
+
+#include <tools/gen.hxx>
+#include <tools/mapunit.hxx>
+#include "fapihelper.hxx"
+#include "xladdress.hxx"
+#include "xlstyle.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShape; }
+ namespace awt { class XControlModel; }
+ namespace script { struct ScriptEventDescriptor; }
+} } }
+
+class SdrObject;
+class Rectangle;
+class ScDocument;
+class SvStream;
+class XclImpStream;
+class XclExpStream;
+
+// Constants and Enumerations =================================================
+
+// (0x001C) NOTE --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_NOTE = 0x001C;
+const sal_uInt16 EXC_NOTE_VISIBLE = 0x0002;
+const sal_uInt16 EXC_NOTE5_MAXLEN = 2048;
+
+// (0x005D) OBJ ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_OBJ = 0x005D;
+
+const sal_uInt16 EXC_OBJ_INVALID_ID = 0;
+
+// object types
+const sal_uInt16 EXC_OBJTYPE_GROUP = 0;
+const sal_uInt16 EXC_OBJTYPE_LINE = 1;
+const sal_uInt16 EXC_OBJTYPE_RECTANGLE = 2;
+const sal_uInt16 EXC_OBJTYPE_OVAL = 3;
+const sal_uInt16 EXC_OBJTYPE_ARC = 4;
+const sal_uInt16 EXC_OBJTYPE_CHART = 5;
+const sal_uInt16 EXC_OBJTYPE_TEXT = 6;
+const sal_uInt16 EXC_OBJTYPE_BUTTON = 7;
+const sal_uInt16 EXC_OBJTYPE_PICTURE = 8;
+const sal_uInt16 EXC_OBJTYPE_POLYGON = 9; // new in BIFF4
+const sal_uInt16 EXC_OBJTYPE_CHECKBOX = 11; // new in BIFF5
+const sal_uInt16 EXC_OBJTYPE_OPTIONBUTTON = 12;
+const sal_uInt16 EXC_OBJTYPE_EDIT = 13;
+const sal_uInt16 EXC_OBJTYPE_LABEL = 14;
+const sal_uInt16 EXC_OBJTYPE_DIALOG = 15;
+const sal_uInt16 EXC_OBJTYPE_SPIN = 16;
+const sal_uInt16 EXC_OBJTYPE_SCROLLBAR = 17;
+const sal_uInt16 EXC_OBJTYPE_LISTBOX = 18;
+const sal_uInt16 EXC_OBJTYPE_GROUPBOX = 19;
+const sal_uInt16 EXC_OBJTYPE_DROPDOWN = 20;
+const sal_uInt16 EXC_OBJTYPE_NOTE = 25; // new in BIFF8
+const sal_uInt16 EXC_OBJTYPE_DRAWING = 30;
+const sal_uInt16 EXC_OBJTYPE_UNKNOWN = 0xFFFF; /// For internal use only.
+
+// BIFF3-BIFF5 flags
+const sal_uInt16 EXC_OBJ_HIDDEN = 0x0100;
+const sal_uInt16 EXC_OBJ_VISIBLE = 0x0200;
+const sal_uInt16 EXC_OBJ_PRINTABLE = 0x0400;
+
+// BIFF5 line formatting
+const sal_uInt8 EXC_OBJ_LINE_AUTOCOLOR = 64;
+
+const sal_uInt8 EXC_OBJ_LINE_SOLID = 0;
+const sal_uInt8 EXC_OBJ_LINE_DASH = 1;
+const sal_uInt8 EXC_OBJ_LINE_DOT = 2;
+const sal_uInt8 EXC_OBJ_LINE_DASHDOT = 3;
+const sal_uInt8 EXC_OBJ_LINE_DASHDOTDOT = 4;
+const sal_uInt8 EXC_OBJ_LINE_MEDTRANS = 5;
+const sal_uInt8 EXC_OBJ_LINE_DARKTRANS = 6;
+const sal_uInt8 EXC_OBJ_LINE_LIGHTTRANS = 7;
+const sal_uInt8 EXC_OBJ_LINE_NONE = 255;
+
+const sal_uInt8 EXC_OBJ_LINE_HAIR = 0;
+const sal_uInt8 EXC_OBJ_LINE_THIN = 1;
+const sal_uInt8 EXC_OBJ_LINE_MEDIUM = 2;
+const sal_uInt8 EXC_OBJ_LINE_THICK = 3;
+
+const sal_uInt8 EXC_OBJ_LINE_AUTO = 0x01;
+
+const sal_uInt8 EXC_OBJ_ARROW_NONE = 0;
+const sal_uInt8 EXC_OBJ_ARROW_OPEN = 1;
+const sal_uInt8 EXC_OBJ_ARROW_FILLED = 2;
+const sal_uInt8 EXC_OBJ_ARROW_OPENBOTH = 3;
+const sal_uInt8 EXC_OBJ_ARROW_FILLEDBOTH = 4;
+
+const sal_uInt8 EXC_OBJ_ARROW_NARROW = 0;
+const sal_uInt8 EXC_OBJ_ARROW_MEDIUM = 1;
+const sal_uInt8 EXC_OBJ_ARROW_WIDE = 2;
+
+const sal_uInt8 EXC_OBJ_LINE_TL = 0;
+const sal_uInt8 EXC_OBJ_LINE_TR = 1;
+const sal_uInt8 EXC_OBJ_LINE_BR = 2;
+const sal_uInt8 EXC_OBJ_LINE_BL = 3;
+
+// BIFF5 fill formatting
+const sal_uInt8 EXC_OBJ_FILL_AUTOCOLOR = 65;
+
+const sal_uInt8 EXC_OBJ_FILL_AUTO = 0x01;
+
+// BIFF5 frame formatting
+const sal_uInt16 EXC_OBJ_FRAME_SHADOW = 0x0002;
+
+// BIFF5 text objects
+const sal_uInt8 EXC_OBJ_HOR_LEFT = 1;
+const sal_uInt8 EXC_OBJ_HOR_CENTER = 2;
+const sal_uInt8 EXC_OBJ_HOR_RIGHT = 3;
+const sal_uInt8 EXC_OBJ_HOR_JUSTIFY = 4;
+
+const sal_uInt8 EXC_OBJ_VER_TOP = 1;
+const sal_uInt8 EXC_OBJ_VER_CENTER = 2;
+const sal_uInt8 EXC_OBJ_VER_BOTTOM = 3;
+const sal_uInt8 EXC_OBJ_VER_JUSTIFY = 4;
+
+const sal_uInt16 EXC_OBJ_ORIENT_NONE = 0;
+const sal_uInt16 EXC_OBJ_ORIENT_STACKED = 1; /// Stacked top to bottom.
+const sal_uInt16 EXC_OBJ_ORIENT_90CCW = 2; /// 90 degr. counterclockwise.
+const sal_uInt16 EXC_OBJ_ORIENT_90CW = 3; /// 90 degr. clockwise.
+
+const sal_uInt16 EXC_OBJ_TEXT_AUTOSIZE = 0x0080;
+const sal_uInt16 EXC_OBJ_TEXT_LOCKED = 0x0200;
+
+const sal_Int32 EXC_OBJ_TEXT_MARGIN = 20000; /// Automatic text margin (EMUs).
+
+// BIFF5 arc objects
+const sal_uInt8 EXC_OBJ_ARC_TR = 0;
+const sal_uInt8 EXC_OBJ_ARC_TL = 1;
+const sal_uInt8 EXC_OBJ_ARC_BL = 2;
+const sal_uInt8 EXC_OBJ_ARC_BR = 3;
+
+// BIFF5 polygon objects
+const sal_uInt16 EXC_OBJ_POLY_CLOSED = 0x0100;
+
+// BIFF5 pictures/OLE objects
+const sal_uInt16 EXC_OBJ_PIC_MANUALSIZE = 0x0001;
+const sal_uInt16 EXC_OBJ_PIC_DDE = 0x0002;
+const sal_uInt16 EXC_OBJ_PIC_SYMBOL = 0x0008;
+const sal_uInt16 EXC_OBJ_PIC_CONTROL = 0x0010; /// Form control (BIFF8).
+const sal_uInt16 EXC_OBJ_PIC_CTLSSTREAM = 0x0020; /// Data in Ctls stream (BIFF8).
+const sal_uInt16 EXC_OBJ_PIC_AUTOLOAD = 0x0200; /// Auto-load form control (BIFF8).
+
+// BIFF5 button objects
+const sal_uInt16 EXC_OBJ_BUTTON_DEFAULT = 0x0001;
+const sal_uInt16 EXC_OBJ_BUTTON_HELP = 0x0002;
+const sal_uInt16 EXC_OBJ_BUTTON_CANCEL = 0x0004;
+const sal_uInt16 EXC_OBJ_BUTTON_CLOSE = 0x0008;
+
+// BIFF5 checkboxs, radio buttons
+const sal_uInt16 EXC_OBJ_CHECKBOX_UNCHECKED = 0;
+const sal_uInt16 EXC_OBJ_CHECKBOX_CHECKED = 1;
+const sal_uInt16 EXC_OBJ_CHECKBOX_TRISTATE = 2;
+const sal_uInt16 EXC_OBJ_CHECKBOX_FLAT = 0x0001;
+
+// BIFF5 editbox objects
+const sal_uInt16 EXC_OBJ_EDIT_TEXT = 0;
+const sal_uInt16 EXC_OBJ_EDIT_INTEGER = 1;
+const sal_uInt16 EXC_OBJ_EDIT_DOUBLE = 2;
+const sal_uInt16 EXC_OBJ_EDIT_REFERENCE = 3;
+const sal_uInt16 EXC_OBJ_EDIT_FORMULA = 4;
+
+// BIFF5 scrollbars/spinbuttons
+const sal_uInt16 EXC_OBJ_SCROLLBAR_MIN = 0;
+const sal_uInt16 EXC_OBJ_SCROLLBAR_MAX = 30000;
+
+const sal_uInt16 EXC_OBJ_SCROLLBAR_HOR = 0x0001;
+
+const sal_uInt16 EXC_OBJ_SCROLLBAR_DEFFLAGS = 0x0001;
+const sal_uInt16 EXC_OBJ_SCROLLBAR_FLAT = 0x0008;
+
+// BIFF5 listboxes/dropdowns
+const sal_uInt8 EXC_OBJ_LISTBOX_SINGLE = 0; /// Single selection.
+const sal_uInt8 EXC_OBJ_LISTBOX_MULTI = 1; /// Multi selection.
+const sal_uInt8 EXC_OBJ_LISTBOX_RANGE = 2; /// Range selection.
+
+const sal_uInt16 EXC_OBJ_LISTBOX_EDIT = 0x0002;
+const sal_uInt16 EXC_OBJ_LISTBOX_FLAT = 0x0008;
+
+// BIFF5 dropdown listboxes
+const sal_uInt16 EXC_OBJ_DROPDOWN_LISTBOX = 0; /// Listbox, text not editable.
+const sal_uInt16 EXC_OBJ_DROPDOWN_COMBOBOX = 1; /// Dropdown listbox with editable text.
+const sal_uInt16 EXC_OBJ_DROPDOWN_SIMPLE = 2; /// Dropdown button only, no text area.
+const sal_uInt16 EXC_OBJ_DROPDOWN_MAX = 3;
+const sal_uInt16 EXC_OBJ_DROPDOWN_FILTERED = 0x0008; /// Drowdown style: filtered.
+
+// BIFF5 groupboxes
+const sal_uInt16 EXC_OBJ_GROUPBOX_FLAT = 0x0001;
+
+// BIFF8 sub records
+const sal_uInt16 EXC_ID_OBJEND = 0x0000; /// End of OBJ.
+const sal_uInt16 EXC_ID_OBJMACRO = 0x0004; /// Macro link.
+const sal_uInt16 EXC_ID_OBJBUTTON = 0x0005; /// Button data.
+const sal_uInt16 EXC_ID_OBJGMO = 0x0006; /// Group marker.
+const sal_uInt16 EXC_ID_OBJCF = 0x0007; /// Clipboard format.
+const sal_uInt16 EXC_ID_OBJFLAGS = 0x0008; /// Option flags.
+const sal_uInt16 EXC_ID_OBJPICTFMLA = 0x0009; /// OLE link formula.
+const sal_uInt16 EXC_ID_OBJCBLS = 0x000A; /// Check box/radio button data.
+const sal_uInt16 EXC_ID_OBJRBO = 0x000B; /// Radio button group data.
+const sal_uInt16 EXC_ID_OBJSBS = 0x000C; /// Scroll bar data.
+const sal_uInt16 EXC_ID_OBJNTS = 0x000D; /// Note data.
+const sal_uInt16 EXC_ID_OBJSBSFMLA = 0x000E; /// Scroll bar/list box/combo box cell link.
+const sal_uInt16 EXC_ID_OBJGBODATA = 0x000F; /// Group box data.
+const sal_uInt16 EXC_ID_OBJEDODATA = 0x0010; /// Edit box data.
+const sal_uInt16 EXC_ID_OBJRBODATA = 0x0011; /// Radio button group data.
+const sal_uInt16 EXC_ID_OBJCBLSDATA = 0x0012; /// Check box/radio button data.
+const sal_uInt16 EXC_ID_OBJLBSDATA = 0x0013; /// List box/combo box data.
+const sal_uInt16 EXC_ID_OBJCBLSFMLA = 0x0014; /// Check box/radio button cell link.
+const sal_uInt16 EXC_ID_OBJCMO = 0x0015; /// Common object settings.
+const sal_uInt16 EXC_ID_OBJUNKNOWN = 0xFFFF; /// For internal use only.
+
+// BIFF8 OBJCMO: flags
+const sal_uInt16 EXC_OBJCMO_PRINTABLE = 0x0010; /// Object printable.
+const sal_uInt16 EXC_OBJCMO_AUTOLINE = 0x2000; /// Automatic line formatting.
+const sal_uInt16 EXC_OBJCMO_AUTOFILL = 0x4000; /// Automatic fill formatting.
+
+/** Value binding mode for cells linked to form controls. */
+enum XclCtrlBindMode
+{
+ EXC_CTRL_BINDCONTENT, /// Binds cell to content of control.
+ EXC_CTRL_BINDPOSITION /// Binds cell to position in control (e.g. listbox selection index).
+};
+
+// (0x007F) IMGDATA -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID3_IMGDATA = 0x007F;
+const sal_uInt16 EXC_ID8_IMGDATA = 0x00E9;
+
+const sal_uInt16 EXC_IMGDATA_WMF = 2;
+const sal_uInt16 EXC_IMGDATA_BMP = 9;
+
+const sal_uInt16 EXC_IMGDATA_WIN = 1;
+const sal_uInt16 EXC_IMGDATA_MAC = 2;
+
+const sal_uInt32 EXC_IMGDATA_MAXREC8 = 0x201C;
+const sal_uInt32 EXC_IMGDATA_MAXCONT8 = 0x2014;
+
+// (0x00A9) COORDLIST ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_COORDLIST = 0x00A9;
+
+// (0x00EB) MSODRAWINGGROUP ---------------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWINGGROUP = 0x00EB;
+
+// (0x00EC) MSODRAWING --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWING = 0x00EC;
+
+// additional flags not extant in svx headers
+const sal_uInt16 EXC_ESC_ANCHOR_POSLOCKED = 0x0001;
+const sal_uInt16 EXC_ESC_ANCHOR_SIZELOCKED = 0x0002;
+const sal_uInt16 EXC_ESC_ANCHOR_LOCKED = EXC_ESC_ANCHOR_POSLOCKED|EXC_ESC_ANCHOR_SIZELOCKED;
+
+// (0x00ED) MSODRAWINGSELECTION -----------------------------------------------
+
+const sal_uInt16 EXC_ID_MSODRAWINGSEL = 0x00ED;
+
+// (0x01B6) TXO ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_TXO = 0x01B6;
+
+// TXO constants are eqzal to BIFF5 OBJ text object flags
+
+// Structs and classes ========================================================
+
+/** Identifies a drawing object by sheet index and object identifier. */
+struct XclObjId
+{
+ SCTAB mnScTab; /// Calc sheet index.
+ sal_uInt16 mnObjId; /// Excel object identifier.
+
+ explicit XclObjId();
+ explicit XclObjId( SCTAB nScTab, sal_uInt16 nObjId );
+};
+
+bool operator==( const XclObjId& rL, const XclObjId& rR );
+bool operator<( const XclObjId& rL, const XclObjId& rR );
+
+// ----------------------------------------------------------------------------
+
+/** Represents the position (anchor) of an object in a Calc document. */
+struct XclObjAnchor : public XclRange
+{
+ sal_uInt16 mnLX; /// X offset in left column (1/1024 of column width).
+ sal_uInt32 mnTY; /// Y offset in top row (1/256 of row height).
+ sal_uInt16 mnRX; /// X offset in right column (1/1024 of column width).
+ sal_uInt32 mnBY; /// Y offset in bottom row (1/256 of row height).
+
+ explicit XclObjAnchor();
+
+ /** Calculates a rectangle from the contained coordinates. */
+ Rectangle GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const;
+ /** Initializes the anchor coordinates for a sheet. */
+ void SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit );
+
+ /** Initializes the anchor coordinates for an embedded draw page. */
+ void SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY,
+ const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor );
+};
+
+
+template< typename StreamType >
+StreamType& operator>>( StreamType& rStrm, XclObjAnchor& rAnchor )
+{
+ sal_uInt16 tmpFirstRow, tmpTY, tmpLastRow, tmpBY;
+
+ rStrm
+ >> rAnchor.maFirst.mnCol >> rAnchor.mnLX
+ >> tmpFirstRow >> tmpTY
+ >> rAnchor.maLast.mnCol >> rAnchor.mnRX
+ >> tmpLastRow >> tmpBY;
+
+ rAnchor.maFirst.mnRow = static_cast<sal_uInt32> (tmpFirstRow);
+ rAnchor.mnTY = static_cast<sal_uInt32> (tmpTY);
+ rAnchor.maLast.mnRow = static_cast<sal_uInt32> (tmpLastRow);
+ rAnchor.mnBY = static_cast<sal_uInt32> (tmpBY);
+
+ return rStrm;
+}
+
+template< typename StreamType >
+StreamType& operator<<( StreamType& rStrm, const XclObjAnchor& rAnchor )
+{
+ return rStrm
+ << rAnchor.maFirst.mnCol << rAnchor.mnLX
+ << static_cast<sal_uInt16>(rAnchor.maFirst.mnRow) << static_cast<sal_uInt16>(rAnchor.mnTY)
+ << rAnchor.maLast.mnCol << rAnchor.mnRX
+ << static_cast<sal_uInt16>(rAnchor.maLast.mnRow) << static_cast<sal_uInt16>(rAnchor.mnBY);
+}
+
+// ----------------------------------------------------------------------------
+
+struct XclObjLineData
+{
+ sal_uInt8 mnColorIdx;
+ sal_uInt8 mnStyle;
+ sal_uInt8 mnWidth;
+ sal_uInt8 mnAuto;
+
+ explicit XclObjLineData();
+
+ inline bool IsAuto() const { return ::get_flag( mnAuto, EXC_OBJ_LINE_AUTO ); }
+ inline bool IsVisible() const { return IsAuto() || (mnStyle != EXC_OBJ_LINE_NONE); }
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjLineData& rLineData );
+
+// ----------------------------------------------------------------------------
+
+struct XclObjFillData
+{
+ sal_uInt8 mnBackColorIdx;
+ sal_uInt8 mnPattColorIdx;
+ sal_uInt8 mnPattern;
+ sal_uInt8 mnAuto;
+
+ explicit XclObjFillData();
+
+ inline bool IsAuto() const { return ::get_flag( mnAuto, EXC_OBJ_FILL_AUTO ); }
+ inline bool IsFilled() const { return IsAuto() || (mnPattern != EXC_PATT_NONE); }
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclObjFillData& rFillData );
+
+// ----------------------------------------------------------------------------
+
+struct XclObjTextData
+{
+ sal_uInt16 mnTextLen;
+ sal_uInt16 mnFormatSize;
+ sal_uInt16 mnLinkSize;
+ sal_uInt16 mnDefFontIdx;
+ sal_uInt16 mnFlags;
+ sal_uInt16 mnOrient;
+ sal_uInt16 mnButtonFlags;
+ sal_uInt16 mnShortcut;
+ sal_uInt16 mnShortcutEA;
+
+ explicit XclObjTextData();
+
+ /** Reads text data from a BIFF3/BIFF4 OBJ record. */
+ void ReadObj3( XclImpStream& rStrm );
+ /** Reads text data from a BIFF5 OBJ record. */
+ void ReadObj5( XclImpStream& rStrm );
+ /** Reads text data from a BIFF8 TXO record. */
+ void ReadTxo8( XclImpStream& rStrm );
+
+ inline sal_uInt8 GetHorAlign() const { return ::extract_value< sal_uInt8 >( mnFlags, 1, 3 ); }
+ inline sal_uInt8 GetVerAlign() const { return ::extract_value< sal_uInt8 >( mnFlags, 4, 3 ); }
+};
+
+// ============================================================================
+
+enum XclTbxEventType
+{
+ EXC_TBX_EVENT_ACTION, /// XActionListener.actionPerformed
+ EXC_TBX_EVENT_MOUSE, /// XMouseListener.mouseReleased
+ EXC_TBX_EVENT_TEXT, /// XTextListener.textChanged
+ EXC_TBX_EVENT_VALUE, /// XAdjustmentListener.adjustmentValueChanged
+ EXC_TBX_EVENT_CHANGE /// XChangeListener.changed
+};
+
+// ----------------------------------------------------------------------------
+
+/** Provides static helper functions for form controls. */
+class XclControlHelper
+{
+public:
+ /** Returns the API control model from the passed API shape object. */
+ static ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
+ GetControlModel( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ /** Fills the macro descriptor according to the passed macro name. */
+ static bool FillMacroDescriptor(
+ ::com::sun::star::script::ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType,
+ const String& rXclMacroName,
+ SfxObjectShell* pDocShell = 0 );
+ /** Tries to extract an Excel macro name from the passed macro descriptor. */
+ static String ExtractFromMacroDescriptor(
+ const ::com::sun::star::script::ScriptEventDescriptor& rDescriptor,
+ XclTbxEventType eEventType, SfxObjectShell* pShell = NULL );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlformula.hxx b/sc/source/filter/inc/xlformula.hxx
new file mode 100644
index 000000000000..1f9cf30909e9
--- /dev/null
+++ b/sc/source/filter/inc/xlformula.hxx
@@ -0,0 +1,572 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLFORMULA_HXX
+#define SC_XLFORMULA_HXX
+
+#include <map>
+#include <formula/opcode.hxx>
+#include "address.hxx"
+#include "ftools.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Constants ==================================================================
+
+const size_t EXC_TOKARR_MAXLEN = 4096; /// Maximum size of a token array.
+
+// Token class flags ----------------------------------------------------------
+
+const sal_uInt8 EXC_TOKCLASS_MASK = 0x60;
+const sal_uInt8 EXC_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens.
+const sal_uInt8 EXC_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens.
+const sal_uInt8 EXC_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens.
+const sal_uInt8 EXC_TOKCLASS_ARR = 0x60; /// 60-7F: Array class tokens.
+
+// Base tokens ----------------------------------------------------------------
+
+const sal_uInt8 EXC_TOKID_MASK = 0x1F;
+
+const sal_uInt8 EXC_TOKID_NONE = 0x00; /// Placeholder for invalid token id.
+const sal_uInt8 EXC_TOKID_EXP = 0x01; /// Array or shared formula reference.
+const sal_uInt8 EXC_TOKID_TBL = 0x02; /// Multiple operation reference.
+const sal_uInt8 EXC_TOKID_ADD = 0x03; /// Addition operator.
+const sal_uInt8 EXC_TOKID_SUB = 0x04; /// Subtraction operator.
+const sal_uInt8 EXC_TOKID_MUL = 0x05; /// Multiplication operator.
+const sal_uInt8 EXC_TOKID_DIV = 0x06; /// Division operator.
+const sal_uInt8 EXC_TOKID_POWER = 0x07; /// Power operator.
+const sal_uInt8 EXC_TOKID_CONCAT = 0x08; /// String concatenation operator.
+const sal_uInt8 EXC_TOKID_LT = 0x09; /// Less than operator.
+const sal_uInt8 EXC_TOKID_LE = 0x0A; /// Less than or equal operator.
+const sal_uInt8 EXC_TOKID_EQ = 0x0B; /// Equal operator.
+const sal_uInt8 EXC_TOKID_GE = 0x0C; /// Greater than or equal operator.
+const sal_uInt8 EXC_TOKID_GT = 0x0D; /// Greater than operator.
+const sal_uInt8 EXC_TOKID_NE = 0x0E; /// Not equal operator.
+const sal_uInt8 EXC_TOKID_ISECT = 0x0F; /// Intersection operator.
+const sal_uInt8 EXC_TOKID_LIST = 0x10; /// List operator.
+const sal_uInt8 EXC_TOKID_RANGE = 0x11; /// Range operator.
+const sal_uInt8 EXC_TOKID_UPLUS = 0x12; /// Unary plus.
+const sal_uInt8 EXC_TOKID_UMINUS = 0x13; /// Unary minus.
+const sal_uInt8 EXC_TOKID_PERCENT = 0x14; /// Percent sign.
+const sal_uInt8 EXC_TOKID_PAREN = 0x15; /// Parentheses.
+const sal_uInt8 EXC_TOKID_MISSARG = 0x16; /// Missing argument.
+const sal_uInt8 EXC_TOKID_STR = 0x17; /// String constant.
+const sal_uInt8 EXC_TOKID_NLR = 0x18; /// Natural language reference (NLR).
+const sal_uInt8 EXC_TOKID_ATTR = 0x19; /// Special attribute.
+const sal_uInt8 EXC_TOKID_SHEET = 0x1A; /// Start of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 EXC_TOKID_ENDSHEET = 0x1B; /// End of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 EXC_TOKID_ERR = 0x1C; /// Error constant.
+const sal_uInt8 EXC_TOKID_BOOL = 0x1D; /// Boolean constant.
+const sal_uInt8 EXC_TOKID_INT = 0x1E; /// Integer constant.
+const sal_uInt8 EXC_TOKID_NUM = 0x1F; /// Floating-point constant.
+
+// Base IDs of classified tokens ----------------------------------------------
+
+const sal_uInt8 EXC_TOKID_ARRAY = 0x00; /// Array constant.
+const sal_uInt8 EXC_TOKID_FUNC = 0x01; /// Function, fixed number of arguments.
+const sal_uInt8 EXC_TOKID_FUNCVAR = 0x02; /// Function, variable number of arguments.
+const sal_uInt8 EXC_TOKID_NAME = 0x03; /// Defined name.
+const sal_uInt8 EXC_TOKID_REF = 0x04; /// 2D cell reference.
+const sal_uInt8 EXC_TOKID_AREA = 0x05; /// 2D area reference.
+const sal_uInt8 EXC_TOKID_MEMAREA = 0x06; /// Constant reference subexpression.
+const sal_uInt8 EXC_TOKID_MEMERR = 0x07; /// Deleted reference subexpression.
+const sal_uInt8 EXC_TOKID_MEMNOMEM = 0x08; /// Constant reference subexpression without result.
+const sal_uInt8 EXC_TOKID_MEMFUNC = 0x09; /// Variable reference subexpression.
+const sal_uInt8 EXC_TOKID_REFERR = 0x0A; /// Deleted 2D cell reference.
+const sal_uInt8 EXC_TOKID_AREAERR = 0x0B; /// Deleted 2D area reference.
+const sal_uInt8 EXC_TOKID_REFN = 0x0C; /// Relative 2D cell reference (in names).
+const sal_uInt8 EXC_TOKID_AREAN = 0x0D; /// Relative 2D area reference (in names).
+const sal_uInt8 EXC_TOKID_MEMAREAN = 0x0E; /// Reference subexpression (in names).
+const sal_uInt8 EXC_TOKID_MEMNOMEMN = 0x0F; /// Reference subexpression (in names) without result.
+const sal_uInt8 EXC_TOKID_FUNCCE = 0x18;
+const sal_uInt8 EXC_TOKID_NAMEX = 0x19; /// External reference.
+const sal_uInt8 EXC_TOKID_REF3D = 0x1A; /// 3D cell reference.
+const sal_uInt8 EXC_TOKID_AREA3D = 0x1B; /// 3D area reference.
+const sal_uInt8 EXC_TOKID_REFERR3D = 0x1C; /// Deleted 3D cell reference.
+const sal_uInt8 EXC_TOKID_AREAERR3D = 0x1D; /// Deleted 3D area reference
+
+// specific token constants ---------------------------------------------------
+
+const sal_uInt16 EXC_TOK_STR_MAXLEN = 255; /// Maximum string length of a tStr token.
+
+const sal_uInt8 EXC_TOK_BOOL_FALSE = 0; /// sal_False value of a tBool token.
+const sal_uInt8 EXC_TOK_BOOL_TRUE = 1; /// sal_True value of a tBool token.
+
+const sal_uInt8 EXC_TOK_ATTR_VOLATILE = 0x01; /// Volatile function.
+const sal_uInt8 EXC_TOK_ATTR_IF = 0x02; /// Start of true condition in IF function.
+const sal_uInt8 EXC_TOK_ATTR_CHOOSE = 0x04; /// Jump array of CHOOSE function.
+const sal_uInt8 EXC_TOK_ATTR_GOTO = 0x08; /// Jump to token.
+const sal_uInt8 EXC_TOK_ATTR_SUM = 0x10; /// SUM function with one parameter.
+const sal_uInt8 EXC_TOK_ATTR_ASSIGN = 0x20; /// BASIC style assignment.
+const sal_uInt8 EXC_TOK_ATTR_SPACE = 0x40; /// Spaces in formula representation.
+
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP = 0x00; /// Spaces before next token.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR = 0x01; /// Line breaks before next token.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_OPEN = 0x02; /// Spaces before opening parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_OPEN = 0x03; /// Line breaks before opening parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_CLOSE = 0x04; /// Spaces before closing parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_CLOSE = 0x05; /// Line breaks before closing parenthesis.
+const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_PRE = 0x06; /// Spaces before formula (BIFF3).
+
+const sal_uInt16 EXC_TOK_FUNCVAR_CMD = 0x8000; /// Macro command.
+const sal_uInt16 EXC_TOK_FUNCVAR_INDEXMASK = 0x7FFF; /// Mask for function/command index.
+const sal_uInt8 EXC_TOK_FUNCVAR_PROMPT = 0x80; /// User prompt for macro commands.
+const sal_uInt8 EXC_TOK_FUNCVAR_COUNTMASK = 0x7F; /// Mask for parameter count.
+
+const sal_uInt16 EXC_TOK_REF_COLREL = 0x4000; /// True = Column is relative.
+const sal_uInt16 EXC_TOK_REF_ROWREL = 0x8000; /// True = Row is relative.
+
+const sal_uInt8 EXC_TOK_NLR_ERR = 0x01; /// NLR: Invalid/deleted.
+const sal_uInt8 EXC_TOK_NLR_ROWR = 0x02; /// NLR: Row index.
+const sal_uInt8 EXC_TOK_NLR_COLR = 0x03; /// NLR: Column index.
+const sal_uInt8 EXC_TOK_NLR_ROWV = 0x06; /// NLR: Value in row.
+const sal_uInt8 EXC_TOK_NLR_COLV = 0x07; /// NLR: Value in column.
+const sal_uInt8 EXC_TOK_NLR_RANGE = 0x0A; /// NLR: Range.
+const sal_uInt8 EXC_TOK_NLR_SRANGE = 0x0B; /// Stacked NLR: Range.
+const sal_uInt8 EXC_TOK_NLR_SROWR = 0x0C; /// Stacked NLR: Row index.
+const sal_uInt8 EXC_TOK_NLR_SCOLR = 0x0D; /// Stacked NLR: Column index.
+const sal_uInt8 EXC_TOK_NLR_SROWV = 0x0E; /// Stacked NLR: Value in row.
+const sal_uInt8 EXC_TOK_NLR_SCOLV = 0x0F; /// Stacked NLR: Value in column.
+const sal_uInt8 EXC_TOK_NLR_RANGEERR = 0x10; /// NLR: Invalid/deleted range.
+const sal_uInt8 EXC_TOK_NLR_SXNAME = 0x1D; /// NLR: Pivot table name.
+const sal_uInt16 EXC_TOK_NLR_REL = 0x8000; /// True = Natural language ref is relative.
+
+const sal_uInt32 EXC_TOK_NLR_ADDREL = 0x80000000; /// NLR relative (in appended data).
+const sal_uInt32 EXC_TOK_NLR_ADDMASK = 0x3FFFFFFF; /// Mask for number of appended ranges.
+
+// ----------------------------------------------------------------------------
+
+/** Type of a formula. */
+enum XclFormulaType
+{
+ EXC_FMLATYPE_CELL, /// Simple cell formula, also used in change tracking.
+ EXC_FMLATYPE_MATRIX, /// Matrix (array) formula.
+ EXC_FMLATYPE_SHARED, /// Shared formula.
+ EXC_FMLATYPE_CONDFMT, /// Conditional format.
+ EXC_FMLATYPE_DATAVAL, /// Data validation.
+ EXC_FMLATYPE_NAME, /// Defined name.
+ EXC_FMLATYPE_CHART, /// Chart source ranges.
+ EXC_FMLATYPE_CONTROL, /// Spreadsheet links in form controls.
+ EXC_FMLATYPE_WQUERY, /// Web query source range.
+ EXC_FMLATYPE_LISTVAL /// List (cell range) validation.
+};
+
+// Function parameter info ====================================================
+
+/** Enumerates validity modes for a function parameter. */
+enum XclFuncParamValidity
+{
+ EXC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array.
+ EXC_PARAM_REGULAR, /// Parameter supported by Calc and Excel.
+ EXC_PARAM_CALCONLY, /// Parameter supported by Calc only.
+ EXC_PARAM_EXCELONLY /// Parameter supported by Excel only.
+};
+
+/** Enumerates different types of token class conversion in function parameters. */
+enum XclFuncParamConv
+{
+ EXC_PARAMCONV_ORG, /// Use original class of current token.
+ EXC_PARAMCONV_VAL, /// Convert tokens to VAL class.
+ EXC_PARAMCONV_ARR, /// Convert tokens to ARR class.
+ EXC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters.
+ EXC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters.
+ EXC_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 XclFuncParamInfo
+{
+ XclFuncParamValidity meValid; /// Parameter validity.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
+// Function data ==============================================================
+
+const sal_uInt8 EXC_FUNC_MAXPARAM = 30; /// Maximum parameter count.
+
+const size_t EXC_FUNCINFO_PARAMINFO_COUNT = 5; /// Number of parameter info entries.
+
+const sal_uInt8 EXC_FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
+const sal_uInt8 EXC_FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
+const sal_uInt8 EXC_FUNCFLAG_EXPORTONLY = 0x04; /// Only used in export filter.
+
+// selected function IDs
+const sal_uInt16 EXC_FUNCID_IF = 1;
+const sal_uInt16 EXC_FUNCID_SUM = 4;
+const sal_uInt16 EXC_FUNCID_AND = 36;
+const sal_uInt16 EXC_FUNCID_OR = 37;
+const sal_uInt16 EXC_FUNCID_CHOOSE = 100;
+const sal_uInt16 EXC_FUNCID_EXTERNCALL = 255;
+
+/** Represents information for a spreadsheet function for import and export.
+
+ 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 XclFunctionInfo
+{
+ OpCode meOpCode; /// Calc function opcode.
+ sal_uInt16 mnXclFunc; /// Excel function index.
+ sal_uInt8 mnMinParamCount; /// Minimum number of parameters.
+ sal_uInt8 mnMaxParamCount; /// Maximum number of parameters.
+ sal_uInt8 mnRetClass; /// Token class of the return value.
+ XclFuncParamInfo mpParamInfos[ EXC_FUNCINFO_PARAMINFO_COUNT ]; /// Information for all parameters.
+ sal_uInt8 mnFlags; /// Additional flags (EXC_FUNCFLAG_* constants).
+ const sal_Char* mpcMacroName; /// Function name, if simulated by a macro call (UTF-8).
+
+ /** Returns true, if the function is volatile. */
+ inline bool IsVolatile() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_VOLATILE ); }
+ /** Returns true, if the function parameter count is fixed. */
+ inline bool IsFixedParamCount() const { return (mnXclFunc != EXC_FUNCID_EXTERNCALL) && (mnMinParamCount == mnMaxParamCount); }
+ /** Returns true, if the function is simulated by a macro call. */
+ inline bool IsMacroFunc() const { return mpcMacroName != 0; }
+ /** Returns the name of the external function as string. */
+ String GetMacroFuncName() const;
+};
+
+// ----------------------------------------------------------------------------
+
+class XclRoot;
+
+/** Provides access to function info structs for all available functions. */
+class XclFunctionProvider
+{
+public:
+ explicit XclFunctionProvider( const XclRoot& rRoot );
+
+ /** Returns the function data for an Excel function index, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const;
+ /** Returns the function data for an Excel function simulated by a macro call, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const;
+ /** Returns the function data for a Calc opcode, or 0 on error. */
+ const XclFunctionInfo* GetFuncInfoFromOpCode( OpCode eOpCode ) const;
+
+private:
+ void FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
+ void FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
+
+private:
+ typedef ::std::map< sal_uInt16, const XclFunctionInfo* > XclFuncMap;
+ typedef ::std::map< String, const XclFunctionInfo* > XclMacroNameMap;
+ typedef ::std::map< OpCode, const XclFunctionInfo* > ScFuncMap;
+
+ XclFuncMap maXclFuncMap; /// Maps Excel function indexes to function data.
+ XclMacroNameMap maXclMacroNameMap; /// Maps macro function names to function data.
+ ScFuncMap maScFuncMap; /// Maps Calc opcodes to function data.
+};
+
+// Token array ================================================================
+
+class XclImpStream;
+class XclExpStream;
+
+/** Binary representation of an Excel token array. */
+class XclTokenArray
+{
+public:
+ /** Creates an empty token array. */
+ explicit XclTokenArray( bool bVolatile = false );
+ /** Creates a token array, swaps passed token vector into own data. */
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile = false );
+ /** Creates a token array, swaps passed token vectors into own data. */
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile = false );
+
+ /** Returns true, if the token array is empty. */
+ inline bool Empty() const { return maTokVec.empty(); }
+ /** Returns the size of the token array in bytes. */
+ sal_uInt16 GetSize() const;
+ /** Returns read-only access to the byte vector storing token data. */
+ inline const sal_uInt8* GetData() const { return maTokVec.empty() ? 0 : &maTokVec.front(); }
+ /** Returns true, if the formula contains a volatile function. */
+ inline bool IsVolatile() const { return mbVolatile; }
+
+ /** Reads the size field of the token array. */
+ void ReadSize( XclImpStream& rStrm );
+ /** Reads the tokens of the token array (without size field). */
+ void ReadArray( XclImpStream& rStrm );
+ /** Reads size field and the tokens. */
+ void Read( XclImpStream& rStrm );
+
+ /** Writes the size field of the token array. */
+ void WriteSize( XclExpStream& rStrm ) const;
+ /** Writes the tokens of the token array (without size field). */
+ void WriteArray( XclExpStream& rStrm ) const;
+ /** Writes size field and the tokens. */
+ void Write( XclExpStream& rStrm ) const;
+
+ /** Compares this token array with the passed. */
+ bool operator==( const XclTokenArray& rTokArr ) const;
+
+private:
+ ScfUInt8Vec maTokVec; /// Byte vector containing token data.
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
+ bool mbVolatile; /// True = Formula contains volatile function.
+};
+
+typedef boost::shared_ptr< XclTokenArray > XclTokenArrayRef;
+
+/** Calls the Read() function at the passed token array. */
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr );
+/** Calls the Read() function at the passed token array. */
+XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr );
+/** Calls the Write() function at the passed token array. */
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr );
+/** Calls the Write() function at the passed token array. */
+XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr );
+
+// ----------------------------------------------------------------------------
+
+namespace formula { class FormulaToken; }
+class ScTokenArray;
+
+/** Special token array iterator for the Excel filters.
+
+ Iterates over a Calc token array without modifying it (therefore the
+ iterator can be used with constant token arrays).
+
+ Usage: Construct a new iterator object and pass a Calc token array, or use
+ the Init() function to assign another Calc token array. As long as the Is()
+ function returns true, the accessor functions can be used to get the
+ current Calc token.
+ */
+class XclTokenArrayIterator
+{
+public:
+ explicit XclTokenArrayIterator();
+ explicit XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces );
+ /** Copy constructor that allows to change the skip-spaces mode. */
+ explicit XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces );
+
+ void Init();
+ void Init( const ScTokenArray& rScTokArr, bool bSkipSpaces );
+
+ inline bool Is() const { return mppScToken != 0; }
+ inline bool operator!() const { return !Is(); }
+ inline const ::formula::FormulaToken* Get() const { return mppScToken ? *mppScToken : 0; }
+ inline const ::formula::FormulaToken* operator->() const { return Get(); }
+ inline const ::formula::FormulaToken& operator*() const { return *Get(); }
+
+ XclTokenArrayIterator& operator++();
+
+private:
+ void NextRawToken();
+ void SkipSpaces();
+
+private:
+ const ::formula::FormulaToken*const* mppScTokenBeg; /// Pointer to first token pointer of token array.
+ const ::formula::FormulaToken*const* mppScTokenEnd; /// Pointer behind last token pointer of token array.
+ const ::formula::FormulaToken*const* mppScToken; /// Pointer to current token pointer of token array.
+ bool mbSkipSpaces; /// true = Skip whitespace tokens.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all cell references that can be extracted from a multiple operations formula. */
+struct XclMultipleOpRefs
+{
+ ScAddress maFmlaScPos; /// Position of the (first) formula cell.
+ ScAddress maColFirstScPos;
+ ScAddress maColRelScPos;
+ ScAddress maRowFirstScPos;
+ ScAddress maRowRelScPos;
+ bool mbDblRefMode; /// true = One formula with row and column values.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A helper with Excel specific token array functions.
+
+ The purpose to not add these functions to ScTokenArray is to prevent code
+ changes in low-level Calc headers and to keep the Excel specific source
+ code in the filter directory. Deriving from ScTokenArray is not viable
+ because that would need expensive copy-constructions of the token arrays.
+ */
+class XclTokenArrayHelper
+{
+public:
+ // token identifiers ------------------------------------------------------
+
+ /** Returns the base token ID of the passed (classified) token ID. */
+ inline static sal_uInt8 GetBaseTokenId( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKID_MASK; }
+ /** Returns the classified token ID from a base ID and the token class. */
+ inline static sal_uInt8 GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass );
+
+ /** Returns the token class of the passed token ID. */
+ inline static sal_uInt8 GetTokenClass( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKCLASS_MASK; }
+ /** Changes the token class in the passed classified token ID. */
+ inline static void ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass );
+
+ // strings and string lists -----------------------------------------------
+
+ /** Tries to extract a string from the passed token.
+ @param rString (out-parameter) The string contained in the token.
+ @return true = Passed token is a string token, rString parameter is valid. */
+ static bool GetTokenString( String& rString, const ::formula::FormulaToken& rScToken );
+
+ /** Parses the passed formula and tries to find a single string token, i.e. "abc".
+ @param rString (out-parameter) The string contained in the formula.
+ @return true = String token found, rString parameter is valid. */
+ static bool GetString( String& rString, const ScTokenArray& rScTokArr );
+
+ /** Parses the passed formula and tries to find a string token list, i.e. "abc";"def";"ghi".
+ @descr Returns the unquoted (!) strings in a single string, separated with the
+ passed character. If a comma is specified, the function will return abc,def,ghi from
+ the example above.
+ @param rStringList (out-parameter) All strings contained in the formula as list.
+ @param cSep List separator character.
+ @return true = String token list found, rString parameter is valid. */
+ static bool GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep );
+
+ /** Tries to convert a formula that consists of a single string token to a list of strings.
+ @descr Example: The formula ="abc\ndef\nghi" will be converted to the formula
+ ="abc";"def";"ghi", if the LF character is specified as separator.
+ @param rScTokArr (in/out-parameter) The token array to modify.
+ @param cStringSep The separator in the source string.
+ @param bTrimLeadingSpaces true = remove leading spaces from each token. */
+ static void ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces );
+
+ // shared formulas --------------------------------------------------------
+
+ /** Tries to extract the definition of a shared formula from the passed token array.
+ @descr Shared formulas are stored as hidden defined names in Calc. This
+ function looks if the passed token array consists of the reference to
+ such a hidden defined name and returns its definition on success. */
+ static const ScTokenArray* GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr );
+
+ // multiple operations ----------------------------------------------------
+
+ /** Parses the passed formula and tries to extract references of a multiple operation.
+ @descr Requires that the formula contains a single MULTIPLE.OPERATION function call.
+ Spaces in the formula are silently ignored.
+ @return true = Multiple operation found, and all references successfully extracted. */
+ static bool GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr );
+};
+
+// ----------------------------------------------------------------------------
+
+inline sal_uInt8 XclTokenArrayHelper::GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass )
+{
+ DBG_ASSERT( !::get_flag( nBaseId, static_cast< sal_uInt8 >( ~EXC_TOKID_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token ID" );
+ DBG_ASSERT( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token class" );
+ return nBaseId | nTokenClass;
+}
+
+inline void XclTokenArrayHelper::ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass )
+{
+ DBG_ASSERT( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::ChangeTokenClass - invalid token class" );
+ ::set_flag( rnTokenId, EXC_TOKCLASS_MASK, false );
+ ::set_flag( rnTokenId, nTokenClass );
+}
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xllink.hxx b/sc/source/filter/inc/xllink.hxx
new file mode 100644
index 000000000000..760df8173055
--- /dev/null
+++ b/sc/source/filter/inc/xllink.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLLINK_HXX
+#define SC_XLLINK_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+const sal_uInt16 EXC_TAB_EXTERNAL = 0xFFFE; /// Special sheet index for external links.
+const sal_uInt16 EXC_TAB_DELETED = 0xFFFF; /// Deleted sheet in a 3D reference.
+
+// (0x0016) EXTERNCOUNT -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNCOUNT = 0x0016;
+
+// (0x0017) EXTERNSHEET -------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNSHEET = 0x0017;
+
+const sal_Unicode EXC_EXTSH_URL = '\x01';
+const sal_Unicode EXC_EXTSH_OWNTAB = '\x02';
+const sal_Unicode EXC_EXTSH_TABNAME = '\x03';
+const sal_Unicode EXC_EXTSH_OWNDOC = '\x04';
+const sal_Unicode EXC_EXTSH_ADDIN = '\x3A';
+
+// (0x0023) EXTERNNAME --------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EXTERNNAME = 0x0023;
+
+const sal_uInt16 EXC_EXTN_BUILTIN = 0x0001;
+const sal_uInt16 EXC_EXTN_OLE = 0x0010;
+const sal_uInt16 EXC_EXTN_OLE_OR_DDE = 0xFFFE;
+
+const sal_uInt16 EXC_EXTN_EXPDDE_STDDOC = 0x7FEA; /// for export
+const sal_uInt16 EXC_EXTN_EXPDDE = 0x7FE2; /// for export
+
+// (0x0059, 0x005A) XCT, CRN --------------------------------------------------
+
+const sal_uInt16 EXC_ID_XCT = 0x0059;
+const sal_uInt16 EXC_ID_CRN = 0x005A;
+
+// (0x013D) TABID -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_TABID = 0x013D;
+
+// (0x01AE) SUPBOOK -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SUPBOOK = 0x01AE;
+
+const sal_uInt16 EXC_SUPB_SELF = 0x0401;
+const sal_uInt16 EXC_SUPB_ADDIN = 0x3A01;
+
+/** This enumeration specifies the type of a SUPBOOK record. */
+enum XclSupbookType
+{
+ EXC_SBTYPE_UNKNOWN, /// unknown SUPBOOK record type.
+ EXC_SBTYPE_SELF, /// SUPBOOK is used for internal references.
+ EXC_SBTYPE_EXTERN, /// SUPBOOK is used for external references.
+ EXC_SBTYPE_ADDIN, /// SUPBOOK contains add-in functions.
+ EXC_SBTYPE_SPECIAL, /// SUPBOOK is used for DDE or OLE links.
+ EXC_SBTYPE_EUROTOOL /// SUPBOOK is uesd for EUROCONVERT.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlname.hxx b/sc/source/filter/inc/xlname.hxx
new file mode 100644
index 000000000000..4fbafb280f03
--- /dev/null
+++ b/sc/source/filter/inc/xlname.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLNAME_HXX
+#define SC_XLNAME_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+// (0x0018, 0x0218) NAME ------------------------------------------------------
+
+const sal_uInt16 EXC_ID_NAME = 0x0018;
+const sal_uInt16 EXC_ID34_NAME = 0x0218;
+
+// flags
+const sal_uInt16 EXC_NAME_DEFAULT = 0x0000;
+const sal_uInt16 EXC_NAME_HIDDEN = 0x0001;
+const sal_uInt16 EXC_NAME_FUNC = 0x0002;
+const sal_uInt16 EXC_NAME_VB = 0x0004;
+const sal_uInt16 EXC_NAME_PROC = 0x0008;
+const sal_uInt16 EXC_NAME_CALCEXP = 0x0010;
+const sal_uInt16 EXC_NAME_BUILTIN = 0x0020;
+const sal_uInt16 EXC_NAME_FGROUPMASK = 0x0FC0;
+const sal_uInt16 EXC_NAME_BIG = 0x1000;
+
+const sal_uInt8 EXC_NAME2_FUNC = 0x02; /// BIFF2 function/command flag.
+
+const sal_uInt16 EXC_NAME_GLOBAL = 0; /// 0 = Globally defined name.
+
+// codes for built-in names
+const sal_Unicode EXC_BUILTIN_CONSOLIDATEAREA = '\x00';
+const sal_Unicode EXC_BUILTIN_AUTOOPEN = '\x01';
+const sal_Unicode EXC_BUILTIN_AUTOCLOSE = '\x02';
+const sal_Unicode EXC_BUILTIN_EXTRACT = '\x03';
+const sal_Unicode EXC_BUILTIN_DATABASE = '\x04';
+const sal_Unicode EXC_BUILTIN_CRITERIA = '\x05';
+const sal_Unicode EXC_BUILTIN_PRINTAREA = '\x06';
+const sal_Unicode EXC_BUILTIN_PRINTTITLES = '\x07';
+const sal_Unicode EXC_BUILTIN_RECORDER = '\x08';
+const sal_Unicode EXC_BUILTIN_DATAFORM = '\x09';
+const sal_Unicode EXC_BUILTIN_AUTOACTIVATE = '\x0A';
+const sal_Unicode EXC_BUILTIN_AUTODEACTIVATE = '\x0B';
+const sal_Unicode EXC_BUILTIN_SHEETTITLE = '\x0C';
+const sal_Unicode EXC_BUILTIN_FILTERDATABASE = '\x0D';
+const sal_Unicode EXC_BUILTIN_UNKNOWN = '\x0E';
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlpage.hxx b/sc/source/filter/inc/xlpage.hxx
new file mode 100644
index 000000000000..4c7412ab9171
--- /dev/null
+++ b/sc/source/filter/inc/xlpage.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLPAGE_HXX
+#define SC_XLPAGE_HXX
+
+#include <tools/gen.hxx>
+#include <boost/noncopyable.hpp>
+#include "xltools.hxx"
+
+// Constants and Enumerations =================================================
+
+// (0x0014, 0x0015) HEADER, FOOTER --------------------------------------------
+
+const sal_uInt16 EXC_ID_HEADER = 0x0014;
+const sal_uInt16 EXC_ID_FOOTER = 0x0015;
+
+// (0x001A, 0x001B) VERTICAL-, HORIZONTALPAGEBREAKS ---------------------------
+
+const sal_uInt16 EXC_ID_VERPAGEBREAKS = 0x001A;
+const sal_uInt16 EXC_ID_HORPAGEBREAKS = 0x001B;
+
+// (0x0026, 0x0027, 0x0028, 0x0029) LEFT-, RIGHT-, TOP-, BOTTOMMARGIN ---------
+
+const sal_uInt16 EXC_ID_LEFTMARGIN = 0x0026;
+const sal_uInt16 EXC_ID_RIGHTMARGIN = 0x0027;
+const sal_uInt16 EXC_ID_TOPMARGIN = 0x0028;
+const sal_uInt16 EXC_ID_BOTTOMMARGIN = 0x0029;
+
+const sal_Int32 EXC_MARGIN_DEFAULT_LR = 1900; /// Left/right default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_TB = 2500; /// Top/bottom default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_HF = 1300; /// Header/footer default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_HLR = 1900; /// Left/right header default margin in 1/100mm.
+const sal_Int32 EXC_MARGIN_DEFAULT_FLR = 1900; /// Left/right footer default margin in 1/100mm.
+
+// (0x002A, 0x002B) PRINTHEADERS, PRINTGRIDLINES ------------------------------
+
+const sal_uInt16 EXC_ID_PRINTHEADERS = 0x002A;
+const sal_uInt16 EXC_ID_PRINTGRIDLINES = 0x002B;
+
+// (0x0033) PRINTSIZE ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PRINTSIZE = 0x0033;
+
+const sal_uInt16 EXC_PRINTSIZE_SCREEN = 1;
+const sal_uInt16 EXC_PRINTSIZE_PAGE = 2;
+const sal_uInt16 EXC_PRINTSIZE_FULL = 3;
+
+// (0x0082, 0x0083, 0x0084) GRIDSET, HCENTER, VCENTER -------------------------
+
+const sal_uInt16 EXC_ID_GRIDSET = 0x0082;
+const sal_uInt16 EXC_ID_HCENTER = 0x0083;
+const sal_uInt16 EXC_ID_VCENTER = 0x0084;
+
+// (0x00A1) SETUP -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SETUP = 0x00A1;
+
+const sal_uInt16 EXC_SETUP_INROWS = 0x0001;
+const sal_uInt16 EXC_SETUP_PORTRAIT = 0x0002;
+const sal_uInt16 EXC_SETUP_INVALID = 0x0004;
+const sal_uInt16 EXC_SETUP_BLACKWHITE = 0x0008;
+const sal_uInt16 EXC_SETUP_DRAFT = 0x0010;
+const sal_uInt16 EXC_SETUP_PRINTNOTES = 0x0020;
+const sal_uInt16 EXC_SETUP_STARTPAGE = 0x0080;
+const sal_uInt16 EXC_SETUP_NOTES_END = 0x0200;
+
+const sal_uInt16 EXC_PAPERSIZE_DEFAULT = 0;
+const sal_uInt16 EXC_PAPERSIZE_USER = 0xFFFF;
+
+// ============================================================================
+
+// Page settings ==============================================================
+
+class SvxBrushItem;
+class SfxPrinter;
+
+/** Contains all page (print) settings for a single sheet. */
+struct XclPageData : private boost::noncopyable
+{
+ typedef ::std::auto_ptr< SvxBrushItem > SvxBrushItemPtr;
+
+ ScfUInt16Vec maHorPageBreaks; /// Horizontal page breaks.
+ ScfUInt16Vec maVerPageBreaks; /// Vertical page breaks.
+ SvxBrushItemPtr mxBrushItem; /// Background bitmap.
+ String maHeader; /// Excel header string (empty = off).
+ String maFooter; /// Excel footer string (empty = off).
+ double mfLeftMargin; /// Left margin in inches.
+ double mfRightMargin; /// Right margin in inches.
+ double mfTopMargin; /// Top margin in inches.
+ double mfBottomMargin; /// Bottom margin in inches.
+ double mfHeaderMargin; /// Margin main page to header.
+ double mfFooterMargin; /// Margin main page to footer.
+ double mfHdrLeftMargin; /// Left margin to header.
+ double mfHdrRightMargin; /// Right margin to header.
+ double mfFtrLeftMargin; /// Left margin to footer.
+ double mfFtrRightMargin; /// Right margin to footer.
+ sal_uInt16 mnPaperSize; /// Index into paper size table.
+ sal_uInt16 mnStrictPaperSize; /// Same as papersize - but for ooxml (considering stricter dimensions)
+ sal_uInt16 mnPaperWidth; /// Paper Width in mm
+ sal_uInt16 mnPaperHeight; /// Paper Height in mm
+ sal_uInt16 mnCopies; /// Number of copies.
+ sal_uInt16 mnStartPage; /// Start page number.
+ sal_uInt16 mnScaling; /// Scaling in percent.
+ sal_uInt16 mnFitToWidth; /// Fit to number of pages in width.
+ sal_uInt16 mnFitToHeight; /// Fit to number of pages in height.
+ sal_uInt16 mnHorPrintRes; /// Horizontal printing resolution.
+ sal_uInt16 mnVerPrintRes; /// Vertical printing resolution.
+ bool mbValid; /// false = some of the values are not valid.
+ bool mbPortrait; /// true = portrait; false = landscape.
+ bool mbPrintInRows; /// true = in rows; false = in columns.
+ bool mbBlackWhite; /// true = black/white; false = colors.
+ bool mbDraftQuality; /// true = draft; false = default quality.
+ bool mbPrintNotes; /// true = print notes.
+ bool mbManualStart; /// true = mnStartPage valid; false = automatic.
+ bool mbFitToPages; /// true = fit to pages; false = scale in percent.
+ bool mbHorCenter; /// true = centered horizontally; false = left aligned.
+ bool mbVerCenter; /// true = centered vertically; false = top aligned.
+ bool mbPrintHeadings; /// true = print column and row headings.
+ bool mbPrintGrid; /// true = print grid lines.
+
+ explicit XclPageData();
+ ~XclPageData();
+
+ /** Sets Excel default page settings. */
+ void SetDefaults();
+
+ /** Returns the real paper size (twips) from the paper size index and paper orientation. */
+ Size GetScPaperSize() const;
+ /** Sets the Excel paper size index and paper orientation from Calc paper size (twips). */
+ void SetScPaperSize( const Size& rSize, bool bPortrait, bool bStrict = false );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx
new file mode 100644
index 000000000000..560e18a19a2b
--- /dev/null
+++ b/sc/source/filter/inc/xlpivot.hxx
@@ -0,0 +1,784 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLPIVOT_HXX
+#define SC_XLPIVOT_HXX
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <tools/datetime.hxx>
+#include "ftools.hxx"
+#include "xladdress.hxx"
+#include "dpobject.hxx"
+
+#include <memory>
+
+class XclImpStream;
+class XclExpStream;
+
+// Constants and Enumerations =================================================
+
+// misc -----------------------------------------------------------------------
+
+#define EXC_STORAGE_PTCACHE CREATE_STRING( "_SX_DB_CUR" )
+
+// strings
+const sal_uInt16 EXC_PT_NOSTRING = 0xFFFF;
+const sal_uInt16 EXC_PT_MAXSTRLEN = 0xFFFE;
+
+// pivot cache fields
+const size_t EXC_PC_MAXFIELDCOUNT = 0xFFFE;
+const sal_uInt16 EXC_PC_NOFIELD = 0xFFFF;
+const xub_StrLen EXC_PC_MAXSTRLEN = 255;
+
+// pivot cache items
+const size_t EXC_PC_MAXITEMCOUNT = 32500;
+const sal_uInt16 EXC_PC_NOITEM = 0xFFFF;
+
+// pivot table fields
+const sal_uInt16 EXC_PT_MAXFIELDCOUNT = 0xFFFE;
+const sal_uInt16 EXC_PT_MAXROWCOLCOUNT = EXC_PT_MAXFIELDCOUNT;
+const sal_uInt16 EXC_PT_MAXPAGECOUNT = 256;
+const sal_uInt16 EXC_PT_MAXDATACOUNT = 256;
+
+// pivot table items
+const sal_uInt16 EXC_PT_MAXITEMCOUNT = 32500;
+
+const sal_uInt16 EXC_PT_AUTOFMT_HEADER = 0x810;
+const sal_uInt16 EXC_PT_AUTOFMT_ZERO = 0;
+const sal_uInt32 EXC_PT_AUTOFMT_FLAGS = 0x20;
+
+/** Data type of a pivot cache item. */
+enum XclPCItemType
+{
+ EXC_PCITEM_INVALID, /// Special state, not used in Excel files.
+ EXC_PCITEM_EMPTY, /// Empty cell.
+ EXC_PCITEM_TEXT, /// String data.
+ EXC_PCITEM_DOUBLE, /// Floating-point value.
+ EXC_PCITEM_DATETIME, /// Date/time.
+ EXC_PCITEM_INTEGER, /// 16-bit integer value.
+ EXC_PCITEM_BOOL, /// Boolean value.
+ EXC_PCITEM_ERROR /// Error code.
+};
+
+/** Specifies the type of a pivot cache field. */
+enum XclPCFieldType
+{
+ EXC_PCFIELD_STANDARD, /// Standard field without grouping.
+ EXC_PCFIELD_STDGROUP, /// Standard grouping field.
+ EXC_PCFIELD_NUMGROUP, /// Numeric grouping field.
+ EXC_PCFIELD_DATEGROUP, /// First date grouping field (opt. with child grouping field).
+ EXC_PCFIELD_DATECHILD, /// Additional date grouping field.
+ EXC_PCFIELD_CALCED, /// Calculated field.
+ EXC_PCFIELD_UNKNOWN /// Unknown field state, handled like standard field.
+};
+
+// (0x0051,0x0052) DCONREF, DCONNAME ------------------------------------------
+
+const sal_uInt16 EXC_ID_DCONREF = 0x0051;
+const sal_uInt16 EXC_ID_DCONNAME = 0x0052;
+
+// (0x00B0) SXVIEW ------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SXVIEW = 0x00B0;
+
+const sal_uInt16 EXC_SXVIEW_ROWGRAND = 0x0001;
+const sal_uInt16 EXC_SXVIEW_COLGRAND = 0x0002;
+const sal_uInt16 EXC_SXVIEW_DEFAULTFLAGS = 0x0208;
+
+const sal_uInt16 EXC_SXVIEW_DATALAST = 0xFFFF;
+const sal_uInt16 EXC_SXVIEW_AUTOFMT = 0x0001;
+
+// (0x00B1) SXVD --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVD = 0x00B1;
+
+const sal_uInt16 EXC_SXVD_AXIS_NONE = 0x0000;
+const sal_uInt16 EXC_SXVD_AXIS_ROW = 0x0001;
+const sal_uInt16 EXC_SXVD_AXIS_COL = 0x0002;
+const sal_uInt16 EXC_SXVD_AXIS_PAGE = 0x0004;
+const sal_uInt16 EXC_SXVD_AXIS_DATA = 0x0008;
+const sal_uInt16 EXC_SXVD_AXIS_ROWCOL = EXC_SXVD_AXIS_ROW | EXC_SXVD_AXIS_COL;
+const sal_uInt16 EXC_SXVD_AXIS_ROWCOLPAGE = EXC_SXVD_AXIS_ROWCOL | EXC_SXVD_AXIS_PAGE;
+
+const sal_uInt16 EXC_SXVD_SUBT_NONE = 0x0000;
+const sal_uInt16 EXC_SXVD_SUBT_DEFAULT = 0x0001;
+const sal_uInt16 EXC_SXVD_SUBT_SUM = 0x0002;
+const sal_uInt16 EXC_SXVD_SUBT_COUNT = 0x0004;
+const sal_uInt16 EXC_SXVD_SUBT_AVERAGE = 0x0008;
+const sal_uInt16 EXC_SXVD_SUBT_MAX = 0x0010;
+const sal_uInt16 EXC_SXVD_SUBT_MIN = 0x0020;
+const sal_uInt16 EXC_SXVD_SUBT_PROD = 0x0040;
+const sal_uInt16 EXC_SXVD_SUBT_COUNTNUM = 0x0080;
+const sal_uInt16 EXC_SXVD_SUBT_STDDEV = 0x0100;
+const sal_uInt16 EXC_SXVD_SUBT_STDDEVP = 0x0200;
+const sal_uInt16 EXC_SXVD_SUBT_VAR = 0x0400;
+const sal_uInt16 EXC_SXVD_SUBT_VARP = 0x0800;
+
+const sal_uInt16 EXC_SXVD_DEFAULT_CACHE = EXC_PC_NOFIELD;
+
+// (0x00B2) SXVI --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVI = 0x00B2;
+
+const sal_uInt16 EXC_SXVI_TYPE_PAGE = 0x00FE;
+const sal_uInt16 EXC_SXVI_TYPE_NULL = 0x00FF;
+const sal_uInt16 EXC_SXVI_TYPE_DATA = 0x0000;
+const sal_uInt16 EXC_SXVI_TYPE_DEFAULT = 0x0001;
+const sal_uInt16 EXC_SXVI_TYPE_SUM = 0x0002;
+const sal_uInt16 EXC_SXVI_TYPE_COUNT = 0x0003;
+const sal_uInt16 EXC_SXVI_TYPE_AVERAGE = 0x0004;
+const sal_uInt16 EXC_SXVI_TYPE_MAX = 0x0005;
+const sal_uInt16 EXC_SXVI_TYPE_MIN = 0x0006;
+const sal_uInt16 EXC_SXVI_TYPE_PROD = 0x0007;
+const sal_uInt16 EXC_SXVI_TYPE_COUNTNUM = 0x0008;
+const sal_uInt16 EXC_SXVI_TYPE_STDDEV = 0x0009;
+const sal_uInt16 EXC_SXVI_TYPE_STDDEVP = 0x000A;
+const sal_uInt16 EXC_SXVI_TYPE_VAR = 0x000B;
+const sal_uInt16 EXC_SXVI_TYPE_VARP = 0x000C;
+const sal_uInt16 EXC_SXVI_TYPE_GRAND = 0x000D;
+
+const sal_uInt16 EXC_SXVI_DEFAULTFLAGS = 0x0000;
+const sal_uInt16 EXC_SXVI_HIDDEN = 0x0001;
+const sal_uInt16 EXC_SXVI_HIDEDETAIL = 0x0002;
+const sal_uInt16 EXC_SXVI_FORMULA = 0x0004;
+const sal_uInt16 EXC_SXVI_MISSING = 0x0008;
+
+const sal_uInt16 EXC_SXVI_DEFAULT_CACHE = EXC_PC_NOFIELD;
+
+// (0x00B4) SXIVD -------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXIVD = 0x00B4;
+const sal_uInt16 EXC_SXIVD_DATA = 0xFFFE;
+
+// (0x00B5) SXLI --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXLI = 0x00B5;
+const sal_uInt16 EXC_SXLI_DEFAULTFLAGS = 0x0000;
+
+// (0x00B6) SXPI --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXPI = 0x00B6;
+const sal_uInt16 EXC_SXPI_ALLITEMS = 0x7FFD;
+
+// (0x00C5) SXDI --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXDI = 0x00C5;
+
+const sal_uInt16 EXC_SXDI_FUNC_SUM = 0x0000;
+const sal_uInt16 EXC_SXDI_FUNC_COUNT = 0x0001;
+const sal_uInt16 EXC_SXDI_FUNC_AVERAGE = 0x0002;
+const sal_uInt16 EXC_SXDI_FUNC_MAX = 0x0003;
+const sal_uInt16 EXC_SXDI_FUNC_MIN = 0x0004;
+const sal_uInt16 EXC_SXDI_FUNC_PRODUCT = 0x0005;
+const sal_uInt16 EXC_SXDI_FUNC_COUNTNUM = 0x0006;
+const sal_uInt16 EXC_SXDI_FUNC_STDDEV = 0x0007;
+const sal_uInt16 EXC_SXDI_FUNC_STDDEVP = 0x0008;
+const sal_uInt16 EXC_SXDI_FUNC_VAR = 0x0009;
+const sal_uInt16 EXC_SXDI_FUNC_VARP = 0x000A;
+
+const sal_uInt16 EXC_SXDI_REF_NORMAL = 0x0000;
+const sal_uInt16 EXC_SXDI_REF_DIFF = 0x0001;
+const sal_uInt16 EXC_SXDI_REF_PERC = 0x0002;
+const sal_uInt16 EXC_SXDI_REF_PERC_DIFF = 0x0003;
+const sal_uInt16 EXC_SXDI_REF_RUN_TOTAL = 0x0004;
+const sal_uInt16 EXC_SXDI_REF_PERC_ROW = 0x0005;
+const sal_uInt16 EXC_SXDI_REF_PERC_COL = 0x0006;
+const sal_uInt16 EXC_SXDI_REF_PERC_TOTAL = 0x0007;
+const sal_uInt16 EXC_SXDI_REF_INDEX = 0x0008;
+
+const sal_uInt16 EXC_SXDI_PREVITEM = 0x7FFB;
+const sal_uInt16 EXC_SXDI_NEXTITEM = 0x7FFC;
+
+// (0x00C6) SXDB --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXDB = 0x00C6;
+
+const sal_uInt16 EXC_SXDB_SAVEDATA = 0x0001;
+const sal_uInt16 EXC_SXDB_INVALID = 0x0002;
+const sal_uInt16 EXC_SXDB_REFRESH_LOAD = 0x0004;
+const sal_uInt16 EXC_SXDB_OPT_CACHE = 0x0008;
+const sal_uInt16 EXC_SXDB_BG_QUERY = 0x0010;
+const sal_uInt16 EXC_SXDB_ENABLE_REFRESH = 0x0020;
+const sal_uInt16 EXC_SXDB_DEFAULTFLAGS = EXC_SXDB_SAVEDATA | EXC_SXDB_ENABLE_REFRESH;
+
+const sal_uInt16 EXC_SXDB_BLOCKRECS = 0x1FFF;
+
+const sal_uInt16 EXC_SXDB_SRC_SHEET = 0x0001;
+const sal_uInt16 EXC_SXDB_SRC_EXTERN = 0x0002;
+const sal_uInt16 EXC_SXDB_SRC_CONSOLID = 0x0004;
+const sal_uInt16 EXC_SXDB_SRC_SCENARIO = 0x0008;
+
+// (0x00C7) SXFIELD -----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXFIELD = 0x00C7;
+
+const sal_uInt16 EXC_SXFIELD_HASITEMS = 0x0001;
+const sal_uInt16 EXC_SXFIELD_POSTPONE = 0x0002;
+const sal_uInt16 EXC_SXFIELD_CALCED = 0x0004;
+const sal_uInt16 EXC_SXFIELD_HASCHILD = 0x0008;
+const sal_uInt16 EXC_SXFIELD_NUMGROUP = 0x0010;
+const sal_uInt16 EXC_SXFIELD_16BIT = 0x0200;
+
+const sal_uInt16 EXC_SXFIELD_DATA_MASK = 0x0DE0;
+// known data types
+const sal_uInt16 EXC_SXFIELD_DATA_NONE = 0x0000; /// Special state for groupings.
+const sal_uInt16 EXC_SXFIELD_DATA_STR = 0x0480; /// Only strings, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_INT = 0x0520; /// Only integers, opt. with doubles.
+const sal_uInt16 EXC_SXFIELD_DATA_DBL = 0x0560; /// Only doubles, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_STR_INT = 0x05A0; /// Only strings and integers, opt. with doubles.
+const sal_uInt16 EXC_SXFIELD_DATA_STR_DBL = 0x05E0; /// Only strings and doubles, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE = 0x0900; /// Only dates, nothing else.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_EMP = 0x0980; /// Dates and empty strings, nothing else (?).
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_NUM = 0x0D00; /// Dates with integers or doubles without strings.
+const sal_uInt16 EXC_SXFIELD_DATA_DATE_STR = 0x0D80; /// Dates and strings, opt. with integers or doubles.
+
+const sal_uInt16 EXC_SXFIELD_INDEX_MIN = 0; /// List index for minimum item in groupings.
+const sal_uInt16 EXC_SXFIELD_INDEX_MAX = 1; /// List index for maximum item in groupings.
+const sal_uInt16 EXC_SXFIELD_INDEX_STEP = 2; /// List index for step item in groupings.
+
+// (0x00C8) SXINDEXLIST -------------------------------------------------------
+const sal_uInt16 EXC_ID_SXINDEXLIST = 0x00C8;
+
+// (0x00C9) SXDOUBLE ----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXDOUBLE = 0x00C9;
+
+// (0x00CA) SXBOOLEAN ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXBOOLEAN = 0x00CA;
+
+// (0x00CB) SXERROR -----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXERROR = 0x00CB;
+
+// (0x00CC) SXINTEGER ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXINTEGER = 0x00CC;
+
+// (0x00CD) SXSTRING ----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXSTRING = 0x00CD;
+
+// (0x00CE) SXDATETIME --------------------------------------------------------
+const sal_uInt16 EXC_ID_SXDATETIME = 0x00CE;
+
+// (0x00CF) SXEMPTY -----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXEMPTY = 0x00CF;
+
+// (0x00D5) SXIDSTM -----------------------------------------------------------
+const sal_uInt16 EXC_ID_SXIDSTM = 0x00D5;
+
+// (0x00D8) SXNUMGROUP --------------------------------------------------------
+const sal_uInt16 EXC_ID_SXNUMGROUP = 0x00D8;
+
+const sal_uInt16 EXC_SXNUMGROUP_AUTOMIN = 0x0001;
+const sal_uInt16 EXC_SXNUMGROUP_AUTOMAX = 0x0002;
+
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_SEC = 1;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_MIN = 2;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_HOUR = 3;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_DAY = 4;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_MONTH = 5;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_QUART = 6;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_YEAR = 7;
+const sal_uInt16 EXC_SXNUMGROUP_TYPE_NUM = 8;
+
+// (0x00D9) SXGROUPINFO -------------------------------------------------------
+const sal_uInt16 EXC_ID_SXGROUPINFO = 0x00D9;
+
+// (0x00DC) SXEXT -------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXEXT = 0x00DC;
+
+// (0x00E3) SXVS --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVS = 0x00E3;
+
+const sal_uInt16 EXC_SXVS_UNKNOWN = 0x0000;
+const sal_uInt16 EXC_SXVS_SHEET = 0x0001;
+const sal_uInt16 EXC_SXVS_EXTERN = 0x0002;
+const sal_uInt16 EXC_SXVS_CONSOLID = 0x0004;
+const sal_uInt16 EXC_SXVS_PIVOTTAB = 0x0008;
+const sal_uInt16 EXC_SXVS_SCENARIO = 0x0010;
+
+// (0x00F0) SXRULE ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXRULE = 0x00F0;
+
+// (0x00F1) SXEX --------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXEX = 0x00F1;
+
+const sal_uInt32 EXC_SXEX_DRILLDOWN = 0x00020000;
+const sal_uInt32 EXC_SXEX_DEFAULTFLAGS = 0x004F0200;
+
+// (0x00F2) SXFILT ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXFILT = 0x00F2;
+
+// (0x00F5) -------------------------------------------------------------------
+const sal_uInt16 EXC_ID_00F5 = 0x00F5; /// Unknown record
+
+// (0x00F6) SXNAME ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXNAME = 0x00F6;
+
+// (0x00F8) SXPAIR ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXPAIR = 0x00F8;
+
+// (0x00F9) SXFMLA ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXFMLA = 0x00F9;
+
+// (0x0100) SXVDEX ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVDEX = 0x0100;
+
+const sal_uInt32 EXC_SXVDEX_SHOWALL = 0x00000001;
+const sal_uInt32 EXC_SXVDEX_SORT = 0x00000200;
+const sal_uInt32 EXC_SXVDEX_SORT_ASC = 0x00000400;
+const sal_uInt32 EXC_SXVDEX_AUTOSHOW = 0x00000800;
+const sal_uInt32 EXC_SXVDEX_AUTOSHOW_ASC = 0x00001000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_REPORT = 0x00200000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_BLANK = 0x00400000;
+const sal_uInt32 EXC_SXVDEX_LAYOUT_TOP = 0x00800000;
+const sal_uInt32 EXC_SXVDEX_DEFAULTFLAGS = 0x0A00001E | EXC_SXVDEX_SORT_ASC | EXC_SXVDEX_AUTOSHOW_ASC;
+
+const sal_uInt16 EXC_SXVDEX_SORT_OWN = 0xFFFF;
+const sal_uInt16 EXC_SXVDEX_SHOW_NONE = 0xFFFF;
+const sal_uInt16 EXC_SXVDEX_FORMAT_NONE = 0x0000;
+
+// (0x0103) SXFORMULA ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXFORMULA = 0x0103;
+
+// (0x0122) SXDBEX ------------------------------------------------------------
+const sal_uInt16 EXC_ID_SXDBEX = 0x0122;
+const double EXC_SXDBEX_CREATION_DATE = 51901.029652778;
+
+// (0x01BB) SXFDBTYPE ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXFDBTYPE = 0x01BB;
+const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000;
+
+// (0x0810) SXVIEWEX9 ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810;
+
+// ============================================================================
+// Pivot cache
+// ============================================================================
+
+/** Represents a data item of any type in a pivot cache. Supposed as base class for import and export. */
+class XclPCItem
+{
+public:
+ explicit XclPCItem();
+ virtual ~XclPCItem();
+
+ /** Sets the item to 'empty' type. */
+ void SetEmpty();
+ /** Sets the item to 'text' type and adds the passed text. */
+ void SetText( const String& rText );
+ /** Sets the item to 'double' type and adds the passed value. */
+ void SetDouble( double fValue );
+ /** Sets the item to 'date/time' type and adds the passed date. */
+ void SetDateTime( const DateTime& rDateTime );
+ /** Sets the item to 'integer' type and adds the passed value. */
+ void SetInteger( sal_Int16 nValue );
+ /** Sets the item to 'error' type and adds the passed Excel error code. */
+ void SetError( sal_uInt16 nError );
+ /** Sets the item to 'boolean' type and adds the passed Boolean value. */
+ void SetBool( bool bValue );
+
+ /** Returns the current item type. */
+ inline XclPCItemType GetType() const { return meType; }
+ /** Returns the text representation of the item. */
+ inline const String& ConvertToText() const { return maText; }
+
+ /** Returns true, if the passed iterm equals this item. */
+ bool IsEqual( const XclPCItem& rItem ) const;
+
+ /** Returns true, if the item type is 'empty'. */
+ bool IsEmpty() const;
+ /** Returns pointer to text, if the item type is 'text', otherwise 0. */
+ const String* GetText() const;
+ /** Returns pointer to value, if the item type is 'double', otherwise 0. */
+ const double* GetDouble() const;
+ /** Returns pointer to date, if the item type is 'date/time', otherwise 0. */
+ const DateTime* GetDateTime() const;
+ /** Returns pointer to integer, if the item type is 'integer', otherwise 0. */
+ const sal_Int16* GetInteger() const;
+ /** Returns pointer to error code, if the item type is 'error', otherwise 0. */
+ const sal_uInt16* GetError() const;
+ /** Returns pointer to Boolean value, if the item type is 'boolean', otherwise 0. */
+ const bool* GetBool() const;
+
+private:
+ XclPCItemType meType; /// Type of the item.
+ String maText; /// Text representation of the item.
+ DateTime maDateTime; /// Value of a date/time item.
+ union
+ {
+ double mfValue; /// Value of a floating-point item.
+ sal_Int16 mnValue; /// Value of an integer item.
+ sal_uInt16 mnError; /// Error code of an error item.
+ bool mbValue; /// Value of a boolean item.
+ };
+};
+
+inline bool operator==( const XclPCItem& rLeft, const XclPCItem& rRight ) { return rLeft.IsEqual( rRight ); }
+inline bool operator!=( const XclPCItem& rLeft, const XclPCItem& rRight ) { return !(rLeft == rRight); }
+
+// Field settings =============================================================
+
+/** Contains data for a pivot cache field (SXFIELD record). */
+struct XclPCFieldInfo
+{
+ String maName; /// Name of the pivot cache field.
+ sal_uInt16 mnFlags; /// Various flags.
+ sal_uInt16 mnGroupChild; /// Field containing grouping info for this field.
+ sal_uInt16 mnGroupBase; /// Base field if this field contains grouping info.
+ sal_uInt16 mnVisItems; /// Number of visible items for this field.
+ sal_uInt16 mnGroupItems; /// Number of special items in a grouping field.
+ sal_uInt16 mnBaseItems; /// Number of items in the base field.
+ sal_uInt16 mnOrigItems; /// Number of original source data items.
+
+ explicit XclPCFieldInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo );
+
+// Numeric grouping field settings ============================================
+
+/** Contains data for a numeric grouping field (SXNUMGROUP record). */
+struct XclPCNumGroupInfo
+{
+ sal_uInt16 mnFlags; /// Various flags.
+
+ explicit XclPCNumGroupInfo();
+
+ void SetNumType();
+
+ sal_Int32 GetScDateType() const;
+ void SetScDateType( sal_Int32 nScType );
+
+ sal_uInt16 GetXclDataType() const;
+ void SetXclDataType( sal_uInt16 nXclType );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo );
+
+// Base class for pivot cache fields ==========================================
+
+/** Represents a field in a pivot cache. Supposed as base class for import and export. */
+class XclPCField
+{
+public:
+ explicit XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx );
+ virtual ~XclPCField();
+
+ /** Returns the index of this field in the containing pivot cache. */
+ inline sal_uInt16 GetFieldIndex() const { return mnFieldIdx; }
+
+ /** Returns true, if the type of the field is supported by Calc. */
+ bool IsSupportedField() const;
+
+ /** Returns true, if this is a standard field build directly from source data. */
+ bool IsStandardField() const;
+
+ /** Returns true, if this field is a grouping field. */
+ bool IsStdGroupField() const;
+ /** Returns true, if this field is a numeric grouping field. */
+ bool IsNumGroupField() const;
+ /** Returns true, if this field is a date/time grouping field. */
+ bool IsDateGroupField() const;
+ /** Returns true, if this field is a grouping field of any type. */
+ bool IsGroupField() const;
+
+ /** Returns true, if this field has a child field in a grouping. */
+ bool IsGroupBaseField() const;
+ /** Returns true, if this field is a child field in a grouping (it has a base field). */
+ bool IsGroupChildField() const;
+ /** Returns the index of the base field, if exists, otherwise the own index. */
+ sal_uInt16 GetBaseFieldIndex() const;
+
+ /** Returns true, if the field is based on a column in the source data area. */
+ bool HasOrigItems() const;
+ /** Returns true, if any items are stored after the SXFIELD record. */
+ bool HasInlineItems() const;
+ /** Returns true, if the items are stored separately after the last field. */
+ bool HasPostponedItems() const;
+ /** Returns true, if the item indexes in the SXINDEXLIST record are stored as 16-bit values. */
+ bool Has16BitIndexes() const;
+
+protected:
+ XclPCFieldInfo maFieldInfo; /// Pivot cache field info (SXFIELD record).
+ XclPCFieldType meFieldType; /// Type of this pivot cache field.
+ sal_uInt16 mnFieldIdx; /// Own field index in pivot cache.
+ ScfUInt16Vec maGroupOrder; /// Order of items in a grouping field (SXGROUPINFO record).
+ XclPCNumGroupInfo maNumGroupInfo; /// Info for numeric grouping (SXNUMGROUP record).
+};
+
+// Pivot cache settings =======================================================
+
+/** Contains data for a pivot cache (SXDB record). */
+struct XclPCInfo
+{
+ sal_uInt32 mnSrcRecs; /// Records in source database.
+ sal_uInt16 mnStrmId; /// Stream identifier.
+ sal_uInt16 mnFlags; /// Flags for the cache.
+ sal_uInt16 mnBlockRecs; /// Records in a source database block.
+ sal_uInt16 mnStdFields; /// Number of standard pivot cache fields.
+ sal_uInt16 mnTotalFields; /// Number of all fields (standard, grouped, calculated).
+ sal_uInt16 mnSrcType; /// Database type.
+ String maUserName; /// Name of user who last modified the cache.
+
+ explicit XclPCInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo );
+
+// ============================================================================
+// Pivot table
+// ============================================================================
+
+// cached name ================================================================
+
+/** A name for various pivot table info structs. Includes 'use cache' state. */
+struct XclPTCachedName
+{
+ String maName; /// The visible name, if used.
+ bool mbUseCache; /// true = Use name in cache instead of maName.
+
+ inline explicit XclPTCachedName() : mbUseCache( true ) {}
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName );
+
+// ----------------------------------------------------------------------------
+
+/** Base struct for named info structs. Supports explicit naming and using the cache. */
+struct XclPTVisNameInfo
+{
+ XclPTCachedName maVisName; /// The displayed name of the item.
+
+ /** Returns true, if the name is set explicitly (maVisName.mbUseCache is false). */
+ inline bool HasVisName() const { return !maVisName.mbUseCache; }
+ /** Returns the name, if set explicitly (maVisName.mbUseCache is false). */
+ const String* GetVisName() const;
+ /** Sets the visible name and enables usage of cache if name is empty. */
+ void SetVisName( const String& rName );
+};
+
+// Field item settings ========================================================
+
+/** Contains data for a pivot table data item (SXVI record). */
+struct XclPTItemInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnType; /// Type of the item (e.g. data, function, grand total).
+ sal_uInt16 mnFlags; /// Several flags.
+ sal_uInt16 mnCacheIdx; /// Index into cache for item name.
+
+ explicit XclPTItemInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo );
+
+// General field settings =====================================================
+
+typedef ::std::vector< sal_uInt16 > XclPTSubtotalVec;
+
+/** Contains data for a pivot table field (SXVD record). */
+struct XclPTFieldInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnAxes; /// Flags for axes this field is part of.
+ sal_uInt16 mnSubtCount; /// Number of subtotal functions.
+ sal_uInt16 mnSubtotals; /// Bitfield for subtotal functions.
+ sal_uInt16 mnItemCount; /// Number of items of this field.
+ sal_uInt16 mnCacheIdx; /// Index into cache for field name (not part of record).
+
+ explicit XclPTFieldInfo();
+
+ /** Returns the API enum representing the orientation (first of row/col/page/data).
+ @param nMask Restricts the axes taken into account.
+ @return The first found axis orientation, that is allowed in nMask parameter. */
+ ::com::sun::star::sheet::DataPilotFieldOrientation GetApiOrient( sal_uInt16 nMask ) const;
+ /** Adds the axis orientation represented by the passed API enum. */
+ void AddApiOrient( ::com::sun::star::sheet::DataPilotFieldOrientation eOrient );
+
+ /** Returns a vector of all set subtotal functions. */
+ void GetSubtotals( XclPTSubtotalVec& rSubtotals ) const;
+ /** Sets the subtotal functions contained in the passed sequence. */
+ void SetSubtotals( const XclPTSubtotalVec& rSubtotals );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo );
+
+// Extended field settings ====================================================
+
+/** Contains extended data for a pivot table field (SXVDEX record). */
+struct XclPTFieldExtInfo
+{
+ sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow.
+ sal_uInt16 mnSortField; /// Index to data field sorting bases on.
+ sal_uInt16 mnShowField; /// Index to data field AutoShow bases on.
+ sal_uInt16 mnNumFmt;
+ ::std::auto_ptr<rtl::OUString> mpFieldTotalName;
+
+ explicit XclPTFieldExtInfo();
+
+ /** Returns the API constant representing the sorting mode. */
+ sal_Int32 GetApiSortMode() const;
+ /** Sets the sorting mode represented by the passed API constant. */
+ void SetApiSortMode( sal_Int32 nSortMode );
+
+ /** Returns the API constant representing the AutoShow mode. */
+ sal_Int32 GetApiAutoShowMode() const;
+ /** Sets the AutoShow mode represented by the passed API constant. */
+ void SetApiAutoShowMode( sal_Int32 nShowMode );
+
+ /** Returns the number of items to be shown in AutoShow mode. */
+ sal_Int32 GetApiAutoShowCount() const;
+ /** Sets the number of items to be shown in AutoShow mode. */
+ void SetApiAutoShowCount( sal_Int32 nShowCount );
+
+ /** Returns the API constant representing the layout mode. */
+ sal_Int32 GetApiLayoutMode() const;
+ /** Sets the layout mode represented by the passed API constant. */
+ void SetApiLayoutMode( sal_Int32 nLayoutMode );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo );
+
+// Page field settings ========================================================
+
+/** Contains data for a pivot table page field (part of SXPI record). */
+struct XclPTPageFieldInfo
+{
+ sal_uInt16 mnField; /// Base field for this page info.
+ sal_uInt16 mnSelItem; /// Index to selected item.
+ sal_uInt16 mnObjId; /// Escher object ID of dropdown listbox.
+
+ explicit XclPTPageFieldInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo );
+
+// Data field settings ========================================================
+
+/** Contains data for a pivot table data field (SXDI record). */
+struct XclPTDataFieldInfo : public XclPTVisNameInfo
+{
+ sal_uInt16 mnField; /// Base field for this data info.
+ sal_uInt16 mnAggFunc; /// Data aggregation function.
+ sal_uInt16 mnRefType; /// Result reference type.
+ sal_uInt16 mnRefField; /// Index to SXVD of referred field used for the results.
+ sal_uInt16 mnRefItem; /// Index to SXVI of referred item of the used field.
+ sal_uInt16 mnNumFmt; /// Number format of the results.
+
+ explicit XclPTDataFieldInfo();
+
+ /** Returns the API enum representing the aggregation function. */
+ ::com::sun::star::sheet::GeneralFunction GetApiAggFunc() const;
+ /** Sets the aggregation function represented by the passed API enum. */
+ void SetApiAggFunc( ::com::sun::star::sheet::GeneralFunction eAggFunc );
+
+ /** Returns the API constant representing the result reference type. */
+ sal_Int32 GetApiRefType() const;
+ /** Sets the result reference type represented by the passed API constant. */
+ void SetApiRefType( sal_Int32 nRefType );
+
+ /** Returns the API constant representing the result reference item type. */
+ sal_Int32 GetApiRefItemType() const;
+ /** Sets the result reference item type represented by the passed API constant. */
+ void SetApiRefItemType( sal_Int32 nRefItemType );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo );
+
+// Pivot table settings =======================================================
+
+/** Contains data for a pivot table (SXVIEW record). */
+struct XclPTInfo
+{
+ String maTableName; /// The name of the pivot table.
+ String maDataName; /// The visible name of the data field.
+ XclRange maOutXclRange; /// Output range.
+ XclAddress maDataXclPos; /// First cell containing data.
+ sal_uInt16 mnFirstHeadRow; /// First heading row.
+ sal_uInt16 mnCacheIdx; /// 0-based index of the pivot cache.
+ sal_uInt16 mnDataAxis; /// Orientation of data fields.
+ sal_uInt16 mnDataPos; /// Position of data fields.
+ sal_uInt16 mnFields; /// Number of all fields.
+ sal_uInt16 mnRowFields; /// Number of row fields.
+ sal_uInt16 mnColFields; /// Number of column fields.
+ sal_uInt16 mnPageFields; /// Number of page fields.
+ sal_uInt16 mnDataFields; /// Number of data fields.
+ sal_uInt16 mnDataRows; /// Number of rows containing data.
+ sal_uInt16 mnDataCols; /// Number of columns containing data.
+ sal_uInt16 mnFlags; /// Flags for the entire pivot table.
+ sal_uInt16 mnAutoFmtIdx; /// Index to pivot table autoformat.
+
+ explicit XclPTInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo );
+
+// Extended pivot table settings ==============================================
+
+/** Extended information about a pivot table (SXEX record). */
+struct XclPTExtInfo
+{
+ sal_uInt16 mnSxformulaRecs; /// Number of SXFORMULA records.
+ sal_uInt16 mnSxselectRecs; /// Number of SXSELECT records.
+ sal_uInt16 mnPagePerRow; /// Number of page fields per row.
+ sal_uInt16 mnPagePerCol; /// Number of page fields per column.
+ sal_uInt32 mnFlags; /// Flags for the entire pivot table.
+
+ explicit XclPTExtInfo();
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo );
+
+// ============================================================================
+
+// Pivot table autoformat settings ==============================================
+
+/** Pivot table autoformat settings (SXVIEWEX9 record). */
+struct XclPTViewEx9Info
+{
+ sal_uInt32 mbReport; /// 2 for report* fmts ?
+ sal_uInt8 mnAutoFormat; /// AutoFormat ID
+ sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern
+ String maGrandTotalName;
+
+ explicit XclPTViewEx9Info();
+ void Init( const ScDPObject& rDPObj );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo );
+
+// ============================================================================
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx
new file mode 100644
index 000000000000..53d9535c87b7
--- /dev/null
+++ b/sc/source/filter/inc/xlroot.hxx
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLROOT_HXX
+#define SC_XLROOT_HXX
+
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <i18npool/lang.h>
+#include <sot/storage.hxx>
+#include "xlconst.hxx"
+#include "xltools.hxx"
+#include <boost/shared_ptr.hpp>
+
+namespace comphelper { class IDocPasswordVerifier; }
+
+// Forward declarations of objects in public use ==============================
+
+class DateTime;
+
+struct XclAddress;
+struct XclRange;
+class XclRangeList;
+class XclTokenArray;
+
+// Global data ================================================================
+
+#ifdef DBG_UTIL
+/** Counts the number of created root objects. */
+struct XclDebugObjCounter
+{
+ sal_Int32 mnObjCnt;
+ inline explicit XclDebugObjCounter() : mnObjCnt( 0 ) {}
+ ~XclDebugObjCounter();
+};
+#endif
+
+// ----------------------------------------------------------------------------
+
+class SfxMedium;
+class ScEditEngineDefaulter;
+class ScHeaderEditEngine;
+class EditEngine;
+class ScExtDocOptions;
+class XclFontPropSetHelper;
+class XclChPropSetHelper;
+class XclTracer;
+
+struct RootData;//!
+
+/** Stores global buffers and data needed elsewhere in the Excel filters. */
+struct XclRootData
+#ifdef DBG_UTIL
+ : public XclDebugObjCounter
+#endif
+{
+ typedef boost::shared_ptr< ScEditEngineDefaulter > ScEEDefaulterRef;
+ typedef boost::shared_ptr< ScHeaderEditEngine > ScHeaderEERef;
+ typedef boost::shared_ptr< EditEngine > EditEngineRef;
+ typedef boost::shared_ptr< XclFontPropSetHelper > XclFontPropSetHlpRef;
+ typedef boost::shared_ptr< XclChPropSetHelper > XclChPropSetHlpRef;
+ typedef boost::shared_ptr< ScExtDocOptions > ScExtDocOptRef;
+ typedef boost::shared_ptr< XclTracer > XclTracerRef;
+ typedef boost::shared_ptr< RootData > RootDataRef;
+
+ XclBiff meBiff; /// Current BIFF version.
+ XclOutput meOutput; /// Current Output format.
+ SfxMedium& mrMedium; /// The medium to import from.
+ SotStorageRef mxRootStrg; /// The root OLE storage of imported/exported file.
+ ScDocument& mrDoc; /// The source or destination document.
+ String maDocUrl; /// Document URL of imported/exported file.
+ String maBasePath; /// Base path of imported/exported file (path of maDocUrl).
+ String maUserName; /// Current user name.
+ const String maDefPassword; /// The default password used for stream encryption.
+ rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings.
+ LanguageType meSysLang; /// System language.
+ LanguageType meDocLang; /// Document language (import: from file, export: from system).
+ LanguageType meUILang; /// UI language (import: from file, export: from system).
+ sal_Int16 mnDefApiScript; /// Default script type for blank cells (API constant).
+ ScAddress maScMaxPos; /// Highest Calc cell position.
+ ScAddress maXclMaxPos; /// Highest Excel cell position.
+ ScAddress maMaxPos; /// Highest position valid in Calc and Excel.
+
+ ScEEDefaulterRef mxEditEngine; /// Edit engine for rich strings etc.
+ ScHeaderEERef mxHFEditEngine; /// Edit engine for header/footer.
+ EditEngineRef mxDrawEditEng; /// Edit engine for text boxes.
+
+ XclFontPropSetHlpRef mxFontPropSetHlp; /// Property set helper for fonts.
+ XclChPropSetHlpRef mxChPropSetHlp; /// Property set helper for chart filter.
+
+ ScExtDocOptRef mxExtDocOpt; /// Extended document options.
+ XclTracerRef mxTracer; /// Filter tracer.
+ RootDataRef mxRD; /// Old RootData struct. Will be removed.
+
+ double mfScreenPixelX; /// Width of a screen pixel (1/100 mm).
+ double mfScreenPixelY; /// Height of a screen pixel (1/100 mm).
+ long mnCharWidth; /// Width of '0' in default font (twips).
+ SCTAB mnScTab; /// Current Calc sheet index.
+ const bool mbExport; /// false = Import, true = Export.
+
+ explicit XclRootData( XclBiff eBiff, SfxMedium& rMedium,
+ SotStorageRef xRootStrg, ScDocument& rDoc,
+ rtl_TextEncoding eTextEnc, bool bExport );
+ virtual ~XclRootData();
+};
+
+// ----------------------------------------------------------------------------
+
+class SfxObjectShell;
+class ScModelObj;
+class OutputDevice;
+class SvNumberFormatter;
+class SdrPage;
+class ScDocumentPool;
+class ScStyleSheetPool;
+class ScRangeName;
+class ScDBCollection;
+struct XclFontData;
+
+/** Access to global data for a filter object (imported or exported document) from other classes. */
+class XclRoot
+{
+public:
+ explicit XclRoot( XclRootData& rRootData );
+ XclRoot( const XclRoot& rRoot );
+
+ virtual ~XclRoot();
+
+ XclRoot& operator=( const XclRoot& rRoot );
+
+ /** Returns this root instance - for code readability in derived classes. */
+ inline const XclRoot& GetRoot() const { return *this; }
+ /** Returns old RootData struct. Deprecated. */
+ inline RootData& GetOldRoot() const { return *mrData.mxRD; }
+
+ /** Returns the current BIFF version of the importer/exporter. */
+ inline XclBiff GetBiff() const { return mrData.meBiff; }
+ /** Returns the current output format of the importer/exporter. */
+ inline XclOutput GetOutput() const { return mrData.meOutput; }
+ /** Returns true, if currently a document is imported. */
+ inline bool IsImport() const { return !mrData.mbExport; }
+ /** Returns true, if currently a document is exported. */
+ inline bool IsExport() const { return mrData.mbExport; }
+ /** Returns the text encoding to import/export byte strings. */
+ inline rtl_TextEncoding GetTextEncoding() const { return mrData.meTextEnc; }
+ /** Returns the system language, i.e. for number formats. */
+ inline LanguageType GetSysLanguage() const { return mrData.meSysLang; }
+ /** Returns the document language. */
+ inline LanguageType GetDocLanguage() const { return mrData.meDocLang; }
+ /** Returns the UI language. */
+ inline LanguageType GetUILanguage() const { return mrData.meUILang; }
+ /** Returns the default script type, e.g. for blank cells. */
+ inline sal_Int16 GetDefApiScript() const { return mrData.mnDefApiScript; }
+ /** Returns the width of the '0' character (default font) for the current printer (twips). */
+ inline long GetCharWidth() const { return mrData.mnCharWidth; }
+ /** Returns the current Calc sheet index. */
+ inline bool IsInGlobals() const { return mrData.mnScTab == SCTAB_GLOBAL; }
+ /** Returns the current Calc sheet index. */
+ inline SCTAB GetCurrScTab() const { return mrData.mnScTab; }
+
+ /** Calculates the width of the passed number of pixels in 1/100 mm. */
+ sal_Int32 GetHmmFromPixelX( double fPixelX ) const;
+ /** Calculates the height of the passed number of pixels in 1/100 mm. */
+ sal_Int32 GetHmmFromPixelY( double fPixelY ) const;
+
+ double GetPixelXFromHmm( sal_Int32 nX ) const;
+ double GetPixelYFromHmm( sal_Int32 nY ) const;
+
+ /** Returns the medium to import from. */
+ inline SfxMedium& GetMedium() const { return mrData.mrMedium; }
+ /** Returns the document URL of the imported/exported file. */
+ inline const String& GetDocUrl() const { return mrData.maDocUrl; }
+ /** Returns the base path of the imported/exported file. */
+ inline const String& GetBasePath() const { return mrData.maBasePath; }
+ /** Returns the current user name. */
+ inline const String& GetUserName() const { return mrData.maUserName; }
+
+ /** Returns the default password used for stream encryption. */
+ inline const String& GetDefaultPassword() const { return mrData.maDefPassword; }
+ /** Requests and verifies a password from the medium or the user. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
+ RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
+
+ /** Returns the OLE2 root storage of the imported/exported file.
+ @return Pointer to root storage or 0, if the file is a simple stream. */
+ inline SotStorageRef GetRootStorage() const { return mrData.mxRootStrg; }
+ /** Returns true, if the document contains a VBA storage. */
+ bool HasVbaStorage() const;
+
+ /** Tries to open a storage as child of the specified storage for reading or writing. */
+ SotStorageRef OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const;
+ /** Tries to open a storage as child of the root storage for reading or writing. */
+ SotStorageRef OpenStorage( const String& rStrgName ) const;
+ /** Tries to open a new stream in the specified storage for reading or writing. */
+ SotStorageStreamRef OpenStream( SotStorageRef xStrg, const String& rStrmName ) const;
+ /** Tries to open a new stream in the root storage for reading or writing. */
+ SotStorageStreamRef OpenStream( const String& rStrmName ) const;
+
+ /** Returns the destination document (import) or source document (export). */
+ inline ScDocument& GetDoc() const { return mrData.mrDoc; }
+ /** Returns pointer to the destination document (import) or source document (export). */
+ inline ScDocument* GetDocPtr() const { return &mrData.mrDoc; }
+ /** Returns the object shell of the Calc document. May be 0 (i.e. import from clipboard). */
+ SfxObjectShell* GetDocShell() const;
+ /** Returns the object model of the Calc document. */
+ ScModelObj* GetDocModelObj() const;
+ /** Returns pointer to the printer of the Calc document. */
+ OutputDevice* GetPrinter() const;
+ /** Returns the style sheet pool of the Calc document. */
+ ScStyleSheetPool& GetStyleSheetPool() const;
+ /** Returns the defined names container of the Calc document. */
+ ScRangeName& GetNamedRanges() const;
+ /** Returns the database ranges container of the Calc document. */
+ ScDBCollection& GetDatabaseRanges() const;
+ /** Returns the drawing layer page of the passed sheet, if present. */
+ SdrPage* GetSdrPage( SCTAB nScTab ) const;
+
+ /** Returns the number formatter of the Calc document. */
+ SvNumberFormatter& GetFormatter() const;
+ /** Returns the null date of the current number formatter. */
+ DateTime GetNullDate() const;
+ /** Returns the base year depending on the current null date (1900 or 1904). */
+ sal_uInt16 GetBaseYear() const;
+ /** Converts a date/time value to a floating-point value. */
+ double GetDoubleFromDateTime( const DateTime& rDateTime ) const;
+ /** Converts a floating-point value to a date/time value. */
+ DateTime GetDateTimeFromDouble( double fValue ) const;
+
+ /** Returns the edit engine for import/export of rich strings etc. */
+ ScEditEngineDefaulter& GetEditEngine() const;
+ /** Returns the edit engine for import/export of headers/footers. */
+ ScHeaderEditEngine& GetHFEditEngine() const;
+ /** Returns the edit engine for import/export of drawing text boxes. */
+ EditEngine& GetDrawEditEngine() const;
+
+ /** Returns the property set helper for fonts. */
+ XclFontPropSetHelper& GetFontPropSetHelper() const;
+ /** Returns the property set helper for the chart filters. */
+ XclChPropSetHelper& GetChartPropSetHelper() const;
+
+ /** Returns the extended document options. */
+ ScExtDocOptions& GetExtDocOptions() const;
+ /** Returns the filter tracer. */
+ XclTracer& GetTracer() const;
+
+ /** Returns the highest possible cell address in a Calc document. */
+ inline const ScAddress& GetScMaxPos() const { return mrData.maScMaxPos; }
+ /** Returns the highest possible cell address in an Excel document (using current BIFF version). */
+ inline const ScAddress& GetXclMaxPos() const { return mrData.maXclMaxPos; }
+ /** Returns the highest possible cell address valid in Calc and Excel (using current BIFF version). */
+ inline const ScAddress& GetMaxPos() const { return mrData.maMaxPos; }
+
+ /** Sets the document language. */
+ inline void SetDocLanguage( LanguageType eLang ) { mrData.meDocLang = eLang; }
+ /** Sets the UI language, i.e. if it has been read from a file. */
+ inline void SetUILanguage( LanguageType eLang ) { mrData.meUILang = eLang; }
+ /** Sets the text encoding to import/export byte strings. */
+ void SetTextEncoding( rtl_TextEncoding eTextEnc );
+ /** Sets the width of the '0' character (default font) for the current printer (twips).
+ @param rFontData The font used for the '0' character. */
+ void SetCharWidth( const XclFontData& rFontData );
+ /** Sets the current Calc sheet index. */
+ inline void SetCurrScTab( SCTAB nScTab ) { mrData.mnScTab = nScTab; }
+ /** Increases the current Calc sheet index by 1. */
+ inline void IncCurrScTab() { ++mrData.mnScTab; }
+
+private:
+ XclRootData& mrData; /// Reference to the global data struct.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlstream.hxx b/sc/source/filter/inc/xlstream.hxx
new file mode 100644
index 000000000000..e83b1068fc09
--- /dev/null
+++ b/sc/source/filter/inc/xlstream.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTREAM_HXX
+#define SC_XLSTREAM_HXX
+
+#include <tools/stream.hxx>
+#include <svx/svxerr.hxx>
+#include "ftools.hxx"
+
+// Constants ==================================================================
+
+const sal_Size EXC_REC_SEEK_TO_BEGIN = 0;
+const sal_Size EXC_REC_SEEK_TO_END = static_cast< sal_Size >( -1 );
+
+const sal_uInt16 EXC_MAXRECSIZE_BIFF5 = 2080;
+const sal_uInt16 EXC_MAXRECSIZE_BIFF8 = 8224;
+
+const ErrCode EXC_ENCR_ERROR_WRONG_PASS = ERRCODE_SVX_WRONGPASS;
+const ErrCode EXC_ENCR_ERROR_UNSUPP_CRYPT = ERRCODE_SVX_READ_FILTER_CRYPT;
+const sal_uInt16 EXC_ENCR_BLOCKSIZE = 1024;
+
+const sal_uInt16 EXC_ID_UNKNOWN = SAL_MAX_UINT16;
+const sal_uInt16 EXC_ID_CONT = 0x003C;
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlstring.hxx b/sc/source/filter/inc/xlstring.hxx
new file mode 100644
index 000000000000..c431a594ad1a
--- /dev/null
+++ b/sc/source/filter/inc/xlstring.hxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTRING_HXX
+#define SC_XLSTRING_HXX
+
+#include "ftools.hxx"
+
+// Constants and enumerations =================================================
+
+/** Flags used to specify import/export mode of strings. */
+typedef sal_uInt16 XclStrFlags;
+
+const XclStrFlags EXC_STR_DEFAULT = 0x0000; /// Default string settings.
+const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 characters (default: try to compress). BIFF8 only.
+const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
+const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
+const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string.
+const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields.
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 EXC_STR_MAXLEN_8BIT = 0x00FF;
+const sal_uInt16 EXC_STR_MAXLEN = 0x7FFF;
+
+const sal_uInt8 EXC_STRF_16BIT = 0x01;
+const sal_uInt8 EXC_STRF_FAREAST = 0x04;
+const sal_uInt8 EXC_STRF_RICH = 0x08;
+const sal_uInt8 EXC_STRF_UNKNOWN = 0xF2;
+
+// Fixed-size characters
+const sal_uInt8 EXC_LF_C = '\x0A'; /// LF character (used for line break).
+const sal_uInt16 EXC_LF = EXC_LF_C; /// LF character (unicode).
+const sal_uInt8 EXC_NUL_C = '\x00'; /// NUL chararcter.
+const sal_uInt16 EXC_NUL = EXC_NUL_C; /// NUL chararcter (unicode).
+
+// Rich-string formatting runs ================================================
+
+/** Represents a formatting run for rich-strings.
+
+ An Excel formatting run stores the first formatted character in a
+ rich-string and the index of a font used to format this and the following
+ characters.
+ */
+struct XclFormatRun
+{
+ sal_uInt16 mnChar; /// First character this format applies to.
+ sal_uInt16 mnFontIdx; /// Excel font index for the next characters.
+
+ explicit inline XclFormatRun() : mnChar( 0 ), mnFontIdx( 0 ) {}
+ explicit inline XclFormatRun( sal_uInt16 nChar, sal_uInt16 nFontIdx ) :
+ mnChar( nChar ), mnFontIdx( nFontIdx ) {}
+};
+
+inline bool operator==( const XclFormatRun& rLeft, const XclFormatRun& rRight )
+{
+ return (rLeft.mnChar == rRight.mnChar) && (rLeft.mnFontIdx == rRight.mnFontIdx);
+}
+
+inline bool operator<( const XclFormatRun& rLeft, const XclFormatRun& rRight )
+{
+ return (rLeft.mnChar < rRight.mnChar) || ((rLeft.mnChar == rRight.mnChar) && (rLeft.mnFontIdx < rRight.mnFontIdx));
+}
+
+// ----------------------------------------------------------------------------
+
+/** A vector with all formatting runs for a rich-string. */
+typedef ::std::vector< XclFormatRun > XclFormatRunVec;
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlstyle.hxx b/sc/source/filter/inc/xlstyle.hxx
new file mode 100644
index 000000000000..793576339c2f
--- /dev/null
+++ b/sc/source/filter/inc/xlstyle.hxx
@@ -0,0 +1,623 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLSTYLE_HXX
+#define SC_XLSTYLE_HXX
+
+#include <map>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <tools/color.hxx>
+#include <vcl/vclenum.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/frmdir.hxx>
+#include <svl/zforlist.hxx>
+#include "fapihelper.hxx"
+
+class XclRoot;
+
+// Constants and Enumerations =================================================
+
+// Line styles ----------------------------------------------------------------
+
+const sal_uInt8 EXC_LINE_NONE = 0x00;
+const sal_uInt8 EXC_LINE_THIN = 0x01;
+const sal_uInt8 EXC_LINE_MEDIUM = 0x02;
+const sal_uInt8 EXC_LINE_DASHED = 0x03;
+const sal_uInt8 EXC_LINE_DOTTED = 0x04;
+const sal_uInt8 EXC_LINE_THICK = 0x05;
+const sal_uInt8 EXC_LINE_DOUBLE = 0x06;
+const sal_uInt8 EXC_LINE_HAIR = 0x07;
+const sal_uInt8 EXC_LINE_MEDIUMDASHED = 0x08;
+
+// Background patterns --------------------------------------------------------
+
+const sal_uInt8 EXC_PATT_NONE = 0x00;
+const sal_uInt8 EXC_PATT_SOLID = 0x01;
+const sal_uInt8 EXC_PATT_50_PERC = 0x02;
+const sal_uInt8 EXC_PATT_75_PERC = 0x03;
+const sal_uInt8 EXC_PATT_25_PERC = 0x04;
+const sal_uInt8 EXC_PATT_12_5_PERC = 0x11;
+const sal_uInt8 EXC_PATT_6_25_PERC = 0x12;
+
+// (0x001E, 0x041E) FORMAT ----------------------------------------------------
+
+const sal_uInt16 EXC_ID2_FORMAT = 0x001E;
+const sal_uInt16 EXC_ID4_FORMAT = 0x041E;
+
+const sal_uInt16 EXC_FORMAT_OFFSET5 = 164;
+const sal_uInt16 EXC_FORMAT_OFFSET8 = 164;
+const sal_uInt16 EXC_FORMAT_NOTFOUND = 0xFFFF;
+
+// (0x0031) FONT --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID2_FONT = 0x0031;
+const sal_uInt16 EXC_ID3_FONT = 0x0231;
+
+const sal_uInt16 EXC_FONT_APP = 0; /// Application font index.
+const sal_uInt16 EXC_FONT_NOTFOUND = 0xFFFF;
+
+const size_t EXC_FONT_MAXCOUNT4 = 0x00FF;
+const size_t EXC_FONT_MAXCOUNT5 = 0x00FF;
+const size_t EXC_FONT_MAXCOUNT8 = 0xFFFF;
+
+// families
+const sal_uInt8 EXC_FONTFAM_DONTKNOW = 0x00;
+const sal_uInt8 EXC_FONTFAM_ROMAN = 0x01;
+const sal_uInt8 EXC_FONTFAM_SWISS = 0x02;
+const sal_uInt8 EXC_FONTFAM_SYSTEM = EXC_FONTFAM_SWISS;
+const sal_uInt8 EXC_FONTFAM_MODERN = 0x03;
+const sal_uInt8 EXC_FONTFAM_SCRIPT = 0x04;
+const sal_uInt8 EXC_FONTFAM_DECORATIVE = 0x05;
+
+// charsets
+const sal_uInt8 EXC_FONTCSET_ANSI_LATIN = 0x00;
+
+// attributes
+const sal_uInt16 EXC_FONTATTR_NONE = 0x0000;
+const sal_uInt16 EXC_FONTATTR_BOLD = 0x0001;
+const sal_uInt16 EXC_FONTATTR_ITALIC = 0x0002;
+const sal_uInt16 EXC_FONTATTR_UNDERLINE = 0x0004;
+const sal_uInt16 EXC_FONTATTR_STRIKEOUT = 0x0008;
+const sal_uInt16 EXC_FONTATTR_OUTLINE = 0x0010;
+const sal_uInt16 EXC_FONTATTR_SHADOW = 0x0020;
+
+// weight
+const sal_uInt16 EXC_FONTWGHT_DONTKNOW = 0;
+const sal_uInt16 EXC_FONTWGHT_THIN = 100;
+const sal_uInt16 EXC_FONTWGHT_ULTRALIGHT = 200;
+const sal_uInt16 EXC_FONTWGHT_LIGHT = 300;
+const sal_uInt16 EXC_FONTWGHT_SEMILIGHT = 350;
+const sal_uInt16 EXC_FONTWGHT_NORMAL = 400;
+const sal_uInt16 EXC_FONTWGHT_MEDIUM = 500;
+const sal_uInt16 EXC_FONTWGHT_SEMIBOLD = 600;
+const sal_uInt16 EXC_FONTWGHT_BOLD = 700;
+const sal_uInt16 EXC_FONTWGHT_ULTRABOLD = 800;
+const sal_uInt16 EXC_FONTWGHT_BLACK = 900;
+
+// underline
+const sal_uInt8 EXC_FONTUNDERL_NONE = 0x00;
+const sal_uInt8 EXC_FONTUNDERL_SINGLE = 0x01;
+const sal_uInt8 EXC_FONTUNDERL_DOUBLE = 0x02;
+const sal_uInt8 EXC_FONTUNDERL_SINGLE_ACC = 0x21;
+const sal_uInt8 EXC_FONTUNDERL_DOUBLE_ACC = 0x22;
+
+// escapement
+const sal_uInt16 EXC_FONTESC_NONE = 0x00;
+const sal_uInt16 EXC_FONTESC_SUPER = 0x01;
+const sal_uInt16 EXC_FONTESC_SUB = 0x02;
+
+// (0x0043, 0x0243, 0x0443, 0x00E0) XF ----------------------------------------
+
+const sal_uInt16 EXC_ID2_XF = 0x0043;
+const sal_uInt16 EXC_ID3_XF = 0x0243;
+const sal_uInt16 EXC_ID4_XF = 0x0443;
+const sal_uInt16 EXC_ID5_XF = 0x00E0;
+
+const sal_uInt32 EXC_XF_MAXCOUNT = 4050; /// Maximum number of all XF records.
+const sal_uInt32 EXC_XF_MAXSTYLECOUNT = 1536; /// Arbitrary maximum number of style XFs.
+const sal_uInt16 EXC_XF_DEFAULTSTYLE = 0; /// Excel index to default style XF.
+const sal_uInt16 EXC_XF_DEFAULTCELL = 15; /// Excel index to default cell XF.
+const sal_uInt16 EXC_XF_NOTFOUND = 0xFFFF; /// Special index for "not found" state.
+
+const sal_uInt32 EXC_XFID_NOTFOUND = 0xFFFFFFFF;
+
+const sal_uInt16 EXC_XF_LOCKED = 0x0001;
+const sal_uInt16 EXC_XF_HIDDEN = 0x0002;
+const sal_uInt16 EXC_XF_STYLE = 0x0004;
+const sal_uInt16 EXC_XF_STYLEPARENT = 0x0FFF; /// Syles don't have a parent.
+const sal_uInt16 EXC_XF_LINEBREAK = 0x0008; /// Automatic line break.
+const sal_uInt16 EXC_XF_SHRINK = 0x0010; /// Shrink to fit into cell.
+
+const sal_uInt8 EXC_XF_DIFF_VALFMT = 0x01;
+const sal_uInt8 EXC_XF_DIFF_FONT = 0x02;
+const sal_uInt8 EXC_XF_DIFF_ALIGN = 0x04;
+const sal_uInt8 EXC_XF_DIFF_BORDER = 0x08;
+const sal_uInt8 EXC_XF_DIFF_AREA = 0x10;
+const sal_uInt8 EXC_XF_DIFF_PROT = 0x20;
+
+const sal_uInt8 EXC_XF_HOR_GENERAL = 0x00;
+const sal_uInt8 EXC_XF_HOR_LEFT = 0x01;
+const sal_uInt8 EXC_XF_HOR_CENTER = 0x02;
+const sal_uInt8 EXC_XF_HOR_RIGHT = 0x03;
+const sal_uInt8 EXC_XF_HOR_FILL = 0x04;
+const sal_uInt8 EXC_XF_HOR_JUSTIFY = 0x05;
+const sal_uInt8 EXC_XF_HOR_CENTER_AS = 0x06;
+const sal_uInt8 EXC_XF_HOR_DISTRIB = 0x07;
+
+const sal_uInt8 EXC_XF_VER_TOP = 0x00;
+const sal_uInt8 EXC_XF_VER_CENTER = 0x01;
+const sal_uInt8 EXC_XF_VER_BOTTOM = 0x02;
+const sal_uInt8 EXC_XF_VER_JUSTIFY = 0x03;
+const sal_uInt8 EXC_XF_VER_DISTRIB = 0x04;
+
+const sal_uInt8 EXC_XF_TEXTDIR_CONTEXT = 0x00;
+const sal_uInt8 EXC_XF_TEXTDIR_LTR = 0x01;
+const sal_uInt8 EXC_XF_TEXTDIR_RTL = 0x02;
+
+const sal_uInt8 EXC_XF2_VALFMT_MASK = 0x3F;
+const sal_uInt8 EXC_XF2_LOCKED = 0x40;
+const sal_uInt8 EXC_XF2_HIDDEN = 0x80;
+const sal_uInt8 EXC_XF2_LEFTLINE = 0x08;
+const sal_uInt8 EXC_XF2_RIGHTLINE = 0x10;
+const sal_uInt8 EXC_XF2_TOPLINE = 0x20;
+const sal_uInt8 EXC_XF2_BOTTOMLINE = 0x40;
+const sal_uInt8 EXC_XF2_BACKGROUND = 0x80;
+
+const sal_uInt16 EXC_XF8_SHRINK = 0x0010; /// Shrink to fit into cell.
+const sal_uInt16 EXC_XF8_MERGE = 0x0020;
+
+const sal_uInt32 EXC_XF_DIAGONAL_TL_TO_BR = 0x40000000; /// Top-left to bottom-right.
+const sal_uInt32 EXC_XF_DIAGONAL_BL_TO_TR = 0x80000000; /// Bottom-left to top-right.
+const sal_uInt32 EXC_XF_DIAGONAL_BOTH = 0xC0000000; /// Both.
+
+// (0x0045) EFONT -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_EFONT = 0x0045;
+
+// (0x0092) PALETTE -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PALETTE = 0x0092;
+
+const sal_uInt16 EXC_COLOR_BIFF2_BLACK = 0;
+const sal_uInt16 EXC_COLOR_BIFF2_WHITE = 1;
+
+const sal_uInt16 EXC_COLOR_USEROFFSET = 8; /// First user defined color.
+const sal_uInt16 EXC_COLOR_WINDOWTEXT3 = 24; /// System window text color (BIFF3-BIFF4).
+const sal_uInt16 EXC_COLOR_WINDOWBACK3 = 25; /// System window background color (BIFF3-BIFF4).
+const sal_uInt16 EXC_COLOR_WINDOWTEXT = 64; /// System window text color (>=BIFF5).
+const sal_uInt16 EXC_COLOR_WINDOWBACK = 65; /// System window background color (>=BIFF5).
+const sal_uInt16 EXC_COLOR_BUTTONBACK = 67; /// System button background color (face color).
+const sal_uInt16 EXC_COLOR_CHWINDOWTEXT = 77; /// System window text color (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_CHWINDOWBACK = 78; /// System window background color (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_CHBORDERAUTO = 79; /// Automatic frame border for series (BIFF8 charts).
+const sal_uInt16 EXC_COLOR_NOTEBACK = 80; /// Note background color.
+const sal_uInt16 EXC_COLOR_NOTETEXT = 81; /// Note text color.
+const sal_uInt16 EXC_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (system window text color).
+
+// (0x0293) STYLE -------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_STYLE = 0x0293;
+
+const sal_uInt16 EXC_STYLE_BUILTIN = 0x8000;
+const sal_uInt16 EXC_STYLE_XFMASK = 0x0FFF;
+
+const sal_uInt8 EXC_STYLE_NORMAL = 0x00; /// "Normal" style.
+const sal_uInt8 EXC_STYLE_ROWLEVEL = 0x01; /// "RowLevel_*" styles.
+const sal_uInt8 EXC_STYLE_COLLEVEL = 0x02; /// "ColLevel_*" styles.
+const sal_uInt8 EXC_STYLE_COMMA = 0x03; /// "Comma" style.
+const sal_uInt8 EXC_STYLE_CURRENCY = 0x04; /// "Currency" style.
+const sal_uInt8 EXC_STYLE_PERCENT = 0x05; /// "Percent" style.
+const sal_uInt8 EXC_STYLE_COMMA_0 = 0x06; /// "Comma [0]" style.
+const sal_uInt8 EXC_STYLE_CURRENCY_0 = 0x07; /// "Currency [0]" style.
+const sal_uInt8 EXC_STYLE_HYPERLINK = 0x08; /// "Hyperlink" style.
+const sal_uInt8 EXC_STYLE_FOLLOWED_HYPERLINK= 0x09; /// "Followed_Hyperlink" style.
+const sal_uInt8 EXC_STYLE_USERDEF = 0xFF; /// No built-in style.
+
+const sal_uInt8 EXC_STYLE_LEVELCOUNT = 7; /// Number of outline level styles.
+const sal_uInt8 EXC_STYLE_NOLEVEL = 0xFF; /// Default value for unused level.
+
+// (0x0892) STYLEEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_STYLEEXT = 0x0892;
+
+const sal_uInt8 EXC_STYLEEXT_BUILTIN = 0x01;
+const sal_uInt8 EXC_STYLEEXT_HIDDEN = 0x02;
+const sal_uInt8 EXC_STYLEEXT_CUSTOM = 0x04;
+
+// Structs and classes ========================================================
+
+// Color data =================================================================
+
+/** Stores all default colors for a specific BIFF version. */
+class XclDefaultPalette
+{
+public:
+ explicit XclDefaultPalette( const XclRoot& rRoot );
+
+ /** Returns the color count in the current palette. */
+ inline sal_uInt32 GetColorCount() const { return mnTableSize - EXC_COLOR_USEROFFSET; }
+
+ /** Returns the default RGB color data for a (non-zero-based) Excel color or COL_AUTO on error. */
+ ColorData GetDefColorData( sal_uInt16 nXclIndex ) const;
+ /** Returns the default color for a (non-zero-based) Excel color or COL_AUTO on error. */
+ inline Color GetDefColor( sal_uInt16 nXclIndex ) const
+ { return Color( GetDefColorData( nXclIndex ) ); }
+
+ /** Returns true, if the passed Excel color index is a system color. */
+ inline bool IsSystemColor( sal_uInt16 nXclIndex ) const { return nXclIndex >= mnTableSize; }
+
+private:
+ const ColorData* mpnColorTable; /// The table with RGB values.
+ ColorData mnWindowText; /// System window text color.
+ ColorData mnWindowBack; /// System window background color.
+ ColorData mnFaceColor; /// System button background color.
+ ColorData mnNoteText; /// Note text color.
+ ColorData mnNoteBack; /// Note background color.
+ sal_uInt32 mnTableSize; /// The color table size.
+};
+
+// Font data ==================================================================
+
+class Font;
+class SvxFont;
+
+/** This struct helps reading and writing Excel fonts.
+
+ It stores all Excel compatible properties of a font. In detail this is the
+ name, family, character set, height, color, boldness, posture, script,
+ underline, strikeout, outline and shadow of the font.
+ */
+struct XclFontData
+{
+ String maName; /// Font name.
+ String maStyle; /// String with styles (bold, italic).
+ Color maColor; /// Font color.
+ sal_uInt16 mnHeight; /// Font height in twips (1/20 of a point).
+ sal_uInt16 mnWeight; /// Boldness: 400=normal, 700=bold.
+ sal_uInt16 mnEscapem; /// Escapement type.
+ sal_uInt8 mnFamily; /// Windows font family.
+ sal_uInt8 mnCharSet; /// Windows character set.
+ sal_uInt8 mnUnderline; /// Underline style.
+ bool mbItalic; /// true = Italic.
+ bool mbStrikeout; /// true = Struck out.
+ bool mbOutline; /// true = Outlined.
+ bool mbShadow; /// true = Shadowed.
+
+ /** Constructs an empty font data structure. */
+ explicit XclFontData();
+ /** Constructs a font data structure and fills it with the passed font attributes (except color). */
+ explicit XclFontData( const Font& rFont );
+ /** As directly above but also fills in the escapement member. */
+ explicit XclFontData( const SvxFont& rFont );
+
+ /** Resets all members to default (empty) values. */
+ void Clear();
+ /** Fills all members (except color and escapement) from the passed font. */
+ void FillFromVclFont( const Font& rFont );
+ /** Fills all members (except color) from the passed SVX font. */
+ void FillFromSvxFont( const SvxFont& rFont );
+
+// *** conversion of VCL/SVX constants *** ------------------------------------
+
+ /** Returns the Calc font family. */
+ FontFamily GetScFamily( rtl_TextEncoding eDefTextEnc ) const;
+ /** Returns the font text encoding. */
+ rtl_TextEncoding GetFontEncoding() const;
+ /** Returns the Calc font posture. */
+ FontItalic GetScPosture() const;
+ /** Returns the Calc font weight. */
+ FontWeight GetScWeight() const;
+ /** Returns the Calc font underline style. */
+ FontUnderline GetScUnderline() const;
+ /** Returns the Calc escapement style. */
+ SvxEscapement GetScEscapement() const;
+ /** Returns the Calc strike-out style. */
+ FontStrikeout GetScStrikeout() const;
+
+ /** Sets the Calc font height (in twips). */
+ void SetScHeight( sal_Int32 nTwips );
+ /** Sets the Calc font family. */
+ void SetScFamily( FontFamily eScFamily );
+ /** Sets the font text encoding. */
+ void SetFontEncoding( rtl_TextEncoding eFontEnc );
+ /** Sets the Calc font posture. */
+ void SetScPosture( FontItalic eScPosture );
+ /** Sets the Calc font weight. */
+ void SetScWeight( FontWeight eScWeight );
+ /** Sets the Calc underline style. */
+ void SetScUnderline( FontUnderline eScUnderl );
+ /** Sets the Calc escapement style. */
+ void SetScEscapement( short nScEscapem );
+ /** Sets the Calc strike-out style. */
+ void SetScStrikeout( FontStrikeout eScStrikeout );
+
+// *** conversion of API constants *** ----------------------------------------
+
+ /** Returns the API font height. */
+ float GetApiHeight() const;
+ /** Returns the API font family. */
+ sal_Int16 GetApiFamily() const;
+ /** Returns the API font text encoding. */
+ sal_Int16 GetApiFontEncoding() const;
+ /** Returns the API font posture. */
+ ::com::sun::star::awt::FontSlant GetApiPosture() const;
+ /** Returns the API font weight. */
+ float GetApiWeight() const;
+ /** Returns the API font underline style. */
+ sal_Int16 GetApiUnderline() const;
+ /** Returns the API escapement style. */
+ sal_Int16 GetApiEscapement() const;
+ /** Returns the API font strike-out style. */
+ sal_Int16 GetApiStrikeout() const;
+
+ /** Sets the API font height. */
+ void SetApiHeight( float fPoint );
+ /** Sets the API font family. */
+ void SetApiFamily( sal_Int16 nApiFamily );
+ /** Sets the API font posture. */
+ void SetApiPosture( ::com::sun::star::awt::FontSlant eApiPosture );
+ /** Sets the API font weight. */
+ void SetApiWeight( float fApiWeight );
+ /** Sets the API font underline style. */
+ void SetApiUnderline( sal_Int16 nApiUnderl );
+ /** Sets the API escapement style. */
+ void SetApiEscapement( sal_Int16 nApiEscapem );
+ /** Sets the API font strike-out style. */
+ void SetApiStrikeout( sal_Int16 nApiStrikeout );
+};
+
+bool operator==( const XclFontData& rLeft, const XclFontData& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates different types of Which-IDs for font items. */
+enum XclFontItemType
+{
+ EXC_FONTITEM_CELL, /// Use Calc Which-IDs (ATTR_*).
+ EXC_FONTITEM_EDITENG, /// Use edit engine Which-IDs (EE_CHAR_*).
+ EXC_FONTITEM_HF, /// Use header/footer edit engine Which-IDs (EE_CHAR_*).
+ EXC_FONTITEM_NOTE /// Use note edit engine Which-IDs (EE_CHAR_*), special font handling.
+};
+
+/** Enumerates different types for objects with font settings (using different property names). */
+enum XclFontPropSetType
+{
+ EXC_FONTPROPSET_CHART, /// All text objects in charts.
+ EXC_FONTPROPSET_CONTROL /// Text formatting in form controls.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Helper class for usage of property sets. */
+class XclFontPropSetHelper
+{
+public:
+ explicit XclFontPropSetHelper();
+
+ /** Reads all font properties from the passed property set. */
+ void ReadFontProperties( XclFontData& rFontData,
+ const ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ sal_Int16 nScript = -1 );
+
+ /** Writes all font properties to the passed property set, uses passed color as font color. */
+ void WriteFontProperties(
+ ScfPropertySet& rPropSet, XclFontPropSetType eType,
+ const XclFontData& rFontData,
+ bool bHasWstrn, bool bHasAsian, bool bHasCmplx,
+ const Color* pFontColor = 0 );
+
+private:
+ /** Returns a chart property set helper according to the passed script type. */
+ ScfPropSetHelper& GetChartHelper( sal_Int16 nScript );
+
+private:
+ ScfPropSetHelper maHlpChCommon; /// Chart properties for all scripts.
+ ScfPropSetHelper maHlpChWstrn; /// Chart properties for Western script.
+ ScfPropSetHelper maHlpChAsian; /// Chart properties for Asian script.
+ ScfPropSetHelper maHlpChCmplx; /// Chart properties for Complex script.
+ ScfPropSetHelper maHlpChWstrnNoName; /// Chart properties for Western script, no font name.
+ ScfPropSetHelper maHlpChAsianNoName; /// Chart properties for Asian script, no font name.
+ ScfPropSetHelper maHlpChCmplxNoName; /// Chart properties for Complex script, no font name.
+ ScfPropSetHelper maHlpChEscapement; /// Chart properties for font escapement.
+ ScfPropSetHelper maHlpControl; /// Properties for form controls.
+};
+
+// Number formats =============================================================
+
+struct XclNumFmt
+{
+ String maFormat; /// Format string, may be empty (meOffset used then).
+ NfIndexTableOffset meOffset; /// SvNumberFormatter format index, if maFormat is empty.
+ LanguageType meLanguage; /// Language type to be set with the number format.
+};
+
+// ----------------------------------------------------------------------------
+
+class XclNumFmtBuffer
+{
+public:
+ explicit XclNumFmtBuffer( const XclRoot& rRoot );
+
+ /** Returns the core index of the current standard number format. */
+ inline sal_uLong GetStdScNumFmt() const { return mnStdScNumFmt; }
+
+protected:
+ typedef ::std::map< sal_uInt16, XclNumFmt > XclNumFmtMap;
+
+ /** Clears all buffered data, used to set up for a new sheet. */
+ void InitializeImport();
+
+ /** Returns the current number format map. */
+ inline const XclNumFmtMap& GetFormatMap() const { return maFmtMap; }
+
+ /** Inserts a new number format for the specified Excel format index. */
+ void InsertFormat( sal_uInt16 nXclNumFmt, const String& rFormat );
+
+private:
+ /** Inserts built-in number formats for the current system language. */
+ void InsertBuiltinFormats();
+
+ XclNumFmtMap maFmtMap; /// Map containing all default and user-defined formats.
+ LanguageType meSysLang; /// Current system language.
+ sal_uLong mnStdScNumFmt; /// Calc format key for standard number format.
+};
+
+// Cell formatting data (XF) ==================================================
+
+/** Contains all cell protection attributes. */
+struct XclCellProt
+{
+ bool mbLocked; /// true = Locked against editing.
+ bool mbHidden; /// true = Formula is hidden.
+
+ explicit XclCellProt();
+};
+
+bool operator==( const XclCellProt& rLeft, const XclCellProt& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains all cell alignment attributes. */
+struct XclCellAlign
+{
+ sal_uInt8 mnHorAlign; /// Horizontal alignment.
+ sal_uInt8 mnVerAlign; /// Vertical alignment.
+ sal_uInt8 mnOrient; /// Text orientation.
+ sal_uInt8 mnTextDir; /// CTL text direction.
+ sal_uInt8 mnRotation; /// Text rotation angle.
+ sal_uInt8 mnIndent; /// Indentation.
+ bool mbLineBreak; /// true = Multi-line text.
+ bool mbShrink; /// true = Shrink to fit cell size.
+
+ explicit XclCellAlign();
+
+ /** Returns the Calc horizontal alignment. */
+ SvxCellHorJustify GetScHorAlign() const;
+ /** Returns horizontal justification method as Calc's attribute. */
+ SvxCellJustifyMethod GetScHorJustifyMethod() const;
+ /** Returns the Calc vertical alignment. */
+ SvxCellVerJustify GetScVerAlign() const;
+ /** Returns vertical justification method as Calc's attribute. */
+ SvxCellJustifyMethod GetScVerJustifyMethod() const;
+ /** Returns the Calc frame direction. */
+ SvxFrameDirection GetScFrameDir() const;
+
+ /** Sets the Calc horizontal alignment. */
+ void SetScHorAlign( SvxCellHorJustify eHorJust );
+ /** Sets the Calc vertical alignment. */
+ void SetScVerAlign( SvxCellVerJustify eVerJust );
+ /** Sets the Calc frame direction. */
+ void SetScFrameDir( SvxFrameDirection eFrameDir );
+};
+
+bool operator==( const XclCellAlign& rLeft, const XclCellAlign& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains color and line style for each cell border line. */
+struct XclCellBorder
+{
+ sal_uInt16 mnLeftColor; /// Palette index for left line.
+ sal_uInt16 mnRightColor; /// Palette index for right line.
+ sal_uInt16 mnTopColor; /// Palette index for top line.
+ sal_uInt16 mnBottomColor; /// Palette index for bottom line.
+ sal_uInt16 mnDiagColor; /// Palette index for diagonal line(s).
+ sal_uInt8 mnLeftLine; /// Style of left line.
+ sal_uInt8 mnRightLine; /// Style of right line.
+ sal_uInt8 mnTopLine; /// Style of top line.
+ sal_uInt8 mnBottomLine; /// Style of bottom line.
+ sal_uInt8 mnDiagLine; /// Style of diagonal line(s).
+ bool mbDiagTLtoBR; /// true = Top-left to bottom-right on.
+ bool mbDiagBLtoTR; /// true = Bottom-left to top-right on.
+
+ explicit XclCellBorder();
+};
+
+bool operator==( const XclCellBorder& rLeft, const XclCellBorder& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains background colors and pattern for a cell. */
+struct XclCellArea
+{
+ sal_uInt16 mnForeColor; /// Palette index to foreground color.
+ sal_uInt16 mnBackColor; /// Palette index to background color.
+ sal_uInt8 mnPattern; /// Fill pattern.
+
+ explicit XclCellArea();
+
+ /** Returns true, if the area represents transparent state. */
+ bool IsTransparent() const;
+};
+
+bool operator==( const XclCellArea& rLeft, const XclCellArea& rRight );
+
+// ----------------------------------------------------------------------------
+
+/** Contains base members for XF record import/export.
+ @descr In detail this class stores the XF type (cell/style), the index to the
+ parent style XF and all "attribute used" flags, which reflect the state of
+ specific attribute groups (true = user has changed the attributes). */
+class XclXFBase
+{
+public:
+ explicit XclXFBase( bool bCellXF );
+ virtual ~XclXFBase();
+
+ /** Sets all "attribute used" flags to the passed state. */
+ void SetAllUsedFlags( bool bUsed );
+ /** Returns true, if any "attribute used" flags are ste in this XF. */
+ bool HasUsedFlags() const;
+
+ /** Returns true, if this is a hard cell format. */
+ inline bool IsCellXF() const { return mbCellXF; }
+ /** Returns true, if this is a cell style. */
+ inline bool IsStyleXF() const { return !IsCellXF(); }
+
+protected:
+ /** Returns true, if this object is equal to the passed. */
+ bool Equals( const XclXFBase& rCmp ) const;
+
+protected:
+ sal_uInt16 mnParent; /// Index to parent style XF.
+ bool mbCellXF; /// true = cell XF, false = style XF.
+ bool mbProtUsed; /// true = cell protection used.
+ bool mbFontUsed; /// true = font index used.
+ bool mbFmtUsed; /// true = number format used.
+ bool mbAlignUsed; /// true = alignment used.
+ bool mbBorderUsed; /// true = border data used.
+ bool mbAreaUsed; /// true = area data used.
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xltable.hxx b/sc/source/filter/inc/xltable.hxx
new file mode 100644
index 000000000000..a671d8f25329
--- /dev/null
+++ b/sc/source/filter/inc/xltable.hxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLTABLE_HXX
+#define SC_XLTABLE_HXX
+
+#include <sal/types.h>
+
+// Constants and Enumerations =================================================
+
+// Specials for outlines ------------------------------------------------------
+
+const sal_uInt8 EXC_OUTLINE_MAX = 7;
+const sal_uInt8 EXC_OUTLINE_COUNT = EXC_OUTLINE_MAX + 1;
+
+// (0x0000, 0x0200) DIMENSIONS ------------------------------------------------
+const sal_uInt16 EXC_ID2_DIMENSIONS = 0x0000;
+const sal_uInt16 EXC_ID3_DIMENSIONS = 0x0200;
+
+// (0x0001, 0x0201) BLANK -----------------------------------------------------
+const sal_uInt16 EXC_ID2_BLANK = 0x0001;
+const sal_uInt16 EXC_ID3_BLANK = 0x0201;
+
+// (0x0002) INTEGER -----------------------------------------------------------
+const sal_uInt16 EXC_ID2_INTEGER = 0x0002;
+
+// (0x0003, 0x0203) NUMBER ----------------------------------------------------
+const sal_uInt16 EXC_ID2_NUMBER = 0x0003;
+const sal_uInt16 EXC_ID3_NUMBER = 0x0203;
+
+// (0x0004, 0x0204) LABEL -----------------------------------------------------
+const sal_uInt16 EXC_ID2_LABEL = 0x0004;
+const sal_uInt16 EXC_ID3_LABEL = 0x0204;
+
+const sal_uInt8 EXC_LABEL_MAXLEN = 0xFF;
+
+// (0x0005, 0x0205) BOOLERR ---------------------------------------------------
+const sal_uInt16 EXC_ID2_BOOLERR = 0x0005;
+const sal_uInt16 EXC_ID3_BOOLERR = 0x0205;
+
+const sal_uInt8 EXC_BOOLERR_BOOL = 0x00;
+const sal_uInt8 EXC_BOOLERR_ERROR = 0x01;
+
+// (0x0006, 0x0206, 0x0406) FORMULA -------------------------------------------
+const sal_uInt16 EXC_ID2_FORMULA = 0x0006;
+const sal_uInt16 EXC_ID3_FORMULA = 0x0206;
+const sal_uInt16 EXC_ID4_FORMULA = 0x0406;
+
+const sal_uInt16 EXC_FORMULA_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_FORMULA_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_FORMULA_SHARED = 0x0008;
+const sal_uInt16 EXC_FORMULA_DEFAULTFLAGS = EXC_FORMULA_RECALC_ONLOAD;
+
+const sal_uInt8 EXC_FORMULA_RES_STRING = 0x00; /// Result is a string.
+const sal_uInt8 EXC_FORMULA_RES_BOOL = 0x01; /// Result is Boolean value.
+const sal_uInt8 EXC_FORMULA_RES_ERROR = 0x02; /// Result is error code.
+const sal_uInt8 EXC_FORMULA_RES_EMPTY = 0x03; /// Result is empty cell (BIFF8 only).
+
+// (0x0007, 0x0207) STRING ----------------------------------------------------
+const sal_uInt16 EXC_ID2_STRING = 0x0007;
+const sal_uInt16 EXC_ID3_STRING = 0x0207;
+
+// (0x0008, 0x0208) ROW -------------------------------------------------------
+const sal_uInt16 EXC_ID2_ROW = 0x0008;
+const sal_uInt16 EXC_ID3_ROW = 0x0208;
+
+const sal_uInt16 EXC_ROW_COLLAPSED = 0x0010;
+const sal_uInt16 EXC_ROW_HIDDEN = 0x0020;
+const sal_uInt16 EXC_ROW_UNSYNCED = 0x0040;
+const sal_uInt16 EXC_ROW_USEDEFXF = 0x0080;
+const sal_uInt16 EXC_ROW_DEFAULTFLAGS = 0x0100;
+
+const sal_uInt16 EXC_ROW_XFMASK = 0x0FFF;
+
+const sal_uInt16 EXC_ROW_DEFAULTHEIGHT = 255;
+const sal_uInt16 EXC_ROW_FLAGDEFHEIGHT = 0x8000;
+const sal_uInt16 EXC_ROW_HEIGHTMASK = 0x7FFF;
+
+const sal_uInt16 EXC_ROW_ROWBLOCKSIZE = 32; /// Number of rows in a row block.
+
+// (0x0020) COLUMNDEFAULT -----------------------------------------------------
+const sal_uInt16 EXC_ID_COLUMNDEFAULT = 0x0020;
+
+// (0x0021, 0x0221) ARRAY -----------------------------------------------------
+const sal_uInt16 EXC_ID2_ARRAY = 0x0021;
+const sal_uInt16 EXC_ID3_ARRAY = 0x0221;
+
+const sal_uInt16 EXC_ARRAY_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_ARRAY_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_ARRAY_DEFAULTFLAGS = EXC_ARRAY_RECALC_ONLOAD;
+
+// (0x0024) COLWIDTH ----------------------------------------------------------
+const sal_uInt16 EXC_ID_COLWIDTH = 0x0024;
+
+// (0x0025, 0x0225) DEFAULTROWHEIGHT ------------------------------------------
+const sal_uInt16 EXC_ID2_DEFROWHEIGHT = 0x0025;
+const sal_uInt16 EXC_ID3_DEFROWHEIGHT = 0x0225;
+
+const sal_uInt16 EXC_DEFROW_UNSYNCED = 0x0001;
+const sal_uInt16 EXC_DEFROW_HIDDEN = 0x0002;
+const sal_uInt16 EXC_DEFROW_SPACEABOVE = 0x0004;
+const sal_uInt16 EXC_DEFROW_SPACEBELOW = 0x0008;
+const sal_uInt16 EXC_DEFROW_DEFAULTFLAGS = 0x0000;
+
+const sal_uInt16 EXC_DEFROW_DEFAULTHEIGHT = 255;
+
+// (0x0036, 0x0236) TABLEOP ---------------------------------------------------
+const sal_uInt16 EXC_ID2_TABLEOP = 0x0036;
+const sal_uInt16 EXC_ID3_TABLEOP = 0x0236;
+
+const sal_uInt16 EXC_TABLEOP_RECALC_ALWAYS = 0x0001;
+const sal_uInt16 EXC_TABLEOP_RECALC_ONLOAD = 0x0002;
+const sal_uInt16 EXC_TABLEOP_ROW = 0x0004;
+const sal_uInt16 EXC_TABLEOP_BOTH = 0x0008;
+const sal_uInt16 EXC_TABLEOP_DEFAULTFLAGS = EXC_TABLEOP_RECALC_ONLOAD;
+
+// (0x0037) TABLEOP2 ----------------------------------------------------------
+const sal_uInt16 EXC_ID2_TABLEOP2 = 0x0037;
+
+// (0x0055) DEFCOLWIDTH -------------------------------------------------------
+const sal_uInt16 EXC_ID_DEFCOLWIDTH = 0x0055;
+const sal_uInt16 EXC_DEFCOLWIDTH_DEF = 10;
+
+// (0x007D) COLINFO -----------------------------------------------------------
+const sal_uInt16 EXC_ID_COLINFO = 0x007D;
+
+const sal_uInt16 EXC_COLINFO_HIDDEN = 0x0001;
+const sal_uInt16 EXC_COLINFO_COLLAPSED = 0x1000;
+
+// (0x0080) GUTS --------------------------------------------------------------
+const sal_uInt16 EXC_ID_GUTS = 0x0080;
+
+// (0x00BD) MULRK -------------------------------------------------------------
+const sal_uInt16 EXC_ID_MULRK = 0x00BD;
+
+// (0x00BE) MULBLANK ----------------------------------------------------------
+const sal_uInt16 EXC_ID_MULBLANK = 0x00BE;
+
+// (0x00D6) RSTRING -----------------------------------------------------------
+const sal_uInt16 EXC_ID_RSTRING = 0x00D6;
+
+// (0x00FD) LABELSST ----------------------------------------------------------
+const sal_uInt16 EXC_ID_LABELSST = 0x00FD;
+
+// (0x027E) RK ----------------------------------------------------------------
+const sal_uInt16 EXC_ID_RK = 0x027E;
+
+// (0x04BC) SHRFMLA -----------------------------------------------------------
+const sal_uInt16 EXC_ID_SHRFMLA = 0x04BC;
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx
new file mode 100644
index 000000000000..e9e306e2f1c6
--- /dev/null
+++ b/sc/source/filter/inc/xltools.hxx
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLTOOLS_HXX
+#define SC_XLTOOLS_HXX
+
+#include "address.hxx"
+#include "ftools.hxx"
+#include <boost/noncopyable.hpp>
+
+class SfxObjectShell;
+
+// BIFF versions ==============================================================
+
+#define DBG_ERROR_BIFF() DBG_ERRORFILE( "Unknown BIFF type!" )
+#define DBG_ASSERT_BIFF( c ) DBG_ASSERT( c, "Unknown BIFF type!" )
+
+// Enumerations ===============================================================
+
+/** An enumeration for all Excel error codes and the values true and false. */
+enum XclBoolError
+{
+ xlErrNull, /// The error code #NULL!
+ xlErrDiv0, /// The error code #DIV/0!
+ xlErrValue, /// The error code #VALUE!
+ xlErrRef, /// The error code #REF!
+ xlErrName, /// The error code #NAME?
+ xlErrNum, /// The error code #NUM!
+ xlErrNA, /// The error code #N/A!
+ xlErrTrue, /// The Boolean value true.
+ xlErrFalse, /// The Boolean value false.
+ xlErrUnknown /// For unknown codes and values.
+};
+
+// GUID import/export =========================================================
+
+class XclImpStream;
+class XclExpStream;
+
+/** This struct stores a GUID (class ID) and supports reading, writing and comparison. */
+struct XclGuid
+{
+ sal_uInt8 mpnData[ 16 ]; /// Stores GUID always in little endian.
+
+ explicit XclGuid();
+ explicit XclGuid(
+ sal_uInt32 nData1,
+ sal_uInt16 nData2, sal_uInt16 nData3,
+ sal_uInt8 nData41, sal_uInt8 nData42,
+ sal_uInt8 nData43, sal_uInt8 nData44,
+ sal_uInt8 nData45, sal_uInt8 nData46,
+ sal_uInt8 nData47, sal_uInt8 nData48 );
+};
+
+bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 );
+inline bool operator!=( const XclGuid& rCmp1, const XclGuid& rCmp2 ) { return !(rCmp1 == rCmp2); }
+bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 );
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid );
+
+// Excel Tools ================================================================
+
+class SvStream;
+class ScDocument;
+
+/** This class contains static helper methods for the Excel import and export filters. */
+class XclTools : boost::noncopyable
+{
+public:
+ // GUID's -----------------------------------------------------------------
+
+ static const XclGuid maGuidStdLink; /// GUID of StdLink (HLINK record).
+ static const XclGuid maGuidUrlMoniker; /// GUID of URL moniker (HLINK record).
+ static const XclGuid maGuidFileMoniker; /// GUID of file moniker (HLINK record).
+
+ // numeric conversion -----------------------------------------------------
+
+ /** Calculates the double value from an RK value (encoded integer or double). */
+ static double GetDoubleFromRK( sal_Int32 nRKValue );
+ /** Calculates an RK value (encoded integer or double) from a double value.
+ @param rnRKValue Returns the calculated RK value.
+ @param fValue The double value.
+ @return true = An RK value could be created. */
+ static bool GetRKFromDouble( sal_Int32& rnRKValue, double fValue );
+
+ /** Calculates an angle (in 1/100 of degrees) from an Excel angle value.
+ @param nRotForStacked This value will be returned, if nXclRot contains 'stacked'. */
+ static sal_Int32 GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked );
+ /** Calculates the Excel angle value from an angle in 1/100 of degrees. */
+ static sal_uInt8 GetXclRotation( sal_Int32 nScRot );
+
+ /** Calculates BIFF8 rotation angle from BIFF2-BIFF5 text orientation. */
+ static sal_uInt8 GetXclRotFromOrient( sal_uInt8 nXclOrient );
+ /** Calculates BIFF2-BIFF5 text orientation from BIFF8 rotation angle. */
+ static sal_uInt8 GetXclOrientFromRot( sal_uInt16 nXclRot );
+
+ /** Converts a Calc error code to an Excel error code. */
+ static sal_uInt8 GetXclErrorCode( sal_uInt16 nScError );
+ /** Converts an Excel error code to a Calc error code. */
+ static sal_uInt16 GetScErrorCode( sal_uInt8 nXclError );
+
+ /** Converts the passed BIFF error to a double containing the respective Calc error code. */
+ static double ErrorToDouble( sal_uInt8 nXclError );
+ /** Gets a translated error code or Boolean value from Excel error codes.
+ @param rfDblValue Returns 0.0 for error codes or the value of a Boolean (0.0 or 1.0).
+ @param bErrorOrBool false = nError is a Boolean value; true = is an error value.
+ @param nValue The error code or Boolean value. */
+ static XclBoolError ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue );
+
+ /** Returns the length in twips calculated from a length in inches. */
+ static sal_uInt16 GetTwipsFromInch( double fInches );
+ /** Returns the length in twips calculated from a length in 1/100 mm. */
+ static sal_uInt16 GetTwipsFromHmm( sal_Int32 nHmm );
+
+ /** Returns the length in inches calculated from a length in twips. */
+ static double GetInchFromTwips( sal_Int32 nTwips );
+ /** Returns the length in inches calculated from a length in 1/100 mm. */
+ static double GetInchFromHmm( sal_Int32 nHmm );
+
+ /** Returns the length in 1/100 mm calculated from a length in inches. */
+ static sal_Int32 GetHmmFromInch( double fInches );
+ /** Returns the length in 1/100 mm calculated from a length in twips. */
+ static sal_Int32 GetHmmFromTwips( sal_Int32 nTwips );
+
+ /** Returns the Calc column width (twips) for the passed Excel width.
+ @param nScCharWidth Width of the '0' character in Calc (twips). */
+ static sal_uInt16 GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth );
+ /** Returns the Excel column width for the passed Calc width (twips).
+ @param nScCharWidth Width of the '0' character in Calc (twips). */
+ static sal_uInt16 GetXclColumnWidth( sal_uInt16 nScWidth, long nScCharWidth );
+
+ /** Returns a correction value to convert column widths from/to default column widths.
+ @param nXclDefFontHeight Excel height of application default font. */
+ static double GetXclDefColWidthCorrection( long nXclDefFontHeight );
+
+ // formatting -------------------------------------------------------------
+
+ /** Returns the best fitting color for an Excel pattern area format. */
+ static Color GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern );
+
+ // text encoding ----------------------------------------------------------
+
+ /** Returns a text encoding from an Excel code page.
+ @return The corresponding text encoding or RTL_TEXTENCODING_DONTKNOW. */
+ static rtl_TextEncoding GetTextEncoding( sal_uInt16 nCodePage );
+
+ /** Returns an Excel code page from a text encoding. */
+ static sal_uInt16 GetXclCodePage( rtl_TextEncoding eTextEnc );
+
+ // font names -------------------------------------------------------------
+
+ /** Returns the matching Excel font name for a passed Calc font name. */
+ static String GetXclFontName( const String& rFontName );
+
+ // built-in defined names -------------------------------------------------
+
+ /** Returns the raw English UI representation of a built-in defined name used in NAME records.
+ @param cBuiltIn Excel index of the built-in name. */
+ static String GetXclBuiltInDefName( sal_Unicode cBuiltIn );
+ /** Returns the Calc UI representation of a built-in defined name used in NAME records.
+ @descr Adds a prefix to the representation returned by GetXclBuiltInDefName().
+ @param cBuiltIn Excel index of the built-in name. */
+ static String GetBuiltInDefName( sal_Unicode cBuiltIn );
+ /** Returns the Excel built-in name with OOXML prefix
+ @descr Adds the "_xlnm." prefix to the representation returned by GetXclBuiltInDefName()
+ @param cBuiltIn Excel index of the built in name.*/
+ static String GetBuiltInDefNameXml( sal_Unicode cBuiltIn );
+ /** Returns the Excel built-in name index of the passed defined name from Calc.
+ @descr Ignores any characters following a valid representation of a built-in name.
+ @param pcBuiltIn (out-param) If not 0, the index of the built-in name will be returned here.
+ @return true = passed string is a built-in name; false = user-defined name. */
+ static sal_Unicode GetBuiltInDefNameIndex( const String& rDefName );
+
+ // built-in style names ---------------------------------------------------
+
+ /** Returns the specified built-in cell style name.
+ @param nStyleId The identifier of the built-in style.
+ @param rName Default name for unknown styles.
+ @param nLevel The zero-based outline level for RowLevel and ColLevel styles.
+ @return The style name or an empty string, if the parameters are not valid. */
+ static String GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel );
+ /** Returns the passed style name with a special built-in prefix. */
+ static String GetBuiltInStyleName( const String& rStyleName );
+ /** Returns true, if the passed string is a name of an Excel built-in style.
+ @param pnStyleId If not 0, the found style identifier will be returned here.
+ @param pnNextChar If not 0, the index of the char after the evaluated substring will be returned here. */
+ static bool IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleId = 0, xub_StrLen* pnNextChar = 0 );
+ /** Returns the Excel built-in style identifier of a passed style name.
+ @param rnStyleId The style identifier is returned here.
+ @param rnLevel The zero-based outline level for RowLevel and ColLevel styles is returned here.
+ @param rStyleName The style name to examine.
+ @return true = passed string is a built-in style name, false = user style. */
+ static bool GetBuiltInStyleId(
+ sal_uInt8& rnStyleId, sal_uInt8& rnLevel,
+ const String& rStyleName );
+
+ // conditional formatting style names -------------------------------------
+
+ /** Returns the style name for a single condition of a conditional formatting.
+ @param nScTab The current Calc sheet index.
+ @param nFormat The zero-based index of the conditional formatting.
+ @param nCondition The zero-based index of the condition.
+ @return A style sheet name in the form "Excel_CondFormat_<sheet>_<format>_<condition>". */
+ static String GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition );
+ /** Returns true, if the passed string is a name of a conditional format style created by Excel import.
+ @param pnNextChar If not 0, the index of the char after the evaluated substring will be returned here. */
+ static bool IsCondFormatStyleName( const String& rStyleName, xub_StrLen* pnNextChar = 0 );
+
+ // stream handling --------------------------------------------------------
+
+ /** Skips a substream (BOF/EOF record block). Includes all embedded substreams. */
+ static void SkipSubStream( XclImpStream& rStrm );
+
+ // Basic macro names ------------------------------------------------------
+
+ /** Returns the full StarBasic macro URL from an Excel macro name. */
+ static ::rtl::OUString GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell = 0 );
+ /** Returns the full StarBasic macro URL from an Excel module and macro name. */
+ static ::rtl::OUString GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell = 0 );
+ /** Returns the Excel macro name from a full StarBasic macro URL. */
+ static String GetXclMacroName( const ::rtl::OUString& rSbMacroUrl );
+
+// ------------------------------------------------------------------------
+private:
+ static const String maDefNamePrefix; /// Prefix for built-in defined names.
+ static const String maDefNamePrefixXml; /// Prefix for built-in defined names for OOX
+ static const String maStyleNamePrefix1; /// Prefix for built-in cell style names.
+ static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter.
+ static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names.
+ static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter.
+ static const ::rtl::OUString maSbMacroPrefix; /// Prefix for StarBasic macros.
+ static const ::rtl::OUString maSbMacroSuffix; /// Suffix for StarBasic macros.
+
+ /** We don't want anybody to instantiate this class, since it is just a
+ collection of static items. To enforce this, the default constructor
+ is made private */
+ XclTools();
+};
+
+// read/write colors ----------------------------------------------------------
+
+/** Reads a color from the passed stream.
+ @descr The color has the format (all values 8-bit): Red, Green, Blue, 0. */
+XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor );
+
+/** Reads a color to the passed stream.
+ @descr The color has the format (all values 8-bit): Red, Green, Blue, 0. */
+XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor );
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xltracer.hxx b/sc/source/filter/inc/xltracer.hxx
new file mode 100644
index 000000000000..ba177fd3706f
--- /dev/null
+++ b/sc/source/filter/inc/xltracer.hxx
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// ============================================================================
+
+#ifndef SC_XLTRACER_HXX
+#define SC_XLTRACER_HXX
+
+#include "global.hxx" // ScAddress
+#include "xltools.hxx"
+
+// As Trace features become implemented, we can safely delete the enum entry as
+// we use the member mnID to keep track of the actual trace tag ID value.
+enum XclTracerId
+{
+ eUnKnown , /// unused but allows us to set the correct index
+ eRowLimitExceeded ,
+ eTabLimitExceeded ,
+ ePassword ,
+ ePrintRange ,
+ eShortDate ,
+ eBorderLineStyle ,
+ eFillPattern ,
+ eInvisibleGrid ,
+ eFormattedNote ,
+ eFormulaExtName ,
+ eFormulaMissingArg ,
+ ePivotDataSource ,
+ ePivotChartExists ,
+ eChartUnKnownType ,
+ eChartTrendLines ,
+ eChartErrorBars ,
+ eChartOnlySheet ,
+ eChartRange ,
+ eChartDSName,
+ eChartDataTable,
+ eChartLegendPosition,
+ eChartTextFormatting,
+ eChartEmbeddedObj,
+ eChartAxisAuto,
+ eChartAxisManual,
+ eChartInvalidXY,
+ eUnsupportedObject ,
+ eObjectNotPrintable ,
+ eDVType,
+ eTraceLength /// this *should* always be the final entry
+};
+
+struct XclTracerDetails
+{
+ XclTracerId meProblemId; /// Excel Import Trace index.
+ sal_uInt32 mnID; /// actual ID Index trace tag Value
+ const sal_Char* mpContext; /// Context for problem e.g. Limits
+ const sal_Char* mpDetail; /// Context Detail e.g. SheetX
+ const sal_Char* mpProblem; /// Description of problem
+};
+
+
+// ============================================================================
+
+class MSFilterTracer;
+
+/** This class wraps an MSFilterTracer to create trace logs for import/export filters. */
+class XclTracer
+{
+public:
+ explicit XclTracer( const String& rDocUrl, const ::rtl::OUString& rConfigPath );
+ virtual ~XclTracer();
+
+ /** Returns true, if tracing is enabled. */
+ inline bool IsEnabled() const { return mbEnabled; }
+
+ /** Adds an attribute to be traced with the next Trace() call. */
+ void AddAttribute( const ::rtl::OUString& rName, const ::rtl::OUString& rValue );
+
+ /** Creates an element including all attributes set up to this call.
+ @descr Removes all attributes after the element is traced. */
+ void Trace( const ::rtl::OUString& rElementID, const ::rtl::OUString& rMessage );
+
+ /** Calls Trace() with a known document properties problem. */
+ void TraceLog( XclTracerId eProblem, sal_Int32 nValue = 0 );
+
+ /** Calls AddAttribute() to create the Context & Detail for known problems. */
+ void Context( XclTracerId eProblem, SCTAB nTab = 0 );
+
+ /** Ensure that particular traces are logged once per document. */
+ void ProcessTraceOnce(XclTracerId eProblem, SCTAB nTab = 0);
+
+ void TraceInvalidAddress(const ScAddress& rPos, const ScAddress& rMaxPos);
+ void TraceInvalidRow( SCTAB nTab, sal_uInt32 nRow, sal_uInt32 nMaxrow );
+ void TraceInvalidTab( SCTAB nTab, SCTAB nMaxTab);
+ void TracePrintRange();
+ void TraceDates(sal_uInt16 nNumFmt);
+ void TraceBorderLineStyle(bool bBorderLineStyle);
+ void TraceFillPattern(bool bFillPattern);
+ void TraceFormulaMissingArg();
+ void TracePivotDataSource(bool bExternal);
+ void TracePivotChartExists();
+ void TraceChartUnKnownType();
+ void TraceChartOnlySheet();
+ void TraceChartDataTable();
+ void TraceChartLegendPosition();
+ void TraceUnsupportedObjects();
+ void TraceObjectNotPrintable();
+ void TraceDVType(bool bType);
+
+ /** Returns the SVX filter tracer for usage in external code (i.e. Escher). */
+ inline MSFilterTracer& GetBaseTracer() { return *mpTracer; }
+
+private:
+ typedef ::std::auto_ptr< MSFilterTracer > MSFilterTracerPtr;
+ MSFilterTracerPtr mpTracer;
+ bool mbEnabled;
+ typedef ::std::vector< bool > BoolVec;
+ /** array of flags corresponding to each entry in the XclTracerDetails table. */
+ BoolVec maFirstTimes;
+};
+
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/inc/xlview.hxx b/sc/source/filter/inc/xlview.hxx
new file mode 100644
index 000000000000..f362b58f3579
--- /dev/null
+++ b/sc/source/filter/inc/xlview.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XLVIEW_HXX
+#define SC_XLVIEW_HXX
+
+#include <map>
+#include <tools/color.hxx>
+#include "ftools.hxx"
+#include "xladdress.hxx"
+#include <boost/shared_ptr.hpp>
+
+// Constants and enumerations =================================================
+
+const sal_uInt16 EXC_ZOOM_MIN = 10;
+const sal_uInt16 EXC_ZOOM_MAX = 400;
+
+// (0x001D) SELECTION ---------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SELECTION = 0x001D;
+
+// (0x003D) WINDOW1 -----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_WINDOW1 = 0x003D;
+
+const sal_uInt16 EXC_WIN1_HIDDEN = 0x0001;
+const sal_uInt16 EXC_WIN1_MINIMIZED = 0x0002;
+const sal_uInt16 EXC_WIN1_HOR_SCROLLBAR = 0x0008;
+const sal_uInt16 EXC_WIN1_VER_SCROLLBAR = 0x0010;
+const sal_uInt16 EXC_WIN1_TABBAR = 0x0020;
+
+// (0x003E, 0x023E) WINDOW2 ---------------------------------------------------
+
+const sal_uInt16 EXC_ID2_WINDOW2 = 0x003E;
+const sal_uInt16 EXC_ID_WINDOW2 = 0x023E;
+
+const sal_uInt16 EXC_WIN2_SHOWFORMULAS = 0x0001;
+const sal_uInt16 EXC_WIN2_SHOWGRID = 0x0002;
+const sal_uInt16 EXC_WIN2_SHOWHEADINGS = 0x0004;
+const sal_uInt16 EXC_WIN2_FROZEN = 0x0008;
+const sal_uInt16 EXC_WIN2_SHOWZEROS = 0x0010;
+const sal_uInt16 EXC_WIN2_DEFGRIDCOLOR = 0x0020;
+const sal_uInt16 EXC_WIN2_MIRRORED = 0x0040;
+const sal_uInt16 EXC_WIN2_SHOWOUTLINE = 0x0080;
+const sal_uInt16 EXC_WIN2_FROZENNOSPLIT = 0x0100;
+const sal_uInt16 EXC_WIN2_SELECTED = 0x0200;
+const sal_uInt16 EXC_WIN2_DISPLAYED = 0x0400;
+const sal_uInt16 EXC_WIN2_PAGEBREAKMODE = 0x0800;
+
+const sal_uInt16 EXC_WIN2_NORMALZOOM_DEF = 100; /// Default zoom for normal view.
+const sal_uInt16 EXC_WIN2_PAGEZOOM_DEF = 60; /// Default zoom for pagebreak preview.
+
+// (0x0041) PANE --------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_PANE = 0x0041;
+
+const sal_uInt8 EXC_PANE_BOTTOMRIGHT = 0; /// Bottom-right pane.
+const sal_uInt8 EXC_PANE_TOPRIGHT = 1; /// Right, or top-right pane.
+const sal_uInt8 EXC_PANE_BOTTOMLEFT = 2; /// Bottom, or bottom-left pane.
+const sal_uInt8 EXC_PANE_TOPLEFT = 3; /// Single, top, left, or top-left pane.
+
+// (0x00A0) SCL ---------------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SCL = 0x00A0;
+
+// (0x0862) SHEETEXT ----------------------------------------------------------
+
+const sal_uInt16 EXC_ID_SHEETEXT = 0x0862; /// header id for sheetext
+const sal_uInt8 EXC_SHEETEXT_TABCOLOR = 0x7F; /// mask for tab color
+const sal_uInt16 EXC_COLOR_NOTABBG = 0x7F; /// Excel ignores Tab color when set to this value...
+// Structs ====================================================================
+
+/** Contains all view settings for the entire document. */
+struct XclDocViewData
+{
+ sal_uInt16 mnWinX; /// X position of the document window (twips).
+ sal_uInt16 mnWinY; /// Y position of the document window (twips).
+ sal_uInt16 mnWinWidth; /// Width of the document window (twips).
+ sal_uInt16 mnWinHeight; /// Height of the document window (twips).
+ sal_uInt16 mnFlags; /// Additional flags.
+ sal_uInt16 mnDisplXclTab; /// Displayed (active) sheet.
+ sal_uInt16 mnFirstVisXclTab; /// First visible sheet.
+ sal_uInt16 mnXclSelectCnt; /// Number of selected sheets.
+ sal_uInt16 mnTabBarWidth; /// Width of sheet tabbar (1/1000 of window width).
+
+ explicit XclDocViewData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all settings for a selection in a single pane of a sheet. */
+struct XclSelectionData
+{
+ XclAddress maXclCursor; /// Cell cursor position.
+ XclRangeList maXclSelection; /// Selected cell ranges.
+ sal_uInt16 mnCursorIdx; /// Index of cursor in selection list.
+
+ inline explicit XclSelectionData() : mnCursorIdx( 0 ) {}
+};
+
+typedef boost::shared_ptr< XclSelectionData > XclSelectionDataRef;
+
+// ----------------------------------------------------------------------------
+
+/** Contains all view settings for a single sheet. */
+struct XclTabViewData
+{
+ typedef ::std::map< sal_uInt8, XclSelectionDataRef > XclSelectionMap;
+
+ XclSelectionMap maSelMap; /// Selections of all panes.
+ Color maGridColor; /// Grid color.
+ XclAddress maFirstXclPos; /// First visible cell.
+ XclAddress maSecondXclPos; /// First visible cell in additional panes.
+ sal_uInt16 mnSplitX; /// Split X position, or number of frozen columns.
+ sal_uInt32 mnSplitY; /// Split Y position, or number of frozen rows.
+ sal_uInt16 mnNormalZoom; /// Zoom factor for normal view.
+ sal_uInt16 mnPageZoom; /// Zoom factor for pagebreak preview.
+ sal_uInt16 mnCurrentZoom; /// Zoom factor for current view.
+ sal_uInt8 mnActivePane; /// Active pane (with cell cursor).
+ bool mbSelected; /// true = Sheet is selected.
+ bool mbDisplayed; /// true = Sheet is displayed (active).
+ bool mbMirrored; /// true = Mirrored (right-to-left) sheet.
+ bool mbFrozenPanes; /// true = Frozen panes; false = split window.
+ bool mbPageMode; /// true = Pagebreak preview; false = Normal view.
+ 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.
+ Color maTabBgColor; /// Tab Color default = (COL_AUTO )
+ bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? sal_True : false; };
+ sal_uInt32 mnTabBgColorId; /// pallette color id
+
+ explicit XclTabViewData();
+ ~XclTabViewData();
+
+ /** Sets Excel default view settings. */
+ void SetDefaults();
+
+ /** Returns true, if the window is split in any direction. */
+ bool IsSplit() const;
+ /** Returns true, if the specified pane (EXC_PANE_*) is available. */
+ bool HasPane( sal_uInt8 nPaneId ) const;
+
+ /** Returns the selection data, if available, otherwise 0. */
+ const XclSelectionData* GetSelectionData( sal_uInt8 nPane ) const;
+ /** Returns read/write access to the selection data of the specified pane. */
+ XclSelectionData& CreateSelectionData( sal_uInt8 nPane );
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/expop.cxx b/sc/source/filter/lotus/expop.cxx
new file mode 100644
index 000000000000..e1bd599c29cd
--- /dev/null
+++ b/sc/source/filter/lotus/expop.cxx
@@ -0,0 +1,414 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+
+#include "exp_op.hxx"
+
+#if ENABLE_LOTUS123_EXPORT
+const sal_uInt16 ExportWK1::WK1MAXCOL = 255;
+const sal_uInt16 ExportWK1::WK1MAXROW = 8191;
+
+sal_uInt8 ExportWK1::GenFormByte( const ScPatternAttr& /*aAttr*/ )
+{
+ return 0xFF;
+}
+
+
+inline void ExportWK1::Bof()
+{ // (0x00)
+ aOut << ( sal_uInt16 ) 0x00 << ( sal_uInt16 ) 2 << ( sal_uInt16 ) 0x0406; // Version 1-2-3/2, Symhony/1.1
+}
+
+
+inline void ExportWK1::Eof()
+{ // (0x01)
+ aOut << ( sal_uInt16 ) 0x01 << ( sal_uInt16 ) 0;
+}
+
+
+inline void ExportWK1::Calcmode()
+{ // (0x02)
+ // Calculationmode = automatic
+ aOut << ( sal_uInt16 ) 0x02 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0xFF;
+}
+
+
+inline void ExportWK1::Calcorder()
+{ // (0x03)
+ // order = natural
+ aOut << ( sal_uInt16 ) 0x03 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Split()
+{ // (0x04)
+ // not split
+ aOut << ( sal_uInt16 ) 0x04 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Sync()
+{ // (0x05)
+ // not synchronized
+ aOut << ( sal_uInt16 ) 0x05 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Dimensions()
+{ // (0x06)
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aOut << ( sal_uInt16 ) 0x06 << ( sal_uInt16 ) 8 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0; // Starting Col/Row
+ pD->GetPrintArea( 0, nEndCol, nEndRow );
+#if SC_ROWLIMIT_MORE_THAN_64K
+#error row limit 64k
+#endif
+ sal_uInt16 nCol = static_cast<sal_uInt16>(nEndCol);
+ sal_uInt16 nRow = static_cast<sal_uInt16>(nEndRow);
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Dimensions(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Dimensions(): Row > WK1MAXROW" );
+ aOut << nCol << nRow; // Ending Col/Row
+}
+
+
+inline void ExportWK1::Window1()
+{ // (0x07)
+ aOut << ( sal_uInt16 ) 0x07 << ( sal_uInt16 ) 32
+ << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Cursor Col/Row
+ << ( sal_uInt8 ) 0xFF // Format: protected, special, default
+ << ( sal_uInt8 ) 0 // Dummy
+ << ( sal_uInt16 ) 9 // Default column width
+ << ( sal_uInt16 ) 8 << ( sal_uInt16 ) 14// Number of cols/rows on screen
+ << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left col / top row
+ // Rest aus Doku-Beispiel
+ << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Number of title cols / rows
+ << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left title col / top title row
+ << ( sal_uInt16 ) 0x0004 << ( sal_uInt16 ) 0x0004// Top-left col / row
+ << ( sal_uInt16 ) 0x0048 // Number of cols in window
+ << ( sal_uInt16 ) 0x00; // Dummy
+}
+
+
+inline void ExportWK1::Colw()
+{ // (0x08)
+ // ACHTUNG: muss nach Window1 und vor hidden cols record kommen!
+ sal_uInt16 nWidth;
+ sal_uInt8 nWidthSpaces;
+ for( sal_uInt16 nCol = 0 ; nCol < 256 ; nCol++ )
+ {
+ nWidth = pD->GetColWidth( static_cast<SCCOL>(nCol), 0 );
+ nWidthSpaces = ( sal_uInt8 ) ( nWidth / TWIPS_PER_CHAR );
+ aOut << ( sal_uInt16 ) 0x08 << ( sal_uInt16 ) 3 << nCol << nWidthSpaces;
+ }
+}
+
+
+void ExportWK1::Blank( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScPatternAttr& aAttr )
+{ // (0x0C)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Blank(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Blank(): Row > WK1MAXROW" );
+
+ aOut << ( sal_uInt16 ) 0x0C << ( sal_uInt16 ) 5 << GenFormByte( aAttr ) << nCol << nRow;
+}
+
+
+void ExportWK1::Number( const sal_uInt16 nCol, const sal_uInt16 nRow, const double fWert, const ScPatternAttr &aAttr )
+{ // (0x0E)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Number(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Number(): Row > WK1MAXROW" );
+
+ aOut << ( sal_uInt16 ) 0x0E << ( sal_uInt16 ) 13 << GenFormByte( aAttr ) << nCol << nRow << fWert;
+}
+
+
+void ExportWK1::Label( const sal_uInt16 nCol, const sal_uInt16 nRow, const String& rStr, const ScPatternAttr& aAttr )
+{ // (0x0F)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
+
+ ByteString aStr( rStr, eZielChar );
+
+ sal_uInt16 nLaenge = 7; // Anzahl Bytes vor String+Nullbyte am Ende + Alignment-Char
+
+ xub_StrLen nAnz = aStr.Len();
+
+
+ if( nAnz > 240 ) // max. 240 Zeichen im String
+ nAnz = 240;
+
+ nLaenge = nLaenge + ( sal_uInt16 ) nAnz; // + Stringlaenge
+
+ aOut << ( sal_uInt16 ) 0x0F << nLaenge << GenFormByte( aAttr ) << nCol << nRow << ( sal_Char ) '\'';
+ // ACHTUNG: ZUNAECHST NUR LEFT ALIGNMENT
+
+ aOut.Write( aStr.GetBuffer(), nAnz );
+
+ aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
+}
+
+
+void ExportWK1::Formula( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScFormulaCell* pFC, const ScPatternAttr& aAttr )
+{ // (0x10)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+ DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Formula(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Formula(): Row > WK1MAXROW" );
+
+ sal_uInt16 nLaenge = 15; // Bytes bis Formel
+ double fErgebnis;
+
+ // zunaechst nur Dummy-Angaben (Formel := Ergebnis der Berechnung )
+ nLaenge += 9+1;
+
+ fErgebnis = ( ( ScFormulaCell* ) pFC )->GetValue();
+
+ aOut << ( sal_uInt16 ) 0x10 << ( sal_uInt16 ) nLaenge
+ << GenFormByte( aAttr ) << nCol << nRow
+ << fErgebnis
+ << ( sal_uInt16 ) 9+1 // Dummy-Formula-Size
+ << ( sal_uInt8 ) 0x00 // constant, floating point
+ << fErgebnis
+ << ( sal_uInt8 ) 0x03; // return
+}
+
+
+inline void ExportWK1::Protect()
+{ // (0x24)
+ //Global protection off
+ aOut << ( sal_uInt16 ) 0x24 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Footer()
+{ // (0x25)
+ // zunaechst nur leerer C-String
+ aOut << ( sal_uInt16 ) 0x25 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
+ for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
+ aOut << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Header()
+{ // (0x26)
+ // zunaechst nur leerer C-String
+ aOut << ( sal_uInt16 ) 0x26 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
+ for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
+ aOut << ( sal_uInt8 ) 0x00;
+}
+
+
+inline void ExportWK1::Margins()
+{ // (0x28)
+ aOut << ( sal_uInt16 ) 0x28 << ( sal_uInt16 ) 10
+ << ( sal_uInt16 ) 4 << ( sal_uInt16 ) 76 // Left/right margin
+ << ( sal_uInt16 ) 66 // Page length
+ << ( sal_uInt16 ) 2 << ( sal_uInt16 ) 2; // Top/Bottom margin
+}
+
+
+inline void ExportWK1::Labelfmt()
+{ // (0x29)
+ // Global label alignment = left
+ aOut << ( sal_uInt16 ) 0x29 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x27;
+}
+
+
+inline void ExportWK1::Calccount()
+{ // (0x2F)
+ // Iteration count = 16 (oder so aehnlich)
+ aOut << ( sal_uInt16 ) 0x2F << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 16;
+}
+
+
+inline void ExportWK1::Cursorw12()
+{ // (0x31)
+ // Cursor location in window 1
+ aOut << ( sal_uInt16 ) 0x31 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 1;
+}
+
+
+void ExportWK1::WKString( const sal_uInt16 /*nCol*/, const sal_uInt16 /*nRow*/, const ScFormulaCell* /*pFC*/, const ScPatternAttr& /*aAttr*/ )
+{ // (0x33)
+ // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
+/* DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
+ DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
+
+ String aStr;
+ ( ( ScFormulaCell * ) pFC )->GetString( aStr ); // Formeltext zunaechst so belassen
+
+ sal_uInt16 nLaenge = 6; // Anzahl Bytes vor String+Nullbyte am Ende
+
+ sal_uInt16 nAnz = aStr.Len();
+
+ if( nAnz > 240 ) // max. 240 Zeichen im String
+ nAnz = 240;
+
+ nLaenge += nAnz; // + Stringlaenge
+
+ aOut << ( sal_uInt16 ) 0x33 << nLaenge
+ << GenFormByte( aAttr ) << nCol << nRow;
+
+ // Zeichenweise String ausgeben
+ for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ aOut << aStr[ nLauf ];
+
+ aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
+*/
+ }
+
+
+inline void ExportWK1::Snrange()
+{ // (0x47)
+ //aOut << ( sal_uInt16 ) 0x47 << ( sal_uInt16 ) x
+/* ScRangeName *pRanges = pD->GetRangeName();
+ ScRangeData *pData;
+ String aName;
+
+ sal_uInt16 nAnz = pRanges->GetCount();
+
+ for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ {
+ pData = pRanges[ nLauf ];
+
+ }
+*/
+}
+
+
+inline void ExportWK1::Hidcol()
+{ // (0x64)
+ sal_uInt32 nHide = 0x00000000; // ...niemand ist versteckt
+
+ aOut << ( sal_uInt16 ) 0x64 << ( sal_uInt16 ) 32;
+
+ for( int nLauf = 0 ; nLauf < 8 ; nLauf++ )
+ aOut << nHide; // 8 * 32 Bits = 256
+}
+
+
+inline void ExportWK1::Cpi()
+{ // (0x96)
+ //aOut << ( sal_uInt16 ) 0x96 << ( sal_uInt16 ) x;
+}
+
+
+FltError ExportWK1::Write()
+{
+ Bof();
+ //Dimensions();
+ //Cpi();
+ //Calccount();
+ //Calcmode();
+ //Calcorder();
+ //Split();
+ //Sync();
+ //Window1();
+ Colw();
+ //Hidcol();
+ //Cursorw12();
+ //Snrange();
+ //Protect();
+ //Footer();
+ //Header();
+ //Margins();
+ //Labelfmt();
+
+ // Zellen-Bemachung
+ ScDocumentIterator aIter( pD, 0, 0 );
+ ScBaseCell* pCell;
+ sal_uInt16 nCol, nRow;
+ SCTAB nTab;
+ const ScPatternAttr* pPatAttr;
+
+ if( aIter.GetFirst() )
+ do
+ { // ueber alle Zellen der ersten Tabelle iterieren
+ pPatAttr = aIter.GetPattern();
+ pCell = aIter.GetCell();
+ SCCOL nScCol;
+ SCROW nScRow;
+ aIter.GetPos( nScCol, nScRow, nTab );
+#if SC_ROWLIMIT_MORE_THAN_64K
+#error row limit 64k
+#endif
+ nCol = static_cast<sal_uInt16>(nScCol);
+ nRow = static_cast<sal_uInt16>(nScRow);
+
+ switch( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ double fVal;
+ fVal = ( ( ScValueCell * ) pCell)->GetValue();
+ Number( nCol, nRow, fVal, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_STRING:
+ {
+ String aStr;
+ ( ( ScStringCell * ) pCell)->GetString( aStr );
+ Label( nCol, nRow, aStr, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ Formula( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
+ WKString( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
+ }
+ break;
+ case CELLTYPE_NOTE:
+ case CELLTYPE_NONE:
+ break;
+ default:
+ DBG_ASSERT( false, "ExportWK1::Write(): unbekannter Celltype!" );
+ }
+ }
+ while( aIter.GetNext() );
+
+ Eof();
+
+ return eERR_OK;
+}
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/export.cxx b/sc/source/filter/lotus/export.cxx
new file mode 100644
index 000000000000..5ca8cc7c6f49
--- /dev/null
+++ b/sc/source/filter/lotus/export.cxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "scerrors.hxx"
+#include "exp_op.hxx"
+
+#if ENABLE_LOTUS123_EXPORT
+FltError ScFormatFilterPluginImpl::ScExportLotus123( SvStream& aStream, ScDocument* pDoc, ExportFormatLotus eFormat, CharSet eDest )
+{
+ switch( eFormat )
+ {
+ case ExpWK1:
+ {
+ ExportWK1 aWKFile( aStream, pDoc, eDest );
+ aWKFile.Write();
+ }
+ break;
+ case ExpWK3:
+ return eERR_NI;
+ default:
+ return eERR_NI;
+ }
+
+ return eERR_OK;
+}
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/filter.cxx b/sc/source/filter/lotus/filter.cxx
new file mode 100644
index 000000000000..c3f53b5eb615
--- /dev/null
+++ b/sc/source/filter/lotus/filter.cxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// Das geht: Versionserkennung WKS, WK1 und WK3
+// ...Rest steht in op.cpp
+
+//------------------------------------------------------------------------
+
+#include <tools/solar.h>
+#include <string.h>
+#include <map>
+
+#include "filter.hxx"
+#include "document.hxx"
+#include "compiler.hxx"
+#include "scerrors.hxx"
+
+#include "root.hxx"
+#include "lotrange.hxx"
+#include "optab.h"
+#include "scmem.h"
+#include "decl.h"
+#include "tool.h"
+
+#include "fprogressbar.hxx"
+
+#include "op.h"
+
+// Konstanten ------------------------------------------------------------
+const sal_uInt16 nBOF = 0x0000;
+
+
+
+// externe Variablen -----------------------------------------------------
+extern WKTYP eTyp; // Typ der gerade in bearbeitung befindlichen Datei
+WKTYP eTyp;
+
+extern sal_Bool bEOF; // zeigt Ende der Datei
+sal_Bool bEOF;
+
+extern CharSet eCharNach; // Zeichenkonvertierung von->nach
+CharSet eCharNach;
+
+extern CharSet eCharVon;
+CharSet eCharVon;
+
+extern ScDocument* pDoc; // Aufhaenger zum Dokumentzugriff
+ScDocument* pDoc;
+
+
+extern sal_Char* pPuffer; // -> memory.cxx
+extern sal_Char* pDummy1; // -> memory.cxx
+
+extern OPCODE_FKT pOpFkt[ FKT_LIMIT ];
+ // -> optab.cxx, Tabelle moeglicher Opcodes
+extern OPCODE_FKT pOpFkt123[ FKT_LIMIT123 ];
+ // -> optab.cxx, Table of possible Opcodes
+
+extern long nDateiLaenge; // -> datei.cpp, ...der gerade offenen Datei
+
+LOTUS_ROOT* pLotusRoot = NULL;
+
+
+std::map<sal_uInt16, ScPatternAttr> aLotusPatternPool;
+
+static FltError
+generate_Opcodes( SvStream& aStream, ScDocument& rDoc,
+ ScfStreamProgressBar& aPrgrsBar, WKTYP eType )
+{
+ OPCODE_FKT *pOps;
+ int nOps;
+
+ switch(eType)
+ {
+ case eWK_1:
+ case eWK_2:
+ pOps = pOpFkt;
+ nOps = FKT_LIMIT;
+ break;
+ case eWK123:
+ pOps = pOpFkt123;
+ nOps = FKT_LIMIT123;
+ break;
+ case eWK3: return eERR_NI;
+ case eWK_Error: return eERR_FORMAT;
+ default: return eERR_UNKN_WK;
+ }
+
+ // #i76299# seems that SvStream::IsEof() does not work correctly
+ aStream.Seek( STREAM_SEEK_TO_END );
+ sal_Size nStrmSize = aStream.Tell();
+ aStream.Seek( STREAM_SEEK_TO_BEGIN );
+ while( !bEOF && !aStream.IsEof() && (aStream.Tell() < nStrmSize) )
+ {
+ sal_uInt16 nOpcode, nLength;
+
+ aStream >> nOpcode >> nLength;
+ aPrgrsBar.Progress();
+ if( nOpcode == LOTUS_EOF )
+ bEOF = sal_True;
+
+ else if( nOpcode == LOTUS_FILEPASSWD )
+ return eERR_FILEPASSWD;
+
+ else if( nOpcode < nOps )
+ pOps[ nOpcode ] ( aStream, nLength );
+
+ else if( eType == eWK123 &&
+ nOpcode == LOTUS_PATTERN )
+ {
+ // This is really ugly - needs re-factoring ...
+ aStream.SeekRel(nLength);
+ aStream >> nOpcode >> nLength;
+ if ( nOpcode == 0x29a)
+ {
+ aStream.SeekRel(nLength);
+ aStream >> nOpcode >> nLength;
+ if ( nOpcode == 0x804 )
+ {
+ aStream.SeekRel(nLength);
+ OP_ApplyPatternArea123(aStream);
+ }
+ else
+ aStream.SeekRel(nLength);
+ }
+ else
+ aStream.SeekRel(nLength);
+ }
+ else
+ aStream.SeekRel( nLength );
+ }
+
+ MemDelete();
+
+ rDoc.CalcAfterLoad();
+
+ return eERR_OK;
+}
+
+WKTYP ScanVersion( SvStream& aStream )
+{
+ // PREC: pWKDatei: Zeiger auf offene Datei
+ // POST: return: Typ der Datei
+ sal_uInt16 nOpcode, nVersNr, nRecLen;
+
+ // erstes Byte muss wegen BOF zwingend 0 sein!
+ aStream >> nOpcode;
+ if( nOpcode != nBOF )
+ return eWK_UNKNOWN;
+
+ aStream >> nRecLen >> nVersNr;
+
+ if( aStream.IsEof() )
+ return eWK_Error;
+
+ switch( nVersNr )
+ {
+ case 0x0404:
+ if( nRecLen == 2 )
+ return eWK_1;
+ else
+ return eWK_UNKNOWN;
+
+ case 0x0406:
+ if( nRecLen == 2 )
+ return eWK_2;
+ else
+ return eWK_UNKNOWN;
+
+ case 0x1000:
+ aStream >> nVersNr;
+ if( aStream.IsEof() ) return eWK_Error;
+ if( nVersNr == 0x0004 && nRecLen == 26 )
+ { // 4 Bytes von 26 gelesen->22 ueberlesen
+ aStream.Read( pDummy1, 22 );
+ return eWK3;
+ }
+ break;
+ case 0x1003:
+ if( nRecLen == 0x1a )
+ return eWK123;
+ else
+ return eWK_UNKNOWN;
+ case 0x1005:
+ if( nRecLen == 0x1a )
+ return eWK123;
+ else
+ return eWK_UNKNOWN;
+ }
+
+ return eWK_UNKNOWN;
+}
+
+FltError ScImportLotus123old( SvStream& aStream, ScDocument* pDocument, CharSet eSrc )
+{
+ aStream.Seek( 0UL );
+
+ // Zeiger auf Dokument global machen
+ pDoc = pDocument;
+
+ bEOF = false;
+
+ eCharVon = eSrc;
+
+ // Speicher besorgen
+ if( !MemNew() )
+ return eERR_NOMEM;
+
+ InitPage(); // Seitenformat initialisieren (nur Tab 0!)
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( aStream, pDocument->GetDocumentShell() );
+
+ // Datei-Typ ermitteln
+ eTyp = ScanVersion( aStream );
+
+ aLotusPatternPool.clear();
+
+ return generate_Opcodes( aStream, *pDoc, aPrgrsBar, eTyp );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx
new file mode 100644
index 000000000000..6e1a8519c1a6
--- /dev/null
+++ b/sc/source/filter/lotus/lotattr.cxx
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "lotattr.hxx"
+
+#include <boost/bind.hpp>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svx/algitem.hxx>
+
+#include "attrib.hxx"
+#include "docpool.hxx"
+#include "document.hxx"
+#include "lotfntbf.hxx"
+#include "patattr.hxx"
+#include "root.hxx"
+#include "scitems.hxx"
+
+LotAttrCache::ENTRY::ENTRY (const ScPatternAttr &r)
+ : pPattAttr(new ScPatternAttr(r))
+{
+}
+
+LotAttrCache::ENTRY::ENTRY (ScPatternAttr* p)
+ : pPattAttr(p)
+{
+}
+
+LotAttrCache::ENTRY::~ENTRY ()
+{
+ delete pPattAttr;
+}
+
+LotAttrCache::LotAttrCache ()
+{
+ pDocPool = pLotusRoot->pDoc->GetPool();
+
+ pColTab = new Color [ 8 ];
+ pColTab[ 0 ] = Color( COL_WHITE );
+ pColTab[ 1 ] = Color( COL_LIGHTBLUE );
+ pColTab[ 2 ] = Color( COL_LIGHTGREEN );
+ pColTab[ 3 ] = Color( COL_LIGHTCYAN );
+ pColTab[ 4 ] = Color( COL_LIGHTRED );
+ pColTab[ 5 ] = Color( COL_LIGHTMAGENTA );
+ pColTab[ 6 ] = Color( COL_YELLOW );
+ pColTab[ 7 ] = Color( COL_BLACK );
+
+ ppColorItems[ 0 ] = new SvxColorItem( GetColor( 1 ), ATTR_FONT_COLOR ); // 1
+ ppColorItems[ 1 ] = new SvxColorItem( GetColor( 2 ), ATTR_FONT_COLOR );
+ ppColorItems[ 2 ] = new SvxColorItem( GetColor( 3 ), ATTR_FONT_COLOR );
+ ppColorItems[ 3 ] = new SvxColorItem( GetColor( 4 ), ATTR_FONT_COLOR );
+ ppColorItems[ 4 ] = new SvxColorItem( GetColor( 5 ), ATTR_FONT_COLOR );
+ ppColorItems[ 5 ] = new SvxColorItem( GetColor( 6 ), ATTR_FONT_COLOR ); // 6
+
+ pBlack = new SvxColorItem( Color( COL_BLACK ), ATTR_FONT_COLOR );
+ pWhite = new SvxColorItem( Color( COL_WHITE ), ATTR_FONT_COLOR );
+}
+
+
+LotAttrCache::~LotAttrCache()
+{
+ for( sal_uInt16 nCnt = 0 ; nCnt < 6 ; nCnt++ )
+ delete ppColorItems[ nCnt ];
+
+ delete pBlack;
+ delete pWhite;
+
+ delete[] pColTab;
+}
+
+
+const ScPatternAttr& LotAttrCache::GetPattAttr( const LotAttrWK3& rAttr )
+{
+ sal_uInt32 nRefHash;
+ MakeHash( rAttr, nRefHash );
+
+ boost::ptr_vector<ENTRY>::const_iterator iter = std::find_if(aEntries.begin(),aEntries.end(),
+ boost::bind(&ENTRY::nHash0,_1) == nRefHash);
+
+ if (iter != aEntries.end())
+ return *(iter->pPattAttr);
+
+ // neues PatternAttribute erzeugen
+ ScPatternAttr* pNewPatt = new ScPatternAttr(pDocPool);
+
+ SfxItemSet& rItemSet = pNewPatt->GetItemSet();
+ ENTRY *pAkt = new ENTRY( pNewPatt );
+
+ pAkt->nHash0 = nRefHash;
+
+ pLotusRoot->pFontBuff->Fill( rAttr.nFont, rItemSet );
+
+ sal_uInt8 nLine = rAttr.nLineStyle;
+ if( nLine )
+ {
+ SvxBoxItem aBox( ATTR_BORDER );
+ ::editeng::SvxBorderLine aTop, aLeft, aBottom, aRight;
+
+ LotusToScBorderLine( nLine, aLeft );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aRight );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aTop );
+ nLine >>= 2;
+ LotusToScBorderLine( nLine, aBottom );
+
+ aBox.SetLine( &aTop, BOX_LINE_TOP );
+ aBox.SetLine( &aLeft, BOX_LINE_LEFT );
+ aBox.SetLine( &aBottom, BOX_LINE_BOTTOM );
+ aBox.SetLine( &aRight, BOX_LINE_RIGHT );
+
+ rItemSet.Put( aBox );
+ }
+
+ sal_uInt8 nFontCol = rAttr.nFontCol & 0x07;
+ if( nFontCol )
+ {
+ // nFontCol > 0
+ if( nFontCol < 7 )
+ rItemSet.Put( GetColorItem( nFontCol ) );
+ else
+ rItemSet.Put( *pWhite );
+ }
+
+ sal_uInt8 nBack = rAttr.nBack & 0x1F;
+ if( nBack )
+ rItemSet.Put( SvxBrushItem( GetColor( nBack & 0x07 ), ATTR_BACKGROUND ) );
+
+ if( rAttr.nBack & 0x80 )
+ {
+ SvxHorJustifyItem aHorJustify(SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY );
+ rItemSet.Put( aHorJustify );
+ }
+
+ aEntries.push_back(pAkt);
+
+ return *pNewPatt;
+}
+
+
+void LotAttrCache::LotusToScBorderLine( sal_uInt8 nLine, ::editeng::SvxBorderLine& aBL )
+{
+ nLine &= 0x03;
+
+ switch ( nLine )
+ {
+ default:
+ case 0: aBL.SetStyle( ::editeng::NO_STYLE ); break;
+ case 1: aBL.SetWidth( DEF_LINE_WIDTH_1 ); break;
+ case 2: aBL.SetWidth( DEF_LINE_WIDTH_2 ); break;
+ case 3:
+ {
+ aBL.SetStyle( ::editeng::DOUBLE );
+ aBL.SetWidth( DEF_LINE_WIDTH_1 );
+ }
+ break;
+ }
+}
+
+const SvxColorItem& LotAttrCache::GetColorItem( const sal_uInt8 nLotIndex ) const
+{
+ DBG_ASSERT( nLotIndex > 0 && nLotIndex < 7,
+ "-LotAttrCache::GetColorItem(): so nicht!" );
+
+ return *ppColorItems[ nLotIndex - 1 ];
+}
+
+const Color& LotAttrCache::GetColor( const sal_uInt8 nLotIndex ) const
+{
+ // Farbe <-> Index passt fuer Background, nicht aber fuer Fonts (0 <-> 7)!
+ DBG_ASSERT( nLotIndex < 8, "*LotAttrCache::GetColor(): Index > 7!" );
+
+ return pColTab[ nLotIndex ];
+}
+
+void LotAttrCol::SetAttr( const SCROW nRow, const ScPatternAttr& rAttr )
+{
+ DBG_ASSERT( ValidRow(nRow), "*LotAttrCol::SetAttr(): ... und rums?!" );
+
+ boost::ptr_vector<ENTRY>::reverse_iterator iterLast = aEntries.rbegin();
+
+ if(iterLast != aEntries.rend())
+ {
+ if( ( iterLast->nLastRow == nRow - 1 ) && ( &rAttr == iterLast->pPattAttr ) )
+ iterLast->nLastRow = nRow;
+ else
+ {
+ ENTRY *pAkt = new ENTRY;
+
+ pAkt->pPattAttr = &rAttr;
+ pAkt->nFirstRow = pAkt->nLastRow = nRow;
+
+ aEntries.push_back(pAkt);
+ }
+ }
+ else
+ { // erster Eintrag
+ ENTRY *pAkt = new ENTRY;
+ pAkt->pPattAttr = &rAttr;
+ pAkt->nFirstRow = pAkt->nLastRow = nRow;
+
+ aEntries.push_back(pAkt);
+ }
+}
+
+
+void LotAttrCol::Apply( const SCCOL nColNum, const SCTAB nTabNum, const sal_Bool /*bClear*/ )
+{
+ ScDocument* pDoc = pLotusRoot->pDoc;
+
+ boost::ptr_vector<ENTRY>::iterator iter;
+ for (iter = aEntries.begin(); iter != aEntries.end(); ++iter)
+ {
+ pDoc->ApplyPatternAreaTab(nColNum,iter->nFirstRow,nColNum,iter->nLastRow,
+ nTabNum, *(iter->pPattAttr));
+ }
+}
+
+
+void LotAttrCol::Clear ()
+{
+ aEntries.clear();
+}
+
+void LotAttrTable::SetAttr( const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow,
+ const LotAttrWK3& rAttr )
+{
+ const ScPatternAttr &rPattAttr = aAttrCache.GetPattAttr( rAttr );
+ SCCOL nColCnt;
+
+ for( nColCnt = nColFirst ; nColCnt <= nColLast ; nColCnt++ )
+ pCols[ nColCnt ].SetAttr( nRow, rPattAttr );
+}
+
+
+void LotAttrTable::Apply( const SCTAB nTabNum )
+{
+ SCCOL nColCnt;
+ for( nColCnt = 0 ; nColCnt <= MAXCOL ; nColCnt++ )
+ pCols[ nColCnt ].Apply( nColCnt, nTabNum ); // macht auch gleich ein Clear() am Ende
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/lotform.cxx b/sc/source/filter/lotus/lotform.cxx
new file mode 100644
index 000000000000..589b291864cb
--- /dev/null
+++ b/sc/source/filter/lotus/lotform.cxx
@@ -0,0 +1,2076 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "decl.h"
+#include "lotform.hxx"
+#include "compiler.hxx"
+#include "lotrange.hxx"
+#include "namebuff.hxx"
+#include "root.hxx"
+#include "ftools.hxx"
+#include "tool.h"
+
+#include <math.h>
+
+extern WKTYP eTyp;
+
+static const sal_Char* GetAddInName( const sal_uInt8 nIndex );
+
+static DefTokenId lcl_KnownAddIn( const ByteString& sTest );
+
+//extern double decipher_Number123( sal_uInt32 nValue );
+
+
+void LotusToSc::DoFunc( DefTokenId eOc, sal_uInt8 nAnz, const sal_Char* pExtString )
+{
+ TokenId eParam[ 256 ];
+ sal_Int32 nLauf;
+ TokenId nMerk0, nMerk1;
+
+ sal_Bool bAddIn = false;
+ sal_Bool bNeg = false;
+
+ DBG_ASSERT( nAnz < 128, "-LotusToSc::DoFunc(): Neee! -so viel kann ich nicht!" );
+
+ if( eOc == ocNoName )
+ {
+ ByteString t;
+ if( pExtString )
+ {
+ const ByteString s( "@<<@123>>" );
+
+ t = pExtString;
+
+ xub_StrLen n = t.Search( s );
+ if( n != STRING_NOTFOUND )
+ t.Erase( 0, n + s.Len() );
+
+ t.EraseTrailingChars( '(' );
+
+ eOc = lcl_KnownAddIn( t );
+
+ if( eOc == ocNoName )
+ t.Insert( "L123_", 0 );
+ }
+ else
+ t = "#UNKNOWN FUNC NAME#";
+
+ if( eOc == ocNoName )
+ {
+ bAddIn = sal_True;
+ nMerk0 = aPool.Store( eOc, String( t, eSrcChar ) );
+
+ aPool << nMerk0;
+ }
+ }
+
+ for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ aStack >> eParam[ nLauf ];
+
+ // Spezialfaelle...
+ switch( eOc )
+ {
+ case ocIndex:
+ DBG_ASSERT( nAnz > 2, "+LotusToSc::DoFunc(): ocIndex braucht mind. 2 Parameter!" );
+ nMerk0 = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nMerk0;
+ IncToken( eParam[ 0 ] );
+ IncToken( eParam[ 1 ] );
+ break;
+ case ocIRR:
+ {
+ DBG_ASSERT( nAnz == 2, "+LotusToSc::DoFunc(): ocIRR hat nur 2 Parameter!" );
+ nMerk0 = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nMerk0;
+ }
+ break;
+ case ocGetYear:
+ {
+ nMerk0 = aPool.Store( 1900.0 );
+ aPool << ocOpen;
+ }
+ break;
+ case ocChose:
+ {// 1. Parameter ++
+ IncToken( eParam[ nAnz - 1 ] );
+ }
+ break;
+ case ocFind:
+ case ocHLookup:
+ case ocVLookup:
+ {// letzten Parameter ++
+ IncToken( eParam[ 0 ] );
+ }
+ break;
+ case ocMid:
+ case ocReplace:
+ {// 2. Parameter ++
+ IncToken( eParam[ nAnz - 2 ] );
+ }
+ break;
+ case ocZins:
+ {
+ // neue Anzahl = 4!
+ DBG_ASSERT( nAnz == 3,
+ "*LotusToSc::DoFunc(): ZINS() hat 3 Parameter!" );
+ nAnz = 4;
+ eParam[ 3 ] = eParam[ 0 ]; // 3. -> 1.
+ eParam[ 0 ] = eParam[ 2 ]; // 1. -> 4.
+ NegToken( eParam[ 1 ] ); // 2. -> -2. (+ 2. -> 3.)
+ eParam[ 2 ] = n0Token; // -> 2. als Default
+ }
+ break;
+ default:;
+ }
+ // ................
+
+
+ if( !bAddIn )
+ aPool << eOc;
+
+ aPool << ocOpen;
+
+ if( nAnz > 0 )
+ {
+ // ACHTUNG: 0 ist der letzte Parameter, nAnz-1 der erste
+
+ sal_Int16 nLast = nAnz - 1;
+
+ if( eOc == ocRMZ )
+ { // Extrawurst ocRMZ letzter Parameter negiert!
+ // zusaetzlich: 1. -> 3., 3. -> 2., 2. -> 1.
+ DBG_ASSERT( nAnz == 3,
+ "+LotusToSc::DoFunc(): ocRMZ hat genau 3 Parameter!" );
+ aPool << eParam[ 1 ] << ocSep << eParam[ 0 ] << ocSep
+ << ocNegSub << eParam[ 2 ];
+ }
+ else
+ { // Normalfall
+ // [Parameter{;Parameter}]
+ aPool << eParam[ nLast ];
+
+ sal_Int16 nNull = -1; // gibt einen auszulassenden Parameter an
+ for( nLauf = nLast - 1 ; nLauf >= 0 ; nLauf-- )
+ {
+ if( nLauf != nNull )
+ aPool << ocSep << eParam[ nLauf ];
+ }
+ }
+ }
+
+
+ // Spezialfaelle...
+ if( eOc == ocGetYear )
+ {
+ aPool << ocClose << ocSub << nMerk0;
+ }
+ else if( eOc == ocFixed )
+ {
+ aPool << ocSep << ocTrue << ocOpen << ocClose;
+ }
+ else if( eOc == ocFind )
+ {
+ nMerk1 = aPool.Store();
+ DecToken( nMerk1 );
+ aPool << nMerk1;
+ }
+
+ aPool << ocClose;
+
+ // ................
+
+ aPool >> aStack;
+
+ if( bNeg )
+ {
+ aPool << ocOpen << ocSub << aStack << ocClose;
+ aPool >> aStack;
+ }
+}
+
+
+void LotusToSc::LotusRelToScRel( sal_uInt16 nCol, sal_uInt16 nRow, ScSingleRefData& rSRD )
+{
+ // Col-Bemachung
+ if( nCol & 0x8000 )
+ {
+ rSRD.SetColRel( sal_True );
+ if( nCol & 0x0080 )
+ nCol |= 0xFF00;
+ else
+ nCol &= 0x00FF;
+ // #i36252# first cast unsigned 16-bit to signed 16-bit, and then to SCsCOL
+ rSRD.nRelCol = static_cast< SCsCOL >( static_cast< sal_Int16 >( nCol ) );
+ }
+ else
+ {
+ rSRD.SetColRel( false );
+ rSRD.nCol = static_cast< SCsCOL >( nCol & 0x00FF );
+ }
+
+ // Row-Bemachung
+ if( nRow & 0x8000 )
+ {
+ rSRD.SetRowRel( sal_True );
+ // vorzeichenrichtige Erweiterung
+ switch( eTyp )
+ {
+ // 5432 1098 7654 3210
+ // 8421 8421 8421 8421
+ // xxx xxxx xxxx
+ case eWK_1:
+ if( nRow & 0x0400 )
+ nRow |= 0xF800;
+ else
+ nRow &= 0x07FF;
+ break;
+ // 8421 8421 8421 8421
+ // x xxxx xxxx xxxx
+ case eWK_2:
+ if( nRow & 0x1000 )
+ nRow |= 0xE000;
+ else
+ nRow &= 0x1FFF;
+ break;
+ default:
+ OSL_FAIL( "*LotusToSc::LotusRelToScRel(): etwas vergessen...?" );
+ }
+ }
+ else
+ {
+ rSRD.SetRowRel( false );
+ switch( eTyp )
+ {
+ // 5432 1098 7654 3210
+ // 8421 8421 8421 8421
+ // xxx xxxx xxxx
+ case eWK_1:
+ nRow &= 0x07FF;
+ break;
+ // 8421 8421 8421 8421
+ // xx xxxx xxxx xxxx
+ case eWK_2:
+ nRow &= 0x3FFF;
+ break;
+ default:
+ OSL_FAIL( "*LotusToSc::LotusRelToScRel(): etwas vergessen...?" );
+ }
+ }
+
+ if( rSRD.IsRowRel() )
+ // #i36252# first cast unsigned 16-bit to signed 16-bit, and then to SCsROW
+ rSRD.nRelRow = static_cast< SCsROW >( static_cast< sal_Int16 >( nRow ) );
+ else
+ rSRD.nRow = static_cast< SCsROW >( nRow );
+
+ if( rSRD.IsRowRel() || rSRD.IsColRel() )
+ rSRD.CalcAbsIfRel( aEingPos );
+}
+
+
+void LotusToSc::ReadSRD( ScSingleRefData& rSRD, sal_uInt8 nRelBit )
+{
+ sal_uInt8 nTab, nCol;
+ sal_uInt16 nRow;
+
+ Read( nRow );
+ Read( nTab );
+ Read( nCol );
+
+ sal_Bool b3D = ( static_cast< SCTAB >( nTab ) != aEingPos.Tab() );
+
+ rSRD.SetColRel( ( nRelBit & 0x01 ) != 0 );
+ rSRD.nCol = static_cast< SCsCOL >( nCol );
+
+ rSRD.SetRowRel( ( nRelBit & 0x02 ) != 0 );
+ rSRD.nRow = static_cast< SCsROW >( nRow );
+
+ rSRD.SetTabRel( ( ( nRelBit & 0x04) != 0 ) || !b3D );
+ rSRD.nTab = static_cast< SCsTAB >( nTab );
+
+ rSRD.SetFlag3D( b3D );
+
+ rSRD.CalcRelFromAbs( aEingPos );
+}
+
+
+void LotusToSc::IncToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << nAddToken;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::DecToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << nSubToken;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::NegToken( TokenId &rParam )
+{
+ aPool << ocNegSub << ocOpen << rParam << ocClose;
+ rParam = aPool.Store();
+}
+
+
+void LotusToSc::Reset( const ScAddress& rEingPos )
+{
+ LotusConverterBase::Reset( rEingPos );
+
+ TokenId nEins = aPool.Store( 1.0 );
+
+ aPool << ocClose << ocAdd << nEins;
+ nAddToken = aPool.Store();
+
+ aPool << ocClose << ocSub << nEins;
+ nSubToken = aPool.Store();
+
+ n0Token = aPool.Store( 0.0 );
+}
+
+
+LotusToSc::LotusToSc( SvStream &rStream, CharSet e, sal_Bool b ) :
+ LotusConverterBase( rStream, 128 )
+{
+ eSrcChar = e;
+ bWK3 = false;
+ bWK123 = b;
+}
+
+
+typedef FUNC_TYPE ( FuncType1 ) ( sal_uInt8 );
+typedef DefTokenId ( FuncType2 ) ( sal_uInt8 );
+
+
+ConvErr LotusToSc::Convert( const ScTokenArray*& rpErg, sal_Int32& rRest,
+ const FORMULA_TYPE /*eFT*/ )
+{
+ sal_uInt8 nOc;
+ sal_uInt8 nAnz;
+ sal_uInt8 nRelBits;
+ sal_uInt16 nStrLen;
+ sal_uInt16 nRngIndex;
+ FUNC_TYPE eType = FT_NOP;
+ TokenId nMerk0;
+ DefTokenId eOc;
+ const sal_Char* pExtName = 0;
+ RangeNameBufferWK3& rRangeNameBufferWK3 = *pLotusRoot->pRngNmBffWK3;
+
+ ScComplexRefData aCRD;
+ aCRD.InitFlags();
+ ScSingleRefData& rR = aCRD.Ref1;
+
+ LR_ID nId;
+ TokenId nNewId;
+
+ LotusRangeList& rRangeList = *pLotusRoot->pRangeNames;
+
+ FuncType1* pIndexToType;
+ FuncType2* pIndexToToken;
+
+ if( bWK3 )
+ { // for > WK3
+ pIndexToType = IndexToTypeWK123;
+ pIndexToToken = IndexToTokenWK123;
+ }
+ else if( bWK123 )
+ {
+ pIndexToType = IndexToTypeWK123;
+ pIndexToToken = IndexToTokenWK123;
+ }
+ else
+ {
+ pIndexToType = IndexToType;
+ pIndexToToken = IndexToToken;
+
+ rR.SetTabRel( sal_True );
+ rR.nTab = aEingPos.Tab();
+ rR.nRelTab = 0;
+ rR.SetFlag3D( false );
+ }
+
+ aCRD.Ref2 = rR;
+
+ nBytesLeft = rRest;
+
+ while( eType ) // != FT_Return (==0)
+ {
+ Read( nOc );
+
+ if( nBytesLeft < 0 )
+ {
+ rpErg = aPool[ aStack.Get() ];
+ return ConvErrCount;
+ }
+
+ eType = ( pIndexToType )( nOc );
+ eOc = ( pIndexToToken)( nOc );
+ if( eOc == ocNoName )
+ pExtName = GetAddInName( nOc );
+
+ switch( eType )
+ {
+ case FT_Return:
+ if( bWK3 || bWK123 )
+ nBytesLeft = 0; // wird ab WK3 nicht benutzt
+
+ rRest = nBytesLeft;
+ break;
+ case FT_NotImpl:
+ case FT_FuncFix0: DoFunc( eOc, 0, pExtName ); break;
+ case FT_FuncFix1: DoFunc( eOc, 1, pExtName ); break;
+ case FT_FuncFix2: DoFunc( eOc, 2, pExtName ); break;
+ case FT_FuncFix3: DoFunc( eOc, 3, pExtName ); break;
+ case FT_FuncFix4: DoFunc( eOc, 4, pExtName ); break;
+ case FT_FuncVar:
+ Read( nAnz );
+ DoFunc( eOc, nAnz, pExtName );
+ break;
+ case FT_Neg:
+ aPool << ocOpen << ocNegSub << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case FT_Op:
+ aStack >> nMerk0;
+ aPool << aStack << eOc << nMerk0;
+ aPool >> aStack;
+ break;
+ case FT_ConstFloat:
+ {
+ double fDouble;
+ Read( fDouble );
+ aStack << aPool.Store( fDouble );
+ }
+ break;
+ case FT_Variable:
+ {
+ sal_uInt16 nCol, nRow;
+ Read( nCol );
+ Read( nRow );
+
+ LotusRelToScRel( nCol, nRow, rR );
+
+ if( bWK3 )
+ nNewId = aPool.Store( rR );
+ else
+ {
+ nId = rRangeList.GetIndex( rR.nCol, rR.nRow );
+
+ if( nId == ID_FAIL )
+ // kein Range dazu
+ nNewId = aPool.Store( rR );
+ else
+ nNewId = aPool.Store( ( sal_uInt16 ) nId );
+ }
+
+ aStack << nNewId;
+ }
+ break;
+ case FT_Range:
+ {
+ sal_uInt16 nColS, nRowS, nColE, nRowE;
+ Read( nColS );
+ Read( nRowS );
+ Read( nColE );
+ Read( nRowE );
+
+ LotusRelToScRel( nColS, nRowS, rR );
+ LotusRelToScRel( nColE, nRowE, aCRD.Ref2 );
+
+ if( bWK3 )
+ nNewId = aPool.Store( aCRD );
+ else
+ {
+ nId = rRangeList.GetIndex(
+ rR.nCol, rR.nRow, aCRD.Ref2.nCol, aCRD.Ref2.nRow );
+
+ if( nId == ID_FAIL )
+ // kein Range dazu
+ nNewId = aPool.Store( aCRD );
+ else
+ nNewId = aPool.Store( ( sal_uInt16 ) nId );
+ }
+
+ aStack << nNewId;
+ }
+ break;
+ case FT_Braces:
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case FT_ConstInt:
+ {
+ sal_Int16 nVal;
+ Read( nVal );
+ aStack << aPool.Store( ( double ) nVal );
+ }
+ break;
+ case FT_ConstString:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+
+ aStack << aPool.Store( aTmp );
+ }
+ break;
+ case FT_NOP:
+ break;
+ // ------------------------------------------ fuer > WK3 -
+ case FT_Cref:
+ Read( nRelBits );
+ ReadSRD( rR, nRelBits );
+ aStack << aPool.Store( rR );
+ break;
+ case FT_Rref:
+ Read( nRelBits );
+ ReadCRD( aCRD, nRelBits );
+ aStack << aPool.Store( aCRD );
+ break;
+ case FT_Nrref:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+ if( rRangeNameBufferWK3.FindRel( aTmp, nRngIndex ) )
+ aStack << aPool.Store( nRngIndex );
+ else
+ {
+ String aText( RTL_CONSTASCII_USTRINGPARAM( "NRREF " ) );
+ aText += aTmp;
+ aStack << aPool.Store( aText );
+ }
+ }
+ break;
+ case FT_Absnref:
+ {
+ String aTmp( ScfTools::ReadCString( aIn, nBytesLeft, eSrcChar ) );
+ if( rRangeNameBufferWK3.FindAbs( aTmp, nRngIndex ) )
+ aStack << aPool.Store( nRngIndex );
+ else
+ {
+ String aText( RTL_CONSTASCII_USTRINGPARAM( "ABSNREF " ) );
+ aText += aTmp;
+ aStack << aPool.Store( aText );
+ }
+ }
+ break;
+ case FT_Erref:
+ Ignore( 4 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Ecref:
+ Ignore( 5 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Econstant:
+ Ignore( 10 );
+ aPool << ocBad;
+ aPool >> aStack;
+ break;
+ case FT_Splfunc:
+ {
+ Read( nAnz );
+ Read( nStrLen );
+
+ if( nStrLen )
+ {
+// String t( ReadString( aIn, nStrLen, eSrcChar ) );
+ sal_Char* p = new sal_Char[ nStrLen + 1 ];
+ aIn.Read( p, nStrLen );
+ p[ nStrLen ] = 0x00;
+
+ DoFunc( ocNoName, nAnz, p );
+
+ delete[] p;
+ }
+ else
+ DoFunc( ocNoName, nAnz, NULL );
+ }
+ break;
+ case FT_Const10Float:
+ if ( bWK123 )
+ {
+ double fValue;
+ Read( fValue );
+ aStack << aPool.Store( fValue );
+ }
+ else aStack << aPool.Store( ScfTools::ReadLongDouble( aIn ) );
+ break;
+ case FT_Snum:
+ if ( bWK123 )
+ {
+ sal_uInt32 nValue;
+
+ Read( nValue );
+ double fValue = Snum32ToDouble( nValue );
+ aStack << aPool.Store( fValue );
+ }
+ else
+ {
+ sal_Int16 nVal;
+ Read( nVal );
+ aStack << aPool.Store( SnumToDouble( nVal ) );
+ }
+ break;
+ default:
+ OSL_FAIL( "*LotusToSc::Convert(): unbekannter enum!" );
+ }
+ }
+
+ rpErg = aPool[ aStack.Get() ];
+
+ DBG_ASSERT( nBytesLeft >= 0, "*LotusToSc::Convert(): zuviel verarbeitet!");
+ DBG_ASSERT( nBytesLeft <= 0, "*LotusToSc::Convert(): wat is mit'm Rest?" );
+
+ if( rRest )
+ aIn.SeekRel( nBytesLeft ); // eventuellen Rest/Ueberlauf korrigieren
+
+ rRest = 0;
+
+ return ConvOK;
+}
+
+
+FUNC_TYPE LotusToSc::IndexToType( sal_uInt8 nIndex )
+{
+ static const FUNC_TYPE pType[ 256 ] =
+ { // Code Bezeichnung
+ FT_ConstFloat, // 0 8-Byte-IEEE-Float
+ FT_Variable, // 1 Variable
+ FT_Range, // 2 Bereich
+ FT_Return, // 3 return
+ FT_Braces, // 4 Klammer
+ FT_ConstInt, // 5 2-Byte-Integer
+ FT_ConstString, // 6 ASCII-String
+ FT_NOP, // 7 NOP
+ FT_Neg, // 8 Negation
+ FT_Op, // 9 Addition
+ FT_Op, // 10 Subtraktion
+ FT_Op, // 11 Multiplikation
+ FT_Op, // 12 Division
+ FT_Op, // 13 Potenzierung
+ FT_Op, // 14 Gleichheit
+ FT_Op, // 15 Ungleich
+ FT_Op, // 16 Kleiner-gleich
+ FT_Op, // 17 Groesser-gleich
+ FT_Op, // 18 Kleiner
+ FT_Op, // 19 Groesser
+ FT_Op, // 20 And (logisch)
+ FT_Op, // 21 Or (logisch)
+ FT_FuncFix1, // 22 Not (logisch)
+ FT_NOP, // 23 unaeres Plus
+ FT_NotImpl, // 24
+ FT_NotImpl, // 25
+ FT_NotImpl, // 26
+ FT_NotImpl, // 27
+ FT_NotImpl, // 28
+ FT_NotImpl, // 29
+ FT_NotImpl, // 30
+ FT_FuncFix0, // 31 Not applicable
+ FT_FuncFix0, // 32 Error
+ FT_FuncFix1, // 33 Betrag ABS()
+ FT_FuncFix1, // 34 Ganzzahl INT()
+ FT_FuncFix1, // 35 Quadratwurzel
+ FT_FuncFix1, // 36 Zehnerlogarithmus
+ FT_FuncFix1, // 37 Natuerlicher Logarithmus
+ FT_FuncFix0, // 38 PI
+ FT_FuncFix1, // 39 Sinus
+ FT_FuncFix1, // 40 Cosinus
+ FT_FuncFix1, // 41 Tangens
+ FT_FuncFix2, // 42 Arcus-Tangens 2 (4.Quadrant) <----- richtig? -
+ FT_FuncFix1, // 43 Arcus-Tangens (2.Quadrant)
+ FT_FuncFix1, // 44 Arcus-Sinus
+ FT_FuncFix1, // 45 Arcus-Cosinus
+ FT_FuncFix1, // 46 Exponentialfunktion
+ FT_FuncFix2, // 47 Modulo
+ FT_FuncVar, // 48 Auswahl
+ FT_FuncFix1, // 49 Is not applicable?
+ FT_FuncFix1, // 50 Is Error?
+ FT_FuncFix0, // 51 FALSE
+ FT_FuncFix0, // 52 TRUE
+ FT_FuncFix0, // 53 Zufallszahl
+ FT_FuncFix3, // 54 Datum
+ FT_FuncFix0, // 55 Heute
+ FT_FuncFix3, // 56 Payment
+ FT_FuncFix3, // 57 Present Value
+ FT_FuncFix3, // 58 Future Value
+ FT_FuncFix3, // 59 If ... then ... else ...
+ FT_FuncFix1, // 60 Tag des Monats
+ FT_FuncFix1, // 61 Monat
+ FT_FuncFix1, // 62 Jahr
+ FT_FuncFix2, // 63 Runden
+ FT_FuncFix3, // 64 Zeit
+ FT_FuncFix1, // 65 Stunde
+ FT_FuncFix1, // 66 Minute
+ FT_FuncFix1, // 67 Sekunde
+ FT_FuncFix1, // 68 Ist Zahl?
+ FT_FuncFix1, // 69 Ist Text?
+ FT_FuncFix1, // 70 Len()
+ FT_FuncFix1, // 71 Val()
+ FT_FuncFix2, // 72 String()
+ FT_FuncFix3, // 73 Mid()
+ FT_FuncFix1, // 74 Char()
+ FT_FuncFix1, // 75 Ascii()
+ FT_FuncFix3, // 76 Find()
+ FT_FuncFix1, // 77 Datevalue
+ FT_FuncFix1, // 78 Timevalue
+ FT_FuncFix1, // 79 Cellpointer
+ FT_FuncVar, // 80 Sum()
+ FT_FuncVar, // 81 Avg()
+ FT_FuncVar, // 82 Cnt()
+ FT_FuncVar, // 83 Min()
+ FT_FuncVar, // 84 Max()
+ FT_FuncFix3, // 85 Vlookup()
+ FT_FuncFix2, // 86 Npv()
+ FT_FuncVar, // 87 Var()
+ FT_FuncVar, // 88 Std()
+ FT_FuncFix2, // 89 Irr()
+ FT_FuncFix3, // 90 Hlookup()
+ FT_FuncFix3, // 91 ?
+ FT_FuncFix3, // 92 ?
+ FT_FuncFix3, // 93 ?
+ FT_FuncFix3, // 94 ?
+ FT_FuncFix3, // 95 ?
+ FT_FuncFix3, // 96 ?
+ FT_FuncFix3, // 97 ?
+ FT_FuncFix3, // 98 Index() <- richtig? -
+ FT_FuncFix1, // 99 Cols()
+ FT_FuncFix1, // 100 Rows()
+ FT_FuncFix2, // 101 Repeat()
+ FT_FuncFix1, // 102 Upper()
+ FT_FuncFix1, // 103 Lower()
+ FT_FuncFix2, // 104 Left()
+ FT_FuncFix2, // 105 Right()
+ FT_FuncFix4, // 106 Replace()
+ FT_FuncFix1, // 107 Proper()
+ FT_FuncFix2, // 108 Cell()
+ FT_FuncFix1, // 109 Trim()
+ FT_FuncFix1, // 110 Clean()
+ FT_FuncFix1, // 111 F()
+ FT_FuncFix1, // 112 Wert() (oder W()?)
+ FT_FuncFix2, // 113 Exact()
+ FT_NotImpl, // 114 Call()
+ FT_FuncFix1, // 115 @@()
+ FT_FuncFix3, // 116 Rate()
+ FT_FuncFix1, // 117 Term()
+ FT_FuncFix1, // 118 Cterm()
+ FT_FuncFix3, // 119 Sln()
+ FT_FuncFix4, // 120 Syd(), Soy()
+ FT_FuncFix4, // 121 Ddb()
+ FT_NotImpl, // 122
+ FT_NotImpl, // 123
+ FT_NotImpl, // 124
+ FT_NotImpl, // 125
+ FT_NotImpl, // 126
+ FT_NotImpl, // 127
+ FT_NotImpl, // 128
+ FT_NotImpl, // 129
+ FT_NotImpl, // 130
+ FT_NotImpl, // 131
+ FT_NotImpl, // 132
+ FT_NotImpl, // 133
+ FT_NotImpl, // 134
+ FT_NotImpl, // 135
+ FT_NotImpl, // 136
+ FT_NotImpl, // 137
+ FT_NotImpl, // 138
+ FT_NotImpl, // 139
+ FT_NotImpl, // 140
+ FT_NotImpl, // 141
+ FT_NotImpl, // 142
+ FT_NotImpl, // 143
+ FT_NotImpl, // 144
+ FT_NotImpl, // 145
+ FT_NotImpl, // 146
+ FT_NotImpl, // 147
+ FT_NotImpl, // 148
+ FT_NotImpl, // 149
+ FT_NotImpl, // 150
+ FT_NotImpl, // 151
+ FT_NotImpl, // 152
+ FT_NotImpl, // 153
+ FT_NotImpl, // 154
+ FT_NotImpl, // 155
+ FT_FuncVar, // 156 ?
+ FT_NotImpl, // 157
+ FT_NotImpl, // 158
+ FT_NotImpl, // 159
+ FT_NotImpl, // 160
+ FT_NotImpl, // 161
+ FT_NotImpl, // 162
+ FT_NotImpl, // 163
+ FT_NotImpl, // 164
+ FT_NotImpl, // 165
+ FT_NotImpl, // 166
+ FT_NotImpl, // 167
+ FT_NotImpl, // 168
+ FT_NotImpl, // 169
+ FT_NotImpl, // 170
+ FT_NotImpl, // 171
+ FT_NotImpl, // 172
+ FT_NotImpl, // 173
+ FT_NotImpl, // 174
+ FT_NotImpl, // 175
+ FT_NotImpl, // 176
+ FT_NotImpl, // 177
+ FT_NotImpl, // 178
+ FT_NotImpl, // 179
+ FT_NotImpl, // 180
+ FT_NotImpl, // 181
+ FT_NotImpl, // 182
+ FT_NotImpl, // 183
+ FT_NotImpl, // 184
+ FT_NotImpl, // 185
+ FT_NotImpl, // 186
+ FT_NotImpl, // 187
+ FT_NotImpl, // 188
+ FT_NotImpl, // 189
+ FT_NotImpl, // 190
+ FT_NotImpl, // 191
+ FT_NotImpl, // 192
+ FT_NotImpl, // 193
+ FT_NotImpl, // 194
+ FT_NotImpl, // 195
+ FT_NotImpl, // 196
+ FT_NotImpl, // 197
+ FT_NotImpl, // 198
+ FT_NotImpl, // 199
+ FT_NotImpl, // 200
+ FT_NotImpl, // 201
+ FT_NotImpl, // 202
+ FT_NotImpl, // 203
+ FT_NotImpl, // 204
+ FT_NotImpl, // 205
+ FT_FuncVar, // 206 ?
+ FT_NotImpl, // 207
+ FT_NotImpl, // 208
+ FT_NotImpl, // 209
+ FT_NotImpl, // 210
+ FT_NotImpl, // 211
+ FT_NotImpl, // 212
+ FT_NotImpl, // 213
+ FT_NotImpl, // 214
+ FT_NotImpl, // 215
+ FT_NotImpl, // 216
+ FT_NotImpl, // 217
+ FT_NotImpl, // 218
+ FT_NotImpl, // 219
+ FT_NotImpl, // 220
+ FT_NotImpl, // 221
+ FT_NotImpl, // 222
+ FT_NotImpl, // 223
+ FT_NotImpl, // 224
+ FT_NotImpl, // 225
+ FT_NotImpl, // 226
+ FT_NotImpl, // 227
+ FT_NotImpl, // 228
+ FT_NotImpl, // 229
+ FT_NotImpl, // 230
+ FT_NotImpl, // 231
+ FT_NotImpl, // 232
+ FT_NotImpl, // 233
+ FT_NotImpl, // 234
+ FT_NotImpl, // 235
+ FT_NotImpl, // 236
+ FT_NotImpl, // 237
+ FT_NotImpl, // 238
+ FT_NotImpl, // 239
+ FT_NotImpl, // 240
+ FT_NotImpl, // 241
+ FT_NotImpl, // 242
+ FT_NotImpl, // 243
+ FT_NotImpl, // 244
+ FT_NotImpl, // 245
+ FT_NotImpl, // 246
+ FT_NotImpl, // 247
+ FT_NotImpl, // 248
+ FT_NotImpl, // 249
+ FT_NotImpl, // 250
+ FT_NotImpl, // 251
+ FT_NotImpl, // 252
+ FT_NotImpl, // 253
+ FT_NotImpl, // 254
+ FT_FuncVar, // 255 ?
+ };
+ return pType[ nIndex ];
+}
+
+
+DefTokenId LotusToSc::IndexToToken( sal_uInt8 nIndex )
+{
+ static const DefTokenId pToken[ 256 ] =
+ { // Code Bezeichnung
+ ocPush, // 0 8-Byte-IEEE-Float
+ ocPush, // 1 Variable
+ ocPush, // 2 Bereich
+ ocPush, // 3 return
+ ocPush, // 4 Klammer
+ ocPush, // 5 2-Byte-Integer
+ ocPush, // 6 ASCII-String
+ ocPush, // 7 NOP
+ ocNegSub, // 8 Negation
+ ocAdd, // 9 Addition
+ ocSub, // 10 Subtraktion
+ ocMul, // 11 Multiplikation
+ ocDiv, // 12 Division
+ ocPow, // 13 Potenzierung
+ ocEqual, // 14 Gleichheit
+ ocNotEqual, // 15 Ungleich
+ ocLessEqual, // 16 Kleiner-gleich
+ ocGreaterEqual, // 17 Groesser-gleich
+ ocLess, // 18 Kleiner
+ ocGreater, // 19 Groesser
+ ocAnd, // 20 And (logisch)
+ ocOr, // 21 Or (logisch)
+ ocNot, // 22 Not (logisch)
+ ocPush, // 23 unaeres Plus
+ ocNoName, // 24
+ ocNoName, // 25
+ ocNoName, // 26
+ ocNoName, // 27
+ ocNoName, // 28
+ ocNoName, // 29
+ ocNoName, // 30
+ ocNotAvail, // 31 Not available
+ ocNoName, // 32 Error
+ ocAbs, // 33 Betrag ABS()
+ ocInt, // 34 Ganzzahl INT()
+ ocSqrt, // 35 Quadratwurzel
+ ocLog10, // 36 Zehnerlogarithmus
+ ocLn, // 37 Natuerlicher Logarithmus
+ ocPi, // 38 PI
+ ocSin, // 39 Sinus
+ ocCos, // 40 Cosinus
+ ocTan, // 41 Tangens
+ ocArcTan2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ ocArcTan, // 43 Arcus-Tangens (2.Quadrant)
+ ocArcSin, // 44 Arcus-Sinus
+ ocArcCos, // 45 Arcus-Cosinus
+ ocExp, // 46 Exponentialfunktion
+ ocMod, // 47 Modulo
+ ocChose, // 48 Auswahl
+ ocIsNA, // 49 Is not available?
+ ocIsError, // 50 Is Error?
+ ocFalse, // 51 FALSE
+ ocTrue, // 52 TRUE
+ ocRandom, // 53 Zufallszahl
+ ocGetDate, // 54 Datum
+ ocGetActDate, // 55 Heute
+ ocRMZ, // 56 Payment
+ ocBW, // 57 Present Value
+ ocZW, // 58 Future Value
+ ocIf, // 59 If ... then ... else ...
+ ocGetDay, // 60 Tag des Monats
+ ocGetMonth, // 61 Monat
+ ocGetYear, // 62 Jahr
+ ocRound, // 63 Runden
+ ocGetTime, // 64 Zeit
+ ocGetHour, // 65 Stunde
+ ocGetMin, // 66 Minute
+ ocGetSec, // 67 Sekunde
+ ocIsValue, // 68 Ist Zahl?
+ ocIsString, // 69 Ist Text?
+ ocLen, // 70 Len()
+ ocValue, // 71 Val()
+ ocFixed, // 72 String() ocFixed ersatzweise + Spezialfall
+ ocMid, // 73 Mid()
+ ocChar, // 74 Char()
+ ocCode, // 75 Ascii()
+ ocFind, // 76 Find()
+ ocGetDateValue, // 77 Datevalue
+ ocGetTimeValue, // 78 Timevalue
+ ocNoName, // 79 Cellpointer
+ ocSum, // 80 Sum()
+ ocAverage, // 81 Avg()
+ ocCount, // 82 Cnt()
+ ocMin, // 83 Min()
+ ocMax, // 84 Max()
+ ocVLookup, // 85 Vlookup()
+ ocNPV, // 86 Npv()
+ ocVar, // 87 Var()
+ ocNormDist, // 88 Std()
+ ocIRR, // 89 Irr()
+ ocHLookup, // 90 Hlookup()
+ ocDBSum, // 91 XlfDsum
+ ocDBAverage, // 92 XlfDaverage
+ ocDBCount, // 93 XlfDcount
+ ocDBMin, // 94 XlfDmin
+ ocDBMax, // 95 XlfDmax
+ ocDBVar, // 96 XlfDvar
+ ocDBStdDev, // 97 XlfDstdev
+ ocIndex, // 98 Index()
+ ocColumns, // 99 Cols()
+ ocRows, // 100 Rows()
+ ocRept, // 101 Repeat()
+ ocUpper, // 102 Upper()
+ ocLower, // 103 Lower()
+ ocLeft, // 104 Left()
+ ocRight, // 105 Right()
+ ocReplace, // 106 Replace()
+ ocPropper, // 107 Proper()
+ ocNoName, // 108 Cell()
+ ocTrim, // 109 Trim()
+ ocClean, // 110 Clean()
+ ocFalse, // 111 F()
+ ocTrue, // 112 W()
+ ocExact, // 113 Exact()
+ ocNoName, // 114 Call()
+ ocIndirect, // 115 @@()
+ ocZins, // 116 Rate()
+ ocNoName, // 117 Term()
+ ocNoName, // 118 Cterm()
+ ocLIA, // 119 Sln()
+ ocDIA, // 120 Syd(), Soy()
+ ocGDA, // 121 Ddb()
+ ocNoName, // 122
+ ocNoName, // 123
+ ocNoName, // 124
+ ocNoName, // 125
+ ocNoName, // 126
+ ocNoName, // 127
+ ocNoName, // 128
+ ocNoName, // 129
+ ocNoName, // 130
+ ocNoName, // 131
+ ocNoName, // 132
+ ocNoName, // 133
+ ocNoName, // 134
+ ocNoName, // 135
+ ocNoName, // 136
+ ocNoName, // 137
+ ocNoName, // 138
+ ocNoName, // 139
+ ocNoName, // 140
+ ocNoName, // 141
+ ocNoName, // 142
+ ocNoName, // 143
+ ocNoName, // 144
+ ocNoName, // 145
+ ocNoName, // 146
+ ocNoName, // 147
+ ocNoName, // 148
+ ocNoName, // 149
+ ocNoName, // 150
+ ocNoName, // 151
+ ocNoName, // 152
+ ocNoName, // 153
+ ocNoName, // 154
+ ocNoName, // 155
+ ocNoName, // 156 ?
+ ocNoName, // 157
+ ocNoName, // 158
+ ocNoName, // 159
+ ocNoName, // 160
+ ocNoName, // 161
+ ocNoName, // 162
+ ocNoName, // 163
+ ocNoName, // 164
+ ocNoName, // 165
+ ocNoName, // 166
+ ocNoName, // 167
+ ocNoName, // 168
+ ocNoName, // 169
+ ocNoName, // 170
+ ocNoName, // 171
+ ocNoName, // 172
+ ocNoName, // 173
+ ocNoName, // 174
+ ocNoName, // 175
+ ocNoName, // 176
+ ocNoName, // 177
+ ocNoName, // 178
+ ocNoName, // 179
+ ocNoName, // 180
+ ocNoName, // 181
+ ocNoName, // 182
+ ocNoName, // 183
+ ocNoName, // 184
+ ocNoName, // 185
+ ocNoName, // 186
+ ocNoName, // 187
+ ocNoName, // 188
+ ocNoName, // 189
+ ocNoName, // 190
+ ocNoName, // 191
+ ocNoName, // 192
+ ocNoName, // 193
+ ocNoName, // 194
+ ocNoName, // 195
+ ocNoName, // 196
+ ocNoName, // 197
+ ocNoName, // 198
+ ocNoName, // 199
+ ocNoName, // 200
+ ocNoName, // 201
+ ocNoName, // 202
+ ocNoName, // 203
+ ocNoName, // 204
+ ocNoName, // 205
+ ocNoName, // 206 ?
+ ocNoName, // 207
+ ocNoName, // 208
+ ocNoName, // 209
+ ocNoName, // 210
+ ocNoName, // 211
+ ocNoName, // 212
+ ocNoName, // 213
+ ocNoName, // 214
+ ocNoName, // 215
+ ocNoName, // 216
+ ocNoName, // 217
+ ocNoName, // 218
+ ocNoName, // 219
+ ocNoName, // 220
+ ocNoName, // 221
+ ocNoName, // 222
+ ocNoName, // 223
+ ocNoName, // 224
+ ocNoName, // 225
+ ocNoName, // 226
+ ocNoName, // 227
+ ocNoName, // 228
+ ocNoName, // 229
+ ocNoName, // 230
+ ocNoName, // 231
+ ocNoName, // 232
+ ocNoName, // 233
+ ocNoName, // 234
+ ocNoName, // 235
+ ocNoName, // 236
+ ocNoName, // 237
+ ocNoName, // 238
+ ocNoName, // 239
+ ocNoName, // 240
+ ocNoName, // 241
+ ocNoName, // 242
+ ocNoName, // 243
+ ocNoName, // 244
+ ocNoName, // 245
+ ocNoName, // 246
+ ocNoName, // 247
+ ocNoName, // 248
+ ocNoName, // 249
+ ocNoName, // 250
+ ocNoName, // 251
+ ocNoName, // 252
+ ocNoName, // 253
+ ocNoName, // 254
+ ocNoName // 255 ?
+ };
+
+ return pToken[ nIndex ];
+}
+
+
+FUNC_TYPE LotusToSc::IndexToTypeWK123( sal_uInt8 nIndex )
+{
+ static const FUNC_TYPE pType[ 256 ] =
+ { // Code Bezeichnung
+ FT_Const10Float, // 0 8-Byte-IEEE-Long-Number
+ FT_Cref, // 1 Cell Reference
+ FT_Rref, // 2 Area Reference
+ FT_Return, // 3 return
+ FT_Braces, // 4 Klammer
+ FT_Snum, // 5 Short-Number
+ FT_ConstString, // 6 ASCII-String
+ FT_Nrref, // 7 Named range reference
+ FT_Absnref, // 8 Absolut named range
+ FT_Erref, // 9 Err range reference
+ FT_Ecref, // 10 Err cell reference
+ FT_Econstant, // 11 Err constant
+ FT_NotImpl, // 12
+ FT_NotImpl, // 13
+ FT_Neg, // 14 Negation
+ FT_Op, // 15 Addition
+ FT_Op, // 16 Subtraktion
+ FT_Op, // 17 Multiplikation
+ FT_Op, // 18 Division
+ FT_Op, // 19 Potenzierung
+ FT_Op, // 20 Gleichheit
+ FT_Op, // 21 Ungleich
+ FT_Op, // 22 Kleiner-gleich
+ FT_Op, // 23 Groesser-gleich
+ FT_Op, // 24 Kleiner
+ FT_Op, // 25 Groesser
+ FT_Op, // 26 And (logisch)
+ FT_Op, // 27 Or (logisch)
+ FT_FuncFix1, // 28 Not (logisch)
+ FT_NOP, // 29 unaeres Plus
+ FT_Op, // 30 Concatenation
+ FT_FuncFix0, // 31 Not applicable
+ FT_FuncFix0, // 32 Error
+ FT_FuncFix1, // 33 Betrag ABS()
+ FT_FuncFix1, // 34 Ganzzahl INT()
+ FT_FuncFix1, // 35 Quadratwurzel
+ FT_FuncFix1, // 36 Zehnerlogarithmus
+ FT_FuncFix1, // 37 Natuerlicher Logarithmus
+ FT_FuncFix0, // 38 PI
+ FT_FuncFix1, // 39 Sinus
+ FT_FuncFix1, // 40 Cosinus
+ FT_FuncFix1, // 41 Tangens
+ FT_FuncFix2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ FT_FuncFix1, // 43 Arcus-Tangens (2.Quadrant)
+ FT_FuncFix1, // 44 Arcus-Sinus
+ FT_FuncFix1, // 45 Arcus-Cosinus
+ FT_FuncFix1, // 46 Exponentialfunktion
+ FT_FuncFix2, // 47 Modulo
+ FT_FuncVar, // 48 Auswahl
+ FT_FuncFix1, // 49 Is not applicable?
+ FT_FuncFix1, // 50 Is Error?
+ FT_FuncFix0, // 51 FALSE
+ FT_FuncFix0, // 52 TRUE
+ FT_FuncFix0, // 53 Zufallszahl
+ FT_FuncFix3, // 54 Datum
+ FT_FuncFix0, // 55 Heute
+ FT_FuncFix3, // 56 Payment
+ FT_FuncFix3, // 57 Present Value
+ FT_FuncFix3, // 58 Future Value
+ FT_FuncFix3, // 59 If ... then ... else ...
+ FT_FuncFix1, // 60 Tag des Monats
+ FT_FuncFix1, // 61 Monat
+ FT_FuncFix1, // 62 Jahr
+ FT_FuncFix2, // 63 Runden
+ FT_FuncFix3, // 64 Zeit
+ FT_FuncFix1, // 65 Stunde
+ FT_FuncFix1, // 66 Minute
+ FT_FuncFix1, // 67 Sekunde
+ FT_FuncFix1, // 68 Ist Zahl?
+ FT_FuncFix1, // 69 Ist Text?
+ FT_FuncFix1, // 70 Len()
+ FT_FuncFix1, // 71 Val()
+ FT_FuncFix2, // 72 String()
+ FT_FuncFix3, // 73 Mid()
+ FT_FuncFix1, // 74 Char()
+ FT_FuncFix1, // 75 Ascii()
+ FT_FuncFix3, // 76 Find()
+ FT_FuncFix1, // 77 Datevalue
+ FT_FuncFix1, // 78 Timevalue
+ FT_FuncFix1, // 79 Cellpointer
+ FT_FuncVar, // 80 Sum()
+ FT_FuncVar, // 81 Avg()
+ FT_FuncVar, // 82 Cnt()
+ FT_FuncVar, // 83 Min()
+ FT_FuncVar, // 84 Max()
+ FT_FuncFix3, // 85 Vlookup()
+ FT_FuncFix2, // 86 Npv()
+ FT_FuncVar, // 87 Var()
+ FT_FuncVar, // 88 Std()
+ FT_FuncFix2, // 89 Irr()
+ FT_FuncFix3, // 90 Hlookup()
+ FT_FuncVar, // 91 Dsum <-------- neu! -
+ FT_FuncVar, // 92 Davg <-------- neu! -
+ FT_FuncVar, // 93 Dcnt <-------- neu! -
+ FT_FuncVar, // 94 Dmin <-------- neu! -
+ FT_FuncVar, // 95 Dmax <-------- neu! -
+ FT_FuncVar, // 96 Dvar <-------- neu! -
+ FT_FuncVar, // 97 Dstd <-------- neu! -
+ FT_FuncVar, // 98 Index() <-------- change! -
+ FT_FuncFix1, // 99 Cols() <-------- neu! -
+ FT_FuncFix1, // 100 Rows() <-------- neu! -
+ FT_FuncFix2, // 101 Repeat() <-------- neu! -
+ FT_FuncFix1, // 102 Upper() <-------- neu! -
+ FT_FuncFix1, // 103 Lower() <-------- neu! -
+ FT_FuncFix2, // 104 Left() <-------- neu! -
+ FT_FuncFix2, // 105 Right() <-------- neu! -
+ FT_FuncFix4, // 106 Replace() <-------- neu! -
+ FT_FuncFix1, // 107 Proper() <-------- neu! -
+ FT_FuncFix2, // 108 Cell() <-------- neu! -
+ FT_FuncFix1, // 109 Trim() <-------- neu! -
+ FT_FuncFix1, // 110 Clean() <-------- neu! -
+ FT_FuncFix1, // 111 S() <--------- change in Bez. -
+ FT_FuncFix1, // 112 N() <--------- change in Bez. -
+ FT_FuncFix2, // 113 Exact() <-------- neu! -
+ FT_NotImpl, // 114 App <--------- change in Bez. -
+ FT_FuncFix1, // 115 @@() <-------- neu! -
+ FT_FuncFix3, // 116 Rate() <-------- neu! -
+ FT_FuncFix3, // 117 Term() <--------- change in Anz.
+ FT_FuncFix3, // 118 Cterm() <--------- change in Anz.
+ FT_FuncFix3, // 119 Sln() <-------- neu! -
+ FT_FuncFix4, // 120 Syd() <-------- neu! -
+ FT_FuncFix4, // 121 Ddb() <-------- neu! -
+ FT_Splfunc, // 122 Splfunc <-------- neu! -
+ FT_FuncFix1, // 123 Sheets <-------- neu! -
+ FT_FuncFix1, // 124 Info <-------- neu! -
+ FT_FuncVar, // 125 Sumproduct <-------- neu! -
+ FT_FuncFix1, // 126 Isrange <-------- neu! -
+ FT_FuncVar, // 127 Dget <-------- neu! -
+ FT_FuncVar, // 128 Dquery <-------- neu! -
+ FT_FuncFix4, // 129 Coord <-------- neu! -
+ FT_NOP, // 130 Reserved (internal) <-------- neu! -
+ FT_FuncFix0, // 131 Today <-------- neu! -
+ FT_FuncVar, // 132 Vdb <-------- neu! -
+ FT_FuncVar, // 133 Dvars <-------- neu! -
+ FT_FuncVar, // 134 Dstds <-------- neu! -
+ FT_FuncVar, // 135 Vars <-------- neu! -
+ FT_FuncVar, // 136 Stds <-------- neu! -
+ FT_FuncFix2, // 137 D360 <-------- neu! -
+ FT_NOP, // 138 Reserved (internal) <-------- neu! -
+ FT_FuncFix0, // 139 Isapp <-------- neu! - Anzahl ? -
+ FT_FuncVar, // 140 Isaaf <-------- neu! - Anzahl ? -
+ FT_FuncFix1, // 141 Weekday <-------- neu! -
+ FT_FuncFix3, // 142 Datedif <-------- neu! -
+ FT_FuncVar, // 143 Rank <-------- neu! -
+ FT_FuncFix2, // 144 Numberstring <-------- neu! -
+ FT_FuncFix1, // 145 Datestring <-------- neu! -
+ FT_FuncFix1, // 146 Decimal <-------- neu! -
+ FT_FuncFix1, // 147 Hex <-------- neu! -
+ FT_FuncFix4, // 148 Db <-------- neu! -
+ FT_FuncFix4, // 149 Pmti <-------- neu! -
+ FT_FuncFix4, // 150 Spi <-------- neu! -
+ FT_FuncFix1, // 151 Fullp <-------- neu! -
+ FT_FuncFix1, // 152 Halfp <-------- neu! -
+ FT_FuncVar, // 153 Pureavg <-------- neu! -
+ FT_FuncVar, // 154 Purecount <-------- neu! -
+ FT_FuncVar, // 155 Puremax <-------- neu! -
+ FT_FuncVar, // 156 Puremin <-------- neu! -
+ FT_FuncVar, // 157 Purestd <-------- neu! -
+ FT_FuncVar, // 158 Purevar <-------- neu! -
+ FT_FuncVar, // 159 Purestds <-------- neu! -
+ FT_FuncVar, // 160 Purevars <-------- neu! -
+ FT_FuncFix3, // 161 Pmt2 <-------- neu! -
+ FT_FuncFix3, // 162 Pv2 <-------- neu! -
+ FT_FuncFix3, // 163 Fv2 <-------- neu! -
+ FT_FuncFix3, // 164 Term2 <-------- neu! -
+ FT_NotImpl, // 165 --- <-------- neu! - Anzahl ? -
+ FT_FuncFix2, // 166 D360 (US-Version)
+ FT_NotImpl, // 167
+ FT_NotImpl, // 168
+ FT_NotImpl, // 169
+ FT_NotImpl, // 170
+ FT_NotImpl, // 171
+ FT_NotImpl, // 172
+ FT_NotImpl, // 173
+ FT_NotImpl, // 174
+ FT_NotImpl, // 175
+ FT_NotImpl, // 176
+ FT_NotImpl, // 177
+ FT_NotImpl, // 178
+ FT_NotImpl, // 179
+ FT_NotImpl, // 180
+ FT_NotImpl, // 181
+ FT_NotImpl, // 182
+ FT_NotImpl, // 183
+ FT_NotImpl, // 184
+ FT_NotImpl, // 185
+ FT_FuncVar, // 186 Solver <-------- neu! -
+ FT_NotImpl, // 187
+ FT_NotImpl, // 188
+ FT_NotImpl, // 189
+ FT_NotImpl, // 190
+ FT_NotImpl, // 191
+ FT_NotImpl, // 192
+ FT_NotImpl, // 193
+ FT_NotImpl, // 194
+ FT_NotImpl, // 195
+ FT_NotImpl, // 196
+ FT_NotImpl, // 197
+ FT_NotImpl, // 198
+ FT_NotImpl, // 199
+ FT_NotImpl, // 200
+ FT_NotImpl, // 201
+ FT_NotImpl, // 202
+ FT_NotImpl, // 203
+ FT_NotImpl, // 204
+ FT_NotImpl, // 205
+ FT_NotImpl, // 206
+ FT_NotImpl, // 207
+ FT_NotImpl, // 208
+ FT_NotImpl, // 209
+ FT_NotImpl, // 210
+ FT_NotImpl, // 211
+ FT_NotImpl, // 212
+ FT_NotImpl, // 213
+ FT_NotImpl, // 214
+ FT_NotImpl, // 215
+ FT_NotImpl, // 216
+ FT_NotImpl, // 217
+ FT_NotImpl, // 218
+ FT_NotImpl, // 219
+ FT_NotImpl, // 220
+ FT_NotImpl, // 221
+ FT_NotImpl, // 222
+ FT_NotImpl, // 223
+ FT_NotImpl, // 224
+ FT_NotImpl, // 225
+ FT_NotImpl, // 226
+ FT_NotImpl, // 227
+ FT_NotImpl, // 228
+ FT_NotImpl, // 229
+ FT_NotImpl, // 230
+ FT_NotImpl, // 231
+ FT_NotImpl, // 232
+ FT_NotImpl, // 233
+ FT_NotImpl, // 234
+ FT_NotImpl, // 235
+ FT_NotImpl, // 236
+ FT_NotImpl, // 237
+ FT_NotImpl, // 238
+ FT_NotImpl, // 239
+ FT_NotImpl, // 240
+ FT_NotImpl, // 241
+ FT_NotImpl, // 242
+ FT_NotImpl, // 243
+ FT_NotImpl, // 244
+ FT_NotImpl, // 245
+ FT_NotImpl, // 246
+ FT_NotImpl, // 247
+ FT_NotImpl, // 248
+ FT_NotImpl, // 249
+ FT_NotImpl, // 250
+ FT_NotImpl, // 251
+ FT_NotImpl, // 252
+ FT_NotImpl, // 253
+ FT_NotImpl, // 254
+ FT_NotImpl, // 255
+ };
+ return pType[ nIndex ];
+}
+
+
+DefTokenId LotusToSc::IndexToTokenWK123( sal_uInt8 nIndex )
+{
+ static const DefTokenId pToken[ 256 ] =
+ { // Code Bezeichnung
+ ocPush, // 0 8-Byte-IEEE-Long-Numbers
+ ocPush, // 1 Variable
+ ocPush, // 2 Bereich
+ ocPush, // 3 return
+ ocPush, // 4 Klammer
+ ocPush, // 5 Numbers
+ ocPush, // 6 ASCII-String
+ ocPush, // 7 Named range reference
+ ocPush, // 8 Absolut named range
+ ocPush, // 9 Err range reference
+ ocPush, // 10 Err cell reference
+ ocPush, // 11 Err constant
+ ocPush, // 12
+ ocPush, // 13
+ ocNegSub, // 14 Negation
+ ocAdd, // 15 Addition
+ ocSub, // 16 Subtraktion
+ ocMul, // 17 Multiplikation
+ ocDiv, // 18 Division
+ ocPow, // 19 Potenzierung
+ ocEqual, // 20 Gleichheit
+ ocNotEqual, // 21 Ungleich
+ ocLessEqual, // 22 Kleiner-gleich
+ ocGreaterEqual, // 23 Groesser-gleich
+ ocLess, // 24 Kleiner
+ ocGreater, // 25 Groesser
+ ocAnd, // 26 And (logisch)
+ ocOr, // 27 Or (logisch)
+ ocNot, // 28 Not (logisch)
+ ocPush, // 29 unaeres Plus
+ ocAmpersand, // 30 Concatenation
+ ocNotAvail, // 31 Not available
+ ocNoName, // 32 Error
+ ocAbs, // 33 Betrag ABS()
+ ocInt, // 34 Ganzzahl INT()
+ ocSqrt, // 35 Quadratwurzel
+ ocLog10, // 36 Zehnerlogarithmus
+ ocLn, // 37 Natuerlicher Logarithmus
+ ocPi, // 38 PI
+ ocSin, // 39 Sinus
+ ocCos, // 40 Cosinus
+ ocTan, // 41 Tangens
+ ocArcTan2, // 42 Arcus-Tangens 2 (4.Quadrant)
+ ocArcTan, // 43 Arcus-Tangens (2.Quadrant)
+ ocArcSin, // 44 Arcus-Sinus
+ ocArcCos, // 45 Arcus-Cosinus
+ ocExp, // 46 Exponentialfunktion
+ ocMod, // 47 Modulo
+ ocChose, // 48 Auswahl
+ ocIsNA, // 49 Is not available?
+ ocIsError, // 50 Is Error?
+ ocFalse, // 51 FALSE
+ ocTrue, // 52 TRUE
+ ocRandom, // 53 Zufallszahl
+ ocGetDate, // 54 Datum
+ ocGetActDate, // 55 Heute
+ ocRMZ, // 56 Payment
+ ocBW, // 57 Present Value
+ ocZW, // 58 Future Value
+ ocIf, // 59 If ... then ... else ...
+ ocGetDay, // 60 Tag des Monats
+ ocGetMonth, // 61 Monat
+ ocGetYear, // 62 Jahr
+ ocRound, // 63 Runden
+ ocGetTime, // 64 Zeit
+ ocGetHour, // 65 Stunde
+ ocGetMin, // 66 Minute
+ ocGetSec, // 67 Sekunde
+ ocIsValue, // 68 Ist Zahl?
+ ocIsString, // 69 Ist Text?
+ ocLen, // 70 Len()
+ ocValue, // 71 Val()
+ ocFixed, // 72 String() ocFixed ersatzweise + Spezialfall
+ ocMid, // 73 Mid()
+ ocChar, // 74 Char()
+ ocCode, // 75 Ascii()
+ ocFind, // 76 Find()
+ ocGetDateValue, // 77 Datevalue
+ ocGetTimeValue, // 78 Timevalue
+ ocNoName, // 79 Cellpointer
+ ocSum, // 80 Sum()
+ ocAverage, // 81 Avg()
+ ocCount, // 82 Cnt()
+ ocMin, // 83 Min()
+ ocMax, // 84 Max()
+ ocVLookup, // 85 Vlookup()
+ ocNPV, // 86 Npv()
+ ocVar, // 87 Var()
+ ocStDev, // 88 Std()
+ ocIRR, // 89 Irr()
+ ocHLookup, // 90 Hlookup()
+ ocDBSum, // 91 XlfDsum
+ ocDBAverage, // 92 XlfDaverage
+ ocDBCount, // 93 XlfDcount
+ ocDBMin, // 94 XlfDmin
+ ocDBMax, // 95 XlfDmax
+ ocDBVar, // 96 XlfDvar
+ ocDBStdDev, // 97 XlfDstdev
+ ocIndex, // 98 Index()
+ ocColumns, // 99 Cols()
+ ocRows, // 100 Rows()
+ ocRept, // 101 Repeat()
+ ocUpper, // 102 Upper()
+ ocLower, // 103 Lower()
+ ocLeft, // 104 Left()
+ ocRight, // 105 Right()
+ ocReplace, // 106 Replace()
+ ocPropper, // 107 Proper()
+ ocNoName, // 108 Cell()
+ ocTrim, // 109 Trim()
+ ocClean, // 110 Clean()
+ ocNoName, // 111 F() (Excel: T()?)
+ ocNoName, // 112 W()
+ ocExact, // 113 Exact()
+ ocNoName, // 114 Call()
+ ocIndirect, // 115 @@()
+ ocZins, // 116 Rate()
+ ocNoName, // 117 Term()
+ ocNoName, // 118 Cterm()
+ ocLIA, // 119 Sln()
+ ocDIA, // 120 Syd(), Soy()
+ ocGDA, // 121 Ddb()
+ ocNoName, // 122 Splfunc
+ ocNoName, // 123 Sheets
+ ocNoName, // 124 Info
+ ocSumProduct, // 125 Sumproduct
+ ocNoName, // 126 Isrange
+ ocDBGet, // 127 Dget
+ ocNoName, // 128 Dquery
+ ocNoName, // 129 Coord
+ ocNoName, // 130 Reserved (internal)
+ ocGetActDate, // 131 Today
+ ocNoName, // 132 Vdb
+ ocDBVarP, // 133 Dvars
+ ocDBStdDevP, // 134 Dstds
+ ocVarP, // 135 Vars
+ ocStDevP, // 136 Stds
+ ocGetDiffDate360, // 137 D360
+ ocNoName, // 138 Reserved (internal)
+ ocNoName, // 139 Isapp
+ ocNoName, // 140 Isaaf
+ ocGetDayOfWeek, // 141 Weekday
+ ocGetDiffDate, // 142 Datedif
+ ocRank, // 143 Rank
+ ocNoName, // 144 Numberstring
+ ocNoName, // 145 Datestring
+ ocNoName, // 146 Decimal
+ ocNoName, // 147 Hex
+ ocNoName, // 148 Db
+ ocNoName, // 149 Pmti
+ ocNoName, // 150 Spi
+ ocNoName, // 151 Fullp
+ ocNoName, // 152 Halfp
+ ocNoName, // 153 Pureavg
+ ocCount2, // 154 Purecount
+ ocNoName, // 155 Puremax
+ ocNoName, // 156 Puremin
+ ocNoName, // 157 Purestd
+ ocNoName, // 158 Purevar
+ ocNoName, // 159 Purestds
+ ocNoName, // 160 Purevars
+ ocNoName, // 161 Pmt2
+ ocNoName, // 162 Pv2
+ ocNoName, // 163 Fv2
+ ocNoName, // 164 Term2
+ ocNoName, // 165 --- <-------- neu! - Anzahl ? -
+ ocGetDiffDate360, // 166 D360 (US-Version, ersatzweise wie ander D360-Funktion)
+ ocNoName, // 167
+ ocNoName, // 168
+ ocNoName, // 169
+ ocNoName, // 170
+ ocNoName, // 171
+ ocNoName, // 172
+ ocNoName, // 173
+ ocNoName, // 174
+ ocNoName, // 175
+ ocNoName, // 176
+ ocNoName, // 177
+ ocNoName, // 178
+ ocNoName, // 179
+ ocNoName, // 180
+ ocNoName, // 181
+ ocNoName, // 182
+ ocNoName, // 183
+ ocNoName, // 184
+ ocNoName, // 185
+ ocNoName, // 186
+ ocNoName, // 187
+ ocNoName, // 188
+ ocNoName, // 189
+ ocNoName, // 190
+ ocNoName, // 191
+ ocNoName, // 192
+ ocNoName, // 193
+ ocNoName, // 194
+ ocNoName, // 195
+ ocNoName, // 196
+ ocNoName, // 197
+ ocNoName, // 198
+ ocNoName, // 199
+ ocNoName, // 200
+ ocNoName, // 201
+ ocNoName, // 202
+ ocNoName, // 203
+ ocNoName, // 204
+ ocNoName, // 205
+ ocNoName, // 206 ?
+ ocNoName, // 207
+ ocNoName, // 208
+ ocNoName, // 209
+ ocNoName, // 210
+ ocNoName, // 211
+ ocNoName, // 212
+ ocNoName, // 213
+ ocNoName, // 214
+ ocNoName, // 215
+ ocNoName, // 216
+ ocNoName, // 217
+ ocNoName, // 218
+ ocNoName, // 219
+ ocNoName, // 220
+ ocNoName, // 221
+ ocNoName, // 222
+ ocNoName, // 223
+ ocNoName, // 224
+ ocNoName, // 225
+ ocNoName, // 226
+ ocNoName, // 227
+ ocNoName, // 228
+ ocNoName, // 229
+ ocNoName, // 230
+ ocNoName, // 231
+ ocNoName, // 232
+ ocNoName, // 233
+ ocNoName, // 234
+ ocNoName, // 235
+ ocNoName, // 236
+ ocNoName, // 237
+ ocNoName, // 238
+ ocNoName, // 239
+ ocNoName, // 240
+ ocNoName, // 241
+ ocNoName, // 242
+ ocNoName, // 243
+ ocNoName, // 244
+ ocNoName, // 245
+ ocNoName, // 246
+ ocNoName, // 247
+ ocNoName, // 248
+ ocNoName, // 249
+ ocNoName, // 250
+ ocNoName, // 251
+ ocNoName, // 252
+ ocNoName, // 253
+ ocNoName, // 254
+ ocNoName // 255 ?
+ };
+
+ return pToken[ nIndex ];
+}
+
+
+
+
+const sal_Char* GetAddInName( const sal_uInt8 n )
+{
+ static const sal_Char* pNames[ 256 ] =
+ {
+ NULL, // 0 8-Byte-IEEE-Float
+ NULL, // 1 Variable
+ NULL, // 2 Bereich
+ NULL, // 3 return
+ NULL, // 4 Klammer
+ NULL, // 5 2-Byte-Integer
+ NULL, // 6 ASCII-String
+ NULL, // 7 Named range reference
+ NULL, // 8 Absolut named range
+ NULL, // 9 Err range reference
+ NULL, // 10 Err cell reference
+ NULL, // 11 Err constant
+ NULL, // 12
+ NULL, // 13
+ NULL, // 14 Negation
+ NULL, // 15 Addition
+ NULL, // 16 Subtraktion
+ NULL, // 17 Multiplikation
+ NULL, // 18 Division
+ NULL, // 19 Potenzierung
+ NULL, // 20 Gleichheit
+ NULL, // 21 Ungleich
+ NULL, // 22 Kleiner-gleich
+ NULL, // 23 Groesser-gleich
+ NULL, // 24 Kleiner
+ NULL, // 25 Groesser
+ NULL, // 26 And (logisch)
+ NULL, // 27 Or (logisch)
+ NULL, // 28 Not (logisch)
+ NULL, // 29 unaeres Plus
+ NULL, // 30 Concatenation
+ NULL, // 31 Not applicable
+ NULL, // 32 Error
+ NULL, // 33 Betrag ABS()
+ NULL, // 34 Ganzzahl INT()
+ NULL, // 35 Quadratwurzel
+ NULL, // 36 Zehnerlogarithmus
+ NULL, // 37 Natuerlicher Logarithmus
+ NULL, // 38 PI
+ NULL, // 39 Sinus
+ NULL, // 40 Cosinus
+ NULL, // 41 Tangens
+ NULL, // 42 Arcus-Tangens 2 (4.Quadrant)
+ NULL, // 43 Arcus-Tangens (2.Quadrant)
+ NULL, // 44 Arcus-Sinus
+ NULL, // 45 Arcus-Cosinus
+ NULL, // 46 Exponentialfunktion
+ NULL, // 47 Modulo
+ NULL, // 48 Auswahl
+ NULL, // 49 Is not applicable?
+ NULL, // 50 Is Error?
+ NULL, // 51 FALSE
+ NULL, // 52 TRUE
+ NULL, // 53 Zufallszahl
+ NULL, // 54 Datum
+ NULL, // 55 Heute
+ NULL, // 56 Payment
+ NULL, // 57 Present Value
+ NULL, // 58 Future Value
+ NULL, // 59 If ... then ... else ...
+ NULL, // 60 Tag des Monats
+ NULL, // 61 Monat
+ NULL, // 62 Jahr
+ NULL, // 63 Runden
+ NULL, // 64 Zeit
+ NULL, // 65 Stunde
+ NULL, // 66 Minute
+ NULL, // 67 Sekunde
+ NULL, // 68 Ist Zahl?
+ NULL, // 69 Ist Text?
+ NULL, // 70 Len()
+ NULL, // 71 Val()
+ NULL, // 72 String() ocFixed ersatzweise + Spezialfall
+ NULL, // 73 Mid()
+ NULL, // 74 Char()
+ NULL, // 75 Ascii()
+ NULL, // 76 Find()
+ NULL, // 77 Datevalue
+ NULL, // 78 Timevalue
+ "ZELLZEIGER", // 79 Cellpointer
+ NULL, // 80 Sum()
+ NULL, // 81 Avg()
+ NULL, // 82 Cnt()
+ NULL, // 83 Min()
+ NULL, // 84 Max()
+ NULL, // 85 Vlookup()
+ NULL, // 86 Npv()
+ NULL, // 87 Var()
+ NULL, // 88 Std()
+ NULL, // 89 Irr()
+ NULL, // 90 Hlookup()
+ NULL, // 91 XlfDsum
+ NULL, // 92 XlfDaverage
+ NULL, // 93 XlfDcount
+ NULL, // 94 XlfDmin
+ NULL, // 95 XlfDmax
+ NULL, // 96 XlfDvar
+ NULL, // 97 XlfDstdev
+ NULL, // 98 Index()
+ NULL, // 99 Cols()
+ NULL, // 100 Rows()
+ NULL, // 101 Repeat()
+ NULL, // 102 Upper()
+ NULL, // 103 Lower()
+ NULL, // 104 Left()
+ NULL, // 105 Right()
+ NULL, // 106 Replace()
+ NULL, // 107 Proper()
+ "ZELLE", // 108 Cell()
+ NULL, // 109 Trim()
+ NULL, // 110 Clean()
+ "F", // 111 F() (Excel: T()?)
+ "W", // 112 W()
+ NULL, // 113 Exact()
+ NULL, // 114 Call()
+ NULL, // 115 @@()
+ NULL, // 116 Rate()
+ "ANN", // 117 Term()
+ NULL, // 118 Cterm()
+ NULL, // 119 Sln()
+ NULL, // 120 Syd(), Soy()
+ NULL, // 121 Ddb()
+ "SplFunc", // 122 Splfunc
+ "BLAETTER", // 123 Sheets
+ "INFO", // 124 Info
+ NULL, // 125 Sumproduct
+ "ISTBEREICH", // 126 Isrange
+ NULL, // 127 Dget
+ "DABFRAGE", // 128 Dquery
+ "KOORD", // 129 Coord
+ NULL, // 130 Reserved (internal)
+ NULL, // 131 Today
+ NULL, // 132 Vdb
+ NULL, // 133 Dvars
+ NULL, // 134 Dstds
+ NULL, // 135 Vars
+ NULL, // 136 Stds
+ NULL, // 137 D360
+ NULL, // 138 Reserved (internal)
+ NULL, // 139 Isapp
+ "ISTDEFZUS", // 140 Isaaf
+ NULL, // 141 Weekday
+ NULL, // 142 Datedif
+ NULL, // 143 Rank
+ NULL, // 144 Numberstring
+ "DATUMFOLGE", // 145 Datestring
+ "DEZIMAL", // 146 Decimal
+ "HEX", // 147 Hex
+ NULL, // 148 Db
+ NULL, // 149 Pmti
+ NULL, // 150 Spi
+ NULL, // 151 Fullp
+ NULL, // 152 Halfp
+ "PURMITTELWERT", // 153 Pureavg
+ "PURANZAHL", // 154 Purecount
+ "PURMAX", // 155 Puremax
+ "PURMIN", // 156 Puremin
+ "PURSTDABW", // 157 Purestd
+ "PURVAR", // 158 Purevar
+ "PURSTDABWP", // 159 Purestds
+ "PURVARP", // 160 Purevars
+ NULL, // 161 Pmt2
+ NULL, // 162 Pv2
+ NULL, // 163 Fv2
+ NULL, // 164 Term2
+ NULL, // 165 --- <-------- neu! - Anzahl ? -
+ NULL, // 166 D360 (US-Version, ersatzweise wie ander D360-Funktion)
+ NULL, // 167
+ NULL, // 168
+ NULL, // 169
+ NULL, // 170
+ NULL, // 171
+ NULL, // 172
+ NULL, // 173
+ NULL, // 174
+ NULL, // 175
+ NULL, // 176
+ NULL, // 177
+ NULL, // 178
+ NULL, // 179
+ NULL, // 180
+ NULL, // 181
+ NULL, // 182
+ NULL, // 183
+ NULL, // 184
+ NULL, // 185
+ NULL, // 186
+ NULL, // 187
+ NULL, // 188
+ NULL, // 189
+ NULL, // 190
+ NULL, // 191
+ NULL, // 192
+ NULL, // 193
+ NULL, // 194
+ NULL, // 195
+ NULL, // 196
+ NULL, // 197
+ NULL, // 198
+ NULL, // 199
+ NULL, // 200
+ NULL, // 201
+ NULL, // 202
+ NULL, // 203
+ NULL, // 204
+ NULL, // 205
+ NULL, // 206 ?
+ NULL, // 207
+ NULL, // 208
+ NULL, // 209
+ NULL, // 210
+ NULL, // 211
+ NULL, // 212
+ NULL, // 213
+ NULL, // 214
+ NULL, // 215
+ NULL, // 216
+ NULL, // 217
+ NULL, // 218
+ NULL, // 219
+ NULL, // 220
+ NULL, // 221
+ NULL, // 222
+ NULL, // 223
+ NULL, // 224
+ NULL, // 225
+ NULL, // 226
+ NULL, // 227
+ NULL, // 228
+ NULL, // 229
+ NULL, // 230
+ NULL, // 231
+ NULL, // 232
+ NULL, // 233
+ NULL, // 234
+ NULL, // 235
+ NULL, // 236
+ NULL, // 237
+ NULL, // 238
+ NULL, // 239
+ NULL, // 240
+ NULL, // 241
+ NULL, // 242
+ NULL, // 243
+ NULL, // 244
+ NULL, // 245
+ NULL, // 246
+ NULL, // 247
+ NULL, // 248
+ NULL, // 249
+ NULL, // 250
+ NULL, // 251
+ NULL, // 252
+ NULL, // 253
+ NULL, // 254
+ NULL // 255 ?
+ };
+
+ return pNames[ n ];
+}
+
+
+DefTokenId lcl_KnownAddIn( const ByteString& sTest )
+{
+ DefTokenId eId = ocNoName;
+
+ if( sTest == "FACT" )
+ eId = ocFact;
+ else if(sTest== "ISEMPTY")
+ eId=ocIsEmpty;
+ else if(sTest== "DEGTORAD")
+ eId=ocRad;
+ else if(sTest== "RADTODEG")
+ eId=ocDeg;
+ else if(sTest== "SIGN")
+ eId=ocPlusMinus;
+ else if(sTest== "ACOSH")
+ eId=ocArcCosHyp;
+ else if(sTest== "ACOTH")
+ eId=ocArcCotHyp;
+ else if(sTest== "ASINH")
+ eId=ocArcSinHyp;
+ else if(sTest== "ATANH")
+ eId=ocArcTanHyp;
+ else if(sTest== "COSH")
+ eId=ocCosHyp;
+ else if(sTest== "COTH")
+ eId=ocCotHyp;
+ else if(sTest== "SINH")
+ eId=ocSinHyp;
+ else if(sTest== "TANH")
+ eId=ocTanHyp;
+ else if(sTest== "EVEN")
+ eId=ocIsEven;
+ else if(sTest== "ODD")
+ eId=ocIsOdd;
+ else if(sTest== "ACOT")
+ eId=ocArcCot;
+ else if(sTest== "COT")
+ eId=ocCot;
+ else if(sTest== "ACOT")
+ eId=ocArcCot;
+ else if(sTest== "TRUNC")
+ eId=ocTrunc;
+ else if(sTest== "GEOMEAN")
+ eId=ocGeoMean;
+ else if(sTest== "HARMEAN")
+ eId=ocHarMean;
+ else if(sTest== "CORREL")
+ eId=ocCorrel;
+ else if(sTest== "MEDIAN")
+ eId=ocMedian;
+ else if(sTest== "COV")
+ eId=ocCovar;
+ else if(sTest== "SKEWNESS")
+ eId=ocSchiefe;
+ else if(sTest== "CHITEST")
+ eId=ocChiTest;
+ else if(sTest== "FTEST")
+ eId=ocFTest;
+ else if(sTest== "AVEDEV")
+ eId=ocAveDev;
+ else if(sTest== "PRODUCT")
+ eId=ocProduct;
+ else if(sTest== "PERMUT")
+ eId=ocVariationen;
+ else if(sTest== "GAMMALN")
+ eId=ocGammaLn;
+ else if(sTest== "POISSON")
+ eId=ocPoissonDist;
+ else if(sTest== "NORMAL")
+ eId=ocNormDist;
+ else if(sTest== "CRITBINOMIAL")
+ eId=ocKritBinom;
+ return eId;
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/lotimpop.cxx b/sc/source/filter/lotus/lotimpop.cxx
new file mode 100644
index 000000000000..150fee171646
--- /dev/null
+++ b/sc/source/filter/lotus/lotimpop.cxx
@@ -0,0 +1,475 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "lotimpop.hxx"
+#include <osl/mutex.hxx>
+
+#include "attrib.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "compiler.hxx"
+#include "global.hxx"
+
+#include "root.hxx"
+#include "lotfntbf.hxx"
+#include "lotform.hxx"
+#include "tool.h"
+#include "namebuff.hxx"
+#include "lotrange.hxx"
+#include "lotattr.hxx"
+
+
+static osl::Mutex aLotImpSemaphore;
+
+
+ImportLotus::ImportLotus( SvStream& aStream, ScDocument* pDoc, CharSet eQ ) :
+ ImportTyp( pDoc, eQ ),
+ pIn( &aStream ),
+ aConv( *pIn, eQ, false )
+{
+ // good point to start locking of import lotus
+ aLotImpSemaphore.acquire();
+
+ pLotusRoot = new LOTUS_ROOT;
+ pLotusRoot->pDoc = pDoc;
+ pLotusRoot->pRangeNames = new LotusRangeList;
+ pLotusRoot->pScRangeName = pDoc->GetRangeName();
+ pLotusRoot->eCharsetQ = eQ;
+ pLotusRoot->eFirstType = Lotus_X;
+ pLotusRoot->eActType = Lotus_X;
+ pLotusRoot->pRngNmBffWK3 = new RangeNameBufferWK3;
+ pFontBuff = pLotusRoot->pFontBuff = new LotusFontBuffer;
+ pLotusRoot->pAttrTable = new LotAttrTable;
+}
+
+
+ImportLotus::~ImportLotus()
+{
+ delete pLotusRoot->pRangeNames;
+ delete pLotusRoot->pRngNmBffWK3;
+ delete pFontBuff;
+ delete pLotusRoot->pAttrTable;
+ delete pLotusRoot;
+
+#ifdef DBG_UTIL
+ pLotusRoot = NULL;
+#endif
+
+ // no need 4 pLotusRoot anymore
+ aLotImpSemaphore.release();
+}
+
+
+void ImportLotus::Bof( void )
+{
+ sal_uInt16 nFileCode, nFileSub, nSaveCnt;
+ sal_uInt8 nMajorId, nMinorId, nFlags;
+
+ Read( nFileCode );
+ Read( nFileSub );
+ Read( pLotusRoot->aActRange );
+ Read( nSaveCnt );
+ Read( nMajorId );
+ Read( nMinorId );
+ Skip( 1 );
+ Read( nFlags );
+
+ if( nFileSub == 0x0004 )
+ {
+ if( nFileCode == 0x1000 )
+ {// <= WK3
+ pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK3;
+ }
+ else if( nFileCode == 0x1002 )
+ {// WK4
+ pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK4;
+ }
+ }
+}
+
+
+sal_Bool ImportLotus::BofFm3( void )
+{
+ sal_uInt16 nFileCode, nFileSub;
+
+ Read( nFileCode );
+ Read( nFileSub );
+
+ return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
+}
+
+
+void ImportLotus::Columnwidth( sal_uInt16 nRecLen )
+{
+ DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Columnwidth(): Record zu kurz!" );
+
+ sal_uInt8 nLTab, nWindow2;
+ sal_uInt16 nCnt = ( nRecLen - 4 ) / 2;
+
+ Read( nLTab );
+ Read( nWindow2 );
+
+ if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
+ pD->MakeTable( static_cast<SCTAB> (nLTab) );
+
+ if( !nWindow2 )
+ {
+ Skip( 2 );
+
+ sal_uInt8 nCol, nSpaces;
+
+ while( nCnt )
+ {
+ Read( nCol );
+ Read( nSpaces );
+ // ACHTUNG: Korrekturfaktor nach 'Augenmass' ermittelt!
+ pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), ( sal_uInt16 ) ( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
+
+ nCnt--;
+ }
+ }
+}
+
+
+void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen )
+{
+ DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Hiddencolumn(): Record zu kurz!" );
+
+ sal_uInt8 nLTab, nWindow2;
+ sal_uInt16 nCnt = ( nRecLen - 4 ) / 2;
+
+ Read( nLTab );
+ Read( nWindow2 );
+
+ if( !nWindow2 )
+ {
+ Skip( 2 );
+
+ sal_uInt8 nCol;
+
+ while( nCnt )
+ {
+ Read( nCol );
+
+ pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
+ nCnt--;
+ }
+ }
+}
+
+
+void ImportLotus::Userrange( void )
+{
+ sal_uInt16 nRangeType;
+ ScRange aScRange;
+ sal_Char* pBuffer = new sal_Char[ 32 ];
+
+ Read( nRangeType );
+
+ pIn->Read( pBuffer, 16 );
+ pBuffer[ 16 ] = ( sal_Char ) 0x00; // zur Sicherheit...
+ String aName( pBuffer, eQuellChar );
+
+ Read( aScRange );
+
+ pLotusRoot->pRngNmBffWK3->Add( aName, aScRange );
+ delete[] pBuffer;
+}
+
+
+void ImportLotus::Errcell( void )
+{
+ ScAddress aA;
+
+ Read( aA );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#ERR!" ) ), (sal_Bool)sal_True );
+}
+
+
+void ImportLotus::Nacell( void )
+{
+ ScAddress aA;
+
+ Read( aA );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#NA!" ) ), (sal_Bool)sal_True );
+}
+
+
+void ImportLotus::Labelcell( void )
+{
+ ScAddress aA;
+ String aLabel;
+ sal_Char cAlign;
+
+ Read( aA );
+ Read( cAlign );
+ Read( aLabel );
+
+// aLabel.Convert( pLotusRoot->eCharsetQ );
+
+ pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( aLabel ), (sal_Bool)sal_True );
+}
+
+
+void ImportLotus::Numbercell( void )
+ {
+ ScAddress aAddr;
+ double fVal;
+
+ Read( aAddr );
+ Read( fVal );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
+ new ScValueCell( fVal ), (sal_Bool)sal_True );
+ }
+
+
+void ImportLotus::Smallnumcell( void )
+ {
+ ScAddress aAddr;
+ sal_Int16 nVal;
+
+ Read( aAddr );
+ Read( nVal );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
+ new ScValueCell( SnumToDouble( nVal ) ), ( sal_Bool ) sal_True );
+ }
+
+
+ScFormulaCell *ImportLotus::Formulacell( sal_uInt16 n )
+ {
+ DBG_ASSERT( pIn, "-ImportLotus::Formulacell(): Null-Stream -> Rums!" );
+
+ ScAddress aAddr;
+
+ Read( aAddr );
+ Skip( 10 );
+
+ n -= 14;
+
+ const ScTokenArray* pErg;
+ sal_Int32 nRest = n;
+
+ aConv.Reset( aAddr );
+ aConv.SetWK3();
+ aConv.Convert( pErg, nRest );
+
+ ScFormulaCell* pZelle = new ScFormulaCell( pD, aAddr, pErg );
+
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), pZelle, (sal_Bool)sal_True );
+
+ return NULL;
+ }
+
+
+void ImportLotus::Read( String &r )
+{
+ ScfTools::AppendCString( *pIn, r, eQuellChar );
+}
+
+
+void ImportLotus::RowPresentation( sal_uInt16 nRecLen )
+{
+ DBG_ASSERT( nRecLen > 4, "*ImportLotus::RowPresentation(): Record zu kurz!" );
+
+ sal_uInt8 nLTab, nFlags;
+ sal_uInt16 nRow, nHeight;
+ sal_uInt16 nCnt = ( nRecLen - 4 ) / 8;
+
+ Read( nLTab );
+ Skip( 1 );
+
+ while( nCnt )
+ {
+ Read( nRow );
+ Read( nHeight );
+ Skip( 2 );
+ Read( nFlags );
+ Skip( 1 );
+
+ if( nFlags & 0x02 ) // Fixed / Strech to fit fonts
+ { // fixed
+ // Height in Lotus in 1/32 Points
+ nHeight *= 20; // -> 32 * TWIPS
+ nHeight /= 32; // -> TWIPS
+
+ pD->SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CR_MANUALSIZE );
+
+ pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
+ }
+
+ nCnt--;
+ }
+}
+
+
+void ImportLotus::NamedSheet( void )
+{
+ sal_uInt16 nLTab;
+ String aName;
+
+ Read( nLTab );
+ Read( aName );
+
+ if( pD->HasTable( static_cast<SCTAB> (nLTab) ) )
+ pD->RenameTab( static_cast<SCTAB> (nLTab), aName );
+ else
+ pD->InsertTab( static_cast<SCTAB> (nLTab), aName );
+}
+
+
+void ImportLotus::Font_Face( void )
+{
+ sal_uInt8 nNum;
+ String aName;
+
+ Read( nNum );
+
+ // ACHTUNG: QUICK-HACK gegen unerklaerliche Loops
+ if( nNum > 7 )
+ return;
+ // ACHTUNG
+
+ Read( aName );
+
+ pFontBuff->SetName( nNum, aName );
+}
+
+
+void ImportLotus::Font_Type( void )
+{
+ static const sal_uInt16 nAnz = 8;
+ sal_uInt16 nCnt;
+ sal_uInt16 nType;
+
+ for( nCnt = 0 ; nCnt < nAnz ; nCnt++ )
+ {
+ Read( nType );
+ pFontBuff->SetType( nCnt, nType );
+ }
+}
+
+
+void ImportLotus::Font_Ysize( void )
+{
+ static const sal_uInt16 nAnz = 8;
+ sal_uInt16 nCnt;
+ sal_uInt16 nSize;
+
+ for( nCnt = 0 ; nCnt < nAnz ; nCnt++ )
+ {
+ Read( nSize );
+ pFontBuff->SetHeight( nCnt, nSize );
+ }
+}
+
+
+void ImportLotus::_Row( const sal_uInt16 nRecLen )
+ {
+ DBG_ASSERT( nExtTab >= 0, "*ImportLotus::_Row(): Kann hier nicht sein!" );
+
+ sal_uInt16 nRow;
+ sal_uInt16 nHeight;
+ sal_uInt16 nCntDwn = ( nRecLen - 4 ) / 5;
+ SCCOL nColCnt = 0;
+ sal_uInt8 nRepeats;
+ LotAttrWK3 aAttr;
+
+ sal_Bool bCenter = false;
+ SCCOL nCenterStart = 0, nCenterEnd = 0;
+
+ Read( nRow );
+ Read( nHeight );
+
+ nHeight &= 0x0FFF;
+ nHeight *= 22;
+
+ if( nHeight )
+ pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab), nHeight );
+
+ while( nCntDwn )
+ {
+ Read( aAttr );
+ Read( nRepeats );
+
+ if( aAttr.HasStyles() )
+ pLotusRoot->pAttrTable->SetAttr(
+ nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), static_cast<SCROW> (nRow), aAttr );
+
+ // hier und NICHT in class LotAttrTable, weil nur Attributiert wird,
+ // wenn die anderen Attribute gesetzt sind
+ // -> bei Center-Attribute wird generell zentriert gesetzt
+ if( aAttr.IsCentered() )
+ {
+ if( bCenter )
+ {
+ if( pD->HasData( nColCnt, static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab) ) )
+ {// neue Center nach vorheriger Center
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ nCenterStart = nColCnt;
+ }
+ }
+ else
+ {// ganz neue Center
+ bCenter = sal_True;
+ nCenterStart = nColCnt;
+ }
+ nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
+ }
+ else
+ {
+ if( bCenter )
+ {// evtl. alte Center bemachen
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ bCenter = false;
+ }
+ }
+
+ nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
+ nColCnt++;
+
+ nCntDwn--;
+ }
+
+ if( bCenter )
+ // evtl. alte Center bemachen
+ pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
+ }
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/lotread.cxx b/sc/source/filter/lotus/lotread.cxx
new file mode 100644
index 000000000000..84cb8df148ba
--- /dev/null
+++ b/sc/source/filter/lotus/lotread.cxx
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "document.hxx"
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "lotimpop.hxx"
+#include "lotattr.hxx"
+#include "fprogressbar.hxx"
+
+
+class ScFormulaCell;
+
+
+FltError ImportLotus::Read()
+{
+ enum STATE
+ {
+ S_START, // analyse first BOF
+ S_WK1, // in WK1-Stream
+ S_WK3, // in WK3-Section
+ S_WK4, // ...
+ S_FM3, // ...
+ S_END // Import finished
+ };
+
+ sal_uInt16 nOp;
+ sal_uInt16 nSubType;
+ sal_uInt16 nRecLen;
+ sal_uInt32 nNextRec = 0UL;
+ FltError eRet = eERR_OK;
+// ScFormulaCell *pLastFormCell;
+
+ STATE eAkt = S_START;
+
+ nTab = 0;
+ nExtTab = -2;
+
+ pIn->Seek( nNextRec );
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( *pIn, pD->GetDocumentShell() );
+
+ while( eAkt != S_END )
+ {
+ *pIn >> nOp >> nRecLen;
+
+ if( pIn->IsEof() )
+ eAkt = S_END;
+
+ nNextRec += nRecLen + 4;
+
+ switch( eAkt )
+ {
+ // -----------------------------------------------------------
+ case S_START: // S_START
+ if( nOp )
+ {
+ eRet = SCERR_IMPORT_UNKNOWN_WK;
+ eAkt = S_END;
+ }
+ else
+ {
+ if( nRecLen > 2 )
+ {
+ Bof();
+ switch( pLotusRoot->eFirstType )
+ {
+ case Lotus_WK1: eAkt = S_WK1; break;
+ case Lotus_WK3: eAkt = S_WK3; break;
+ case Lotus_WK4: eAkt = S_WK4; break;
+ case Lotus_FM3: eAkt = S_FM3; break;
+ default:
+ eRet = SCERR_IMPORT_UNKNOWN_WK;
+ eAkt = S_END;
+ }
+ }
+ else
+ {
+ eAkt = S_END; // hier kommt wat fuer <= WK1 hinne!
+ eRet = 0xFFFFFFFF;
+ }
+ }
+ break;
+ // -----------------------------------------------------------
+ case S_WK1: // S_WK1
+ break;
+ // -----------------------------------------------------------
+ case S_WK3: // S_WK3
+ case S_WK4: // S_WK4
+ switch( nOp )
+ {
+ case 0x0001: // EOF
+ eAkt = S_FM3;
+ nTab++;
+ break;
+
+ case 0x0002: // PASSWORD
+ eRet = eERR_FILEPASSWD;
+ eAkt = S_END;
+ break;
+
+ case 0x0007: // COLUMNWIDTH
+ Columnwidth( nRecLen );
+ break;
+
+ case 0x0008: // HIDDENCOLUMN
+ Hiddencolumn( nRecLen );
+ break;
+
+ case 0x0009: // USERRANGE
+ Userrange();
+ break;
+
+ case 0x0013: // FORMAT
+
+ break;
+ case 0x0014: // ERRCELL
+ Errcell();
+ break;
+
+ case 0x0015: // NACELL
+ Nacell();
+ break;
+
+ case 0x0016: // LABELCELL
+ Labelcell();
+ break;
+
+ case 0x0017: // NUMBERCELL
+ Numbercell();
+ break;
+
+ case 0x0018: // SMALLNUMCELL
+ Smallnumcell();
+ break;
+
+ case 0x0019: // FORMULACELL
+ Formulacell( nRecLen );
+ break;
+
+ case 0x001b: // extended attributes
+ Read( nSubType );
+ nRecLen -= 2;
+ switch( nSubType )
+ {
+ case 2007: // ROW PRESENTATION
+ RowPresentation( nRecLen );
+ break;
+
+ case 14000: // NAMED SHEET
+ NamedSheet();
+ break;
+ }
+ }
+
+ break;
+ // -----------------------------------------------------------
+ case S_FM3: // S_FM3
+ break;
+ // -----------------------------------------------------------
+ case S_END: // S_END
+ break;
+ // -----------------------------------------------------------
+#ifdef DBG_UTIL
+ default:
+ OSL_FAIL( "*ImportLotus::Read(): State unbekannt!" );
+ eAkt = S_END;
+#endif
+ }
+
+ DBG_ASSERT( nNextRec >= pIn->Tell(),
+ "*ImportLotus::Read(): Etwas zu gierig..." );
+
+ pIn->Seek( nNextRec );
+ aPrgrsBar.Progress();
+ }
+
+ // duemmliche Namen eliminieren
+ SCTAB nTabs = pD->GetTableCount();
+ SCTAB nCnt;
+ String aTabName;
+ String aBaseName;
+ String aRef( RTL_CONSTASCII_USTRINGPARAM( "temp" ) );
+ if( nTabs != 0 )
+ {
+ if( nTabs > 1 )
+ {
+ pD->GetName( 0, aBaseName );
+ aBaseName.Erase( aBaseName.Len() - 1 );
+ }
+ for( nCnt = 1 ; nCnt < nTabs ; nCnt++ )
+ {
+ DBG_ASSERT( pD->HasTable( nCnt ),
+ "-ImportLotus::Read(): Wo ist meine Tabelle?!" );
+ pD->GetName( nCnt, aTabName );
+ if( aTabName == aRef )
+ {
+ aTabName = aBaseName;
+ pD->CreateValidTabName( aTabName );
+ pD->RenameTab( nCnt, aTabName );
+ }
+ }
+ }
+
+ pD->CalcAfterLoad();
+
+ return eRet;
+}
+
+
+FltError ImportLotus::Read( SvStream& rIn )
+{
+ pIn = &rIn;
+
+ sal_Bool bRead = sal_True;
+ sal_uInt16 nOp;
+ sal_uInt16 nRecLen;
+ sal_uInt32 nNextRec = 0UL;
+ FltError eRet = eERR_OK;
+
+ nTab = 0;
+ nExtTab = -1;
+
+ pIn->Seek( nNextRec );
+
+ // Progressbar starten
+ ScfStreamProgressBar aPrgrsBar( *pIn, pD->GetDocumentShell() );
+
+ while( bRead )
+ {
+ *pIn >> nOp >> nRecLen;
+
+ if( pIn->IsEof() )
+ bRead = false;
+ else
+ {
+ nNextRec += nRecLen + 4;
+
+ switch( nOp )
+ {
+ case 0x0000: // BOF
+ if( nRecLen != 26 || !BofFm3() )
+ {
+ bRead = false;
+ eRet = eERR_FORMAT;
+ }
+ break;
+
+ case 0x0001: // EOF
+ bRead = false;
+ DBG_ASSERT( nTab == 0,
+ "-ImportLotus::Read( SvStream& ): Zweimal EOF nicht erlaubt" );
+ nTab++;
+ break;
+
+ case 174: // FONT_FACE
+ Font_Face();
+ break;
+
+ case 176: // FONT_TYPE
+ Font_Type();
+ break;
+
+ case 177: // FONT_YSIZE
+ Font_Ysize();
+ break;
+
+ case 195:
+ if( nExtTab >= 0 )
+ pLotusRoot->pAttrTable->Apply( ( SCTAB ) nExtTab );
+ nExtTab++;
+ break;
+ case 197:
+ _Row( nRecLen );
+ break;
+ }
+
+ DBG_ASSERT( nNextRec >= pIn->Tell(),
+ "*ImportLotus::Read(): Etwas zu gierig..." );
+ pIn->Seek( nNextRec );
+ aPrgrsBar.Progress();
+ }
+ }
+
+ pLotusRoot->pAttrTable->Apply( ( SCTAB ) nExtTab );
+
+ return eRet;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/lotus.cxx b/sc/source/filter/lotus/lotus.cxx
new file mode 100644
index 000000000000..050ede83ff1f
--- /dev/null
+++ b/sc/source/filter/lotus/lotus.cxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "lotimpop.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+
+#include "scerrors.hxx"
+#include "root.hxx"
+#include "filtopt.hxx"
+#include "ftools.hxx"
+
+//------------------------------------------------------------------------
+
+extern FltError ScImportLotus123old( SvStream&, ScDocument*, CharSet eSrc );
+ // alter Krempel in filter.cxx!
+
+FltError ScFormatFilterPluginImpl::ScImportLotus123( SfxMedium& rMedium, ScDocument* pDocument, CharSet eSrc )
+{
+ ScFilterOptions aFilterOpt;
+ sal_Bool bWithWK3 = aFilterOpt.GetWK3Flag();
+
+ SvStream* pStream = rMedium.GetInStream();
+
+ if( !pStream )
+ return eERR_OPEN;
+
+ FltError eRet;
+
+ pStream->Seek( 0UL );
+
+ pStream->SetBufferSize( 32768 );
+
+ ImportLotus aLotusImport( *pStream, pDocument, eSrc );
+
+ if( bWithWK3 )
+ eRet = aLotusImport.Read();
+ else
+ eRet = 0xFFFFFFFF; // WK1 /WKS erzwingen
+
+ // ACHTUNG: QUICK-HACK fuer WK1 / WKS <-> WK3 / WK4
+ if( eRet == 0xFFFFFFFF )
+ {
+ pStream->Seek( 0UL );
+
+ pStream->SetBufferSize( 32768 );
+
+ eRet = ScImportLotus123old( *pStream, pDocument, eSrc );
+
+ pStream->SetBufferSize( 0 );
+
+ return eRet;
+ }
+
+ if( eRet != eERR_OK )
+ return eRet;
+
+ if( pLotusRoot->eFirstType == Lotus_WK3 )
+ {// versuchen *.FM3-File zu laden
+ INetURLObject aURL( rMedium.GetURLObject() );
+ aURL.setExtension( CREATE_STRING( "FM3" ) );
+ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_STD_READ, sal_True );
+ pStream = aMedium.GetInStream();
+ if ( pStream )
+ {
+ if( aLotusImport.Read( *pStream ) != eERR_OK )
+ eRet = SCWARN_IMPORT_WRONG_FM3;
+ }
+ else
+ eRet = SCWARN_IMPORT_OPEN_FM3;
+ }
+
+ return eRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/memory.cxx b/sc/source/filter/lotus/memory.cxx
new file mode 100644
index 000000000000..439d2d010521
--- /dev/null
+++ b/sc/source/filter/lotus/memory.cxx
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+// Bemerkung: Variablen nicht ueber Headerfile, Module muessen sich
+// selbst per extern ihre Sachen besorgen!
+
+
+
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/justifyitem.hxx>
+
+#include "attrib.hxx"
+
+#include "decl.h"
+#include "tool.h"
+
+extern const long nStackSize;
+extern const int nAnzNRange;
+
+extern ScDocument* pDoc;
+
+const long nStackSize = 8L * 1024; // -> form_xxx.cpp
+const int nAnzNRange = 2048; // -> tool_xxx.cpp, max. 2048 Named Ranges
+
+sal_Char* pPuffer; // -> flt_xxx.cxx
+sal_Char* pDummy1; // -> flt_xxx.cxx, ScanVersion()
+sal_Char* pDummy2; // -> tool.cxx, CreateTable()
+
+extern sal_uInt8* pFormelBuffer; // -> tool.cxx, fuer OP_Formula()
+sal_uInt8* pFormelBuffer;
+
+extern FormCache* pValueFormCache; // -> tool.cxx
+
+sal_Char* pStack; // -> formel.cxx
+sal_Char* pPuffer0; // -> formel.cxx
+sal_Char* pPuffer1; // -> formel.cxx
+extern const int nMaxPar;
+const int nMaxPar = 128; // max. 128 Parameter werden unterstuetzt
+sal_Char** pPar; // -> formel.cxx, Pn()
+
+#ifndef _DOS // -> op.cxx
+sal_Char* pAnsi;
+#endif
+sal_Char* pErgebnis; // -> op.cxx
+
+extern sal_Bool bFormInit; // -> tool.cxx, fuer GetFormHandle()
+sal_Bool bFormInit;
+
+extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter,
+ *pAttrRepeat, *pAttrStandard; // -> tool.cxx, fuer GetFormAttr()
+extern ScProtectionAttr* pAttrUnprot; // -> tool.cxx, fuer PutFormString()
+
+
+
+sal_Bool MemNew( void )
+{
+ pPuffer = new sal_Char [ 32L*1024L ];
+
+ pDummy1 = new sal_Char [ 32 ];
+
+ pDummy2 = new sal_Char [ 32 ];
+
+ pStack = new sal_Char [ nStackSize * 3 ]; // alle drei auf einmal
+
+ pPuffer0 = pStack + nStackSize;
+ pPuffer1 = pPuffer0 + nStackSize;
+
+ pAnsi = new sal_Char [ 2048 ];
+
+ pErgebnis = new sal_Char [ 32L*1024L ];
+
+ pPar = new sal_Char *[ nMaxPar ];
+
+ pFormelBuffer = new sal_uInt8[ 4096 ];
+
+ pValueFormCache = new FormCache( pDoc );
+
+ // fuer tool.cxx::PutFormString()
+ pAttrUnprot = new ScProtectionAttr( sal_True );
+ pAttrRight = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY );
+ pAttrLeft = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY );
+ pAttrCenter = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY );
+ pAttrRepeat = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_REPEAT, ATTR_HOR_JUSTIFY );
+ pAttrStandard = new SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY );
+ bFormInit = sal_True;
+
+ return sal_True;
+}
+
+
+void MemDelete( void )
+{
+ delete[] pPuffer;
+ delete[] pDummy1;
+ delete[] pDummy2;
+ delete[] pStack;
+ delete[] pAnsi;
+ delete[] pErgebnis;
+ delete[] pPar;
+ delete[] pFormelBuffer;
+
+ delete pValueFormCache;
+ delete pAttrRight;
+ delete pAttrLeft;
+ delete pAttrCenter;
+ delete pAttrRepeat;
+ delete pAttrStandard;
+ delete pAttrUnprot;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
new file mode 100644
index 000000000000..f0a69cae3358
--- /dev/null
+++ b/sc/source/filter/lotus/op.cxx
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------------
+
+#include <tools/solar.h>
+#include <rtl/math.hxx>
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#if defined( ICC )
+#include <stdlib.h>
+#endif
+
+#include "scitems.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/justifyitem.hxx>
+
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "document.hxx"
+#include "postit.hxx"
+
+#include "op.h"
+#include "optab.h"
+#include "tool.h"
+#include "decl.h"
+#include "lotform.hxx"
+#include "lotrange.hxx"
+
+#include "root.hxx"
+
+#include "ftools.hxx"
+
+#include <vector>
+#include <map>
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#if defined( ICC )
+#include <stdlib.h>
+#endif
+
+extern sal_Char* pAnsi; // -> memory.cxx, Puffer zum Umwandeln von OEM->ANSI
+extern sal_Char* pErgebnis; // -> memory.cxx, Ergebnispuffer
+extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
+extern sal_Bool bEOF; // -> filter.cxx, zeigt Dateiende an
+extern sal_Char* pPuffer0; // -> memory.cxx
+extern sal_Char* pPuffer1;
+extern sal_uInt8 nDefaultFormat; // -> tool.cxx, Default-Zellenformat
+extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
+extern sal_uInt8* pFormelBuffer; // -> memory.cxx, fuer
+extern CharSet eCharVon; // -> filter.cxx, character set specified
+
+static sal_uInt16 nDefWidth = ( sal_uInt16 ) ( TWIPS_PER_CHAR * 10 );
+
+extern std::map<sal_uInt16, ScPatternAttr> aLotusPatternPool;
+
+void NI( SvStream& r, sal_uInt16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_BOF( SvStream& r, sal_uInt16 /*n*/ )
+{
+ r.SeekRel( 2 ); // Versionsnummer ueberlesen
+}
+
+
+void OP_EOF( SvStream& /*r*/, sal_uInt16 /*n*/ )
+{
+ bEOF = sal_True;
+}
+
+
+void OP_Integer( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt8 nFormat;
+ sal_uInt16 nCol, nRow;
+ SCTAB nTab = 0;
+ sal_Int16 nValue;
+
+ r >> nFormat >> nCol >> nRow >> nValue;
+
+ ScValueCell* pZelle = new ScValueCell( ( double ) nValue );
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
+
+ // 0 Stellen nach'm Komma!
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, 0 );
+}
+
+
+void OP_Number( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt8 nFormat;
+ sal_uInt16 nCol, nRow;
+ SCTAB nTab = 0;
+ double fValue;
+
+ r >> nFormat >> nCol >> nRow >> fValue;
+
+ fValue = ::rtl::math::round( fValue, 15 );
+ ScValueCell* pZelle = new ScValueCell( fValue );
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
+}
+
+
+void OP_Label( SvStream& r, sal_uInt16 n )
+{
+ sal_uInt8 nFormat;
+ sal_uInt16 nCol, nRow;
+ SCTAB nTab = 0;
+
+ r >> nFormat >> nCol >> nRow;
+ n -= 5;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[n] = 0;
+
+ nFormat &= 0x80; // Bit 7 belassen
+ nFormat |= 0x75; // protected egal, special-text gesetzt
+
+ PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pText );
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezStd );
+
+ delete [] pText;
+}
+
+void OP_Formula( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt8 nFormat;
+ sal_uInt16 nCol, nRow, nFormulaSize;
+ SCTAB nTab = 0;
+
+ r >> nFormat >> nCol >> nRow;
+ r.SeekRel( 8 ); // Ergebnis ueberspringen
+ r >> nFormulaSize;
+
+ const ScTokenArray* pErg;
+ sal_Int32 nBytesLeft = nFormulaSize;
+ ScAddress aAddress( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab );
+
+ LotusToSc aConv( r, pLotusRoot->eCharsetQ, false );
+ aConv.Reset( aAddress );
+ aConv.Convert( pErg, nBytesLeft );
+
+ ScFormulaCell* pZelle = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
+
+ // nFormat = Standard -> Nachkommastellen wie Float
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
+}
+
+
+void OP_ColumnWidth( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt16 nCol, nBreite;
+ sal_uInt8 nWidthSpaces;
+ SCTAB nTab = 0;
+
+ r >> nCol >> nWidthSpaces;
+
+ if( nWidthSpaces )
+ // Annahme: 10cpi-Zeichensatz
+ nBreite = ( sal_uInt16 ) ( TWIPS_PER_CHAR * nWidthSpaces );
+ else
+ {
+ pDoc->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), 0, true);
+ nBreite = nDefWidth;
+ }
+
+ pDoc->SetColWidth( static_cast<SCCOL> (nCol), nTab, nBreite );
+}
+
+
+void OP_NamedRange( SvStream& r, sal_uInt16 /*n*/ )
+ {
+ // POST: waren Koordinaten ungueltig, wird nicht gespeichert
+ sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
+ sal_Char cPuffer[ 32 ];
+
+ r.Read( cPuffer, 16 );
+
+ r >> nColSt >> nRowSt >> nColEnd >> nRowEnd;
+
+ LotusRange* pRange;
+
+ if( nColSt == nColEnd && nRowSt == nRowEnd )
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
+ else
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
+
+ if( isdigit( *cPuffer ) )
+ { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
+ *pAnsi = 'A';
+ strcpy( pAnsi + 1, cPuffer );
+ }
+ else
+ strcpy( pAnsi, cPuffer );
+
+ String aTmp( pAnsi, pLotusRoot->eCharsetQ );
+
+ ScfTools::ConvertToScDefinedName( aTmp );
+
+ pLotusRoot->pRangeNames->Append( pRange, aTmp );
+}
+
+
+void OP_SymphNamedRange( SvStream& r, sal_uInt16 /*n*/ )
+{
+ // POST: waren Koordinaten ungueltig, wird nicht gespeichert
+ sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
+ sal_uInt8 nType;
+ sal_Char cPuffer[ 32 ];
+
+ r.Read( cPuffer, 16 );
+ cPuffer[ 16 ] = 0;
+
+ r >> nColSt >> nRowSt >> nColEnd >> nRowEnd >> nType;
+
+ LotusRange* pRange;
+
+ if( nType )
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
+ else
+ pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
+
+ if( isdigit( *cPuffer ) )
+ { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
+ *pAnsi = 'A';
+ strcpy( pAnsi + 1, cPuffer );
+ }
+ else
+ strcpy( pAnsi, cPuffer );
+
+ String aTmp( pAnsi, pLotusRoot->eCharsetQ );
+ ScfTools::ConvertToScDefinedName( aTmp );
+
+ pLotusRoot->pRangeNames->Append( pRange, aTmp );
+}
+
+
+void OP_Footer( SvStream& r, sal_uInt16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_Header( SvStream& r, sal_uInt16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_Margins( SvStream& r, sal_uInt16 n )
+{
+ r.SeekRel( n );
+}
+
+
+void OP_HiddenCols( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt16 nByte, nBit;
+ SCCOL nCount;
+ sal_uInt8 nAkt;
+ nCount = 0;
+
+ for( nByte = 0 ; nByte < 32 ; nByte++ ) // 32 Bytes mit ...
+ {
+ r >> nAkt;
+ for( nBit = 0 ; nBit < 8 ; nBit++ ) // ...jeweils 8 Bits = 256 Bits
+ {
+ if( nAkt & 0x01 ) // unterstes Bit gesetzt?
+ // -> Hidden Col
+ pDoc->SetColHidden(nCount, nCount, 0, true);
+
+ nCount++;
+ nAkt = nAkt / 2; // der Naechste bitte...
+ }
+ }
+}
+
+
+void OP_Window1( SvStream& r, sal_uInt16 n )
+{
+ r.SeekRel( 4 ); // Cursor Pos ueberspringen
+
+ r >> nDefaultFormat;
+
+ r.SeekRel( 1 ); // 'unused' ueberspringen
+
+ r >> nDefWidth;
+
+ r.SeekRel( n - 8 ); // und den Rest ueberspringen
+
+ nDefWidth = ( sal_uInt16 ) ( TWIPS_PER_CHAR * nDefWidth );
+
+ // statt Defaulteinstellung in SC alle Cols zu Fuss setzen
+ for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
+ pDoc->SetColWidth( nCol, 0, nDefWidth );
+}
+
+
+void OP_Blank( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt16 nCol, nRow;
+ sal_uInt8 nFormat;
+ r >> nFormat >> nCol >> nRow;
+
+ SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), 0, nFormat, nDezFloat );
+}
+
+void OP_BOF123( SvStream& r, sal_uInt16 /*n*/ )
+{
+ r.SeekRel( 26 );
+}
+
+
+void OP_EOF123( SvStream& /*r*/, sal_uInt16 /*n*/ )
+{
+ bEOF = sal_True;
+}
+
+void OP_Label123( SvStream& r, sal_uInt16 n )
+{
+ sal_uInt8 nTab, nCol;
+ sal_uInt16 nRow;
+ r >> nRow >> nTab >> nCol;
+ n -= 4;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[ n ] = 0;
+
+ PutFormString( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pText );
+
+ delete []pText;
+}
+
+void OP_Number123( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt8 nCol,nTab;
+ sal_uInt16 nRow;
+ sal_uInt32 nValue;
+
+ r >> nRow >> nTab >> nCol >> nValue;
+ double fValue = Snum32ToDouble( nValue );
+
+ ScValueCell *pCell = new ScValueCell( fValue );
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
+}
+
+void OP_Formula123( SvStream& r, sal_uInt16 n )
+{
+ sal_uInt8 nCol,nTab;
+ sal_uInt16 nRow;
+
+ r >> nRow >> nTab >> nCol;
+ r.SeekRel( 8 ); // Result- jump over
+
+ const ScTokenArray* pErg;
+ sal_Int32 nBytesLeft = n - 12;
+ ScAddress aAddress( nCol, nRow, nTab );
+
+ LotusToSc aConv( r, pLotusRoot->eCharsetQ, sal_True );
+ aConv.Reset( aAddress );
+ aConv.Convert( pErg, nBytesLeft );
+
+ ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
+
+ pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
+}
+
+void OP_IEEENumber123( SvStream& r, sal_uInt16 /*n*/ )
+{
+ sal_uInt8 nCol,nTab;
+ sal_uInt16 nRow;
+ double dValue;
+
+ r >> nRow >> nTab >> nCol >> dValue;
+
+ ScValueCell *pCell = new ScValueCell(dValue);
+ pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
+}
+
+void OP_Note123( SvStream& r, sal_uInt16 n)
+{
+ sal_uInt8 nTab, nCol;
+ sal_uInt16 nRow;
+ r >> nRow >> nTab >> nCol;
+ n -= 4;
+
+ sal_Char* pText = new sal_Char[n + 1];
+ r.Read( pText, n );
+ pText[ n ] = 0;
+
+ String aNoteText(pText,pLotusRoot->eCharsetQ);
+ delete [] pText;
+
+ ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
+}
+
+void OP_HorAlign123( sal_uInt8 nAlignPattern, SfxItemSet& rPatternItemSet )
+{
+// pre: Pattern is stored in the last 3 bites of the 21st byte
+// post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern.
+//
+// LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
+// LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
+
+ nAlignPattern = ( nAlignPattern & 0x07);
+
+ switch (nAlignPattern)
+ {
+ case 1:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 2:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 3:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
+ break;
+ case 4:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
+ break;
+ case 6:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK, ATTR_HOR_JUSTIFY ) );
+ break;
+ default:
+ rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
+ break;
+ }
+}
+
+void OP_VerAlign123( sal_uInt8 nAlignPattern,SfxItemSet& rPatternItemSet )
+{
+// pre: Pattern is stored in the last 3 bites of the 22nd byte
+// post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern.
+//
+// TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
+
+ nAlignPattern = ( nAlignPattern & 0x07);
+
+ switch (nAlignPattern)
+ {
+ case 0:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
+ break;
+ case 1:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY) );
+ break;
+ case 2:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY) );
+ break;
+ case 4:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY) );
+ break;
+ default:
+ rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
+ break;
+ }
+}
+
+void OP_CreatePattern123( SvStream& r, sal_uInt16 n)
+{
+ sal_uInt16 nCode,nPatternId;
+
+ ScPatternAttr aPattern(pDoc->GetPool());
+ SfxItemSet& rItemSet = aPattern.GetItemSet();
+
+ r >> nCode;
+ n = n - 2;
+
+ if ( nCode == 0x0fd2 )
+ {
+ r >> nPatternId;
+
+ sal_uInt8 Hor_Align, Ver_Align, temp;
+ sal_Bool bIsBold,bIsUnderLine,bIsItalics;
+
+ r.SeekRel(12);
+
+ // Read 17th Byte
+ r >> temp;
+
+ bIsBold = (temp & 0x01);
+ bIsItalics = (temp & 0x02);
+ bIsUnderLine = (temp & 0x04);
+
+ if ( bIsBold )
+ rItemSet.Put( SvxWeightItem(WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
+ if ( bIsItalics )
+ rItemSet.Put( SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if ( bIsUnderLine )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+
+ r.SeekRel(3);
+
+ // Read 21st Byte
+ r >> Hor_Align;
+ OP_HorAlign123( Hor_Align, rItemSet );
+
+ r >> Ver_Align;
+ OP_VerAlign123( Ver_Align, rItemSet );
+
+ aLotusPatternPool.insert( std::map<sal_uInt16, ScPatternAttr>::value_type( nPatternId, aPattern ) );
+ n = n - 20;
+ }
+ r.SeekRel(n);
+}
+
+void OP_SheetName123( SvStream& rStream, sal_uInt16 nLength )
+{
+ if (nLength <= 4)
+ {
+ rStream.SeekRel(nLength);
+ return;
+ }
+
+ // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
+
+ sal_uInt16 nDummy;
+ rStream >> nDummy; // ignore the first 2 bytes (B0 36).
+ rStream >> nDummy;
+ SCTAB nSheetNum = static_cast<SCTAB>(nDummy);
+ pDoc->MakeTable(nSheetNum);
+
+ ::std::vector<sal_Char> sSheetName;
+ sSheetName.reserve(nLength-4);
+ for (sal_uInt16 i = 4; i < nLength; ++i)
+ {
+ sal_Char c;
+ rStream >> c;
+ sSheetName.push_back(c);
+ }
+
+ if (!sSheetName.empty())
+ {
+ String aName(&sSheetName[0], eCharVon);
+ pDoc->RenameTab(nSheetNum, aName);
+ }
+}
+
+void OP_ApplyPatternArea123( SvStream& rStream )
+{
+ sal_uInt16 nOpcode, nLength;
+ sal_uInt16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0;
+
+ do
+ {
+ rStream >> nOpcode >> nLength;
+ switch ( nOpcode )
+ {
+ case ROW_FORMAT_MARKER:
+ nLevel++;
+ break;
+ case COL_FORMAT_MARKER:
+ nLevel--;
+ if( nLevel == 1 )
+ {
+ nTab = nTab + nTabCount;
+ nCol = 0; nColCount = 0;
+ nRow = 0; nRowCount = 0;
+ }
+ break;
+ case LOTUS_FORMAT_INDEX:
+ if( nLength >= 2 )
+ {
+ rStream >> nData;
+ rStream.SeekRel( nLength - 2 );
+ if( nLevel == 1 )
+ nTabCount = nData;
+ else if( nLevel == 2 )
+ {
+ nCol = nCol + nColCount;
+ nColCount = nData;
+ if ( nCol > 0xff ) // 256 is the max col size supported by 123
+ nCol = 0;
+ }
+ else if( nLevel == 3 )
+ {
+ nRow = nRow + nRowCount;
+ nRowCount = nData;
+ if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123
+ nRow = 0;
+ }
+ }
+ else
+ rStream.SeekRel( nLength );
+ break;
+ case LOTUS_FORMAT_INFO:
+ if( nLength >= 2 )
+ {
+ rStream >> nData;
+ rStream.SeekRel( nLength - 2 );
+ for( int i = 0; i < nTabCount; i++)
+ {
+ std::map<sal_uInt16, ScPatternAttr>::iterator loc = aLotusPatternPool.find( nData );
+
+ // apparently, files with invalid index occur in the wild -> don't crash then
+ DBG_ASSERT( loc != aLotusPatternPool.end(), "invalid format index" );
+ if ( loc != aLotusPatternPool.end() )
+ pDoc->ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second );
+ }
+ }
+ else
+ rStream.SeekRel( nLength );
+ break;
+ default:
+ rStream.SeekRel( nLength );
+ break;
+ }
+ }
+ while( nLevel && !rStream.IsEof() );
+
+ aLotusPatternPool.clear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/optab.cxx b/sc/source/filter/lotus/optab.cxx
new file mode 100644
index 000000000000..bf880614d48d
--- /dev/null
+++ b/sc/source/filter/lotus/optab.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "op.h"
+#include "optab.h"
+
+
+// Bearbeitungsfunktion sal_Char *X( sal_Char * )
+OPCODE_FKT pOpFkt[ FKT_LIMIT ] =
+{ // Code
+ OP_BOF, // 0
+ OP_EOF, // 1
+ NI, // 2
+ NI, // 3
+ NI, // 4
+ NI, // 5
+ NI, // 6
+ OP_Window1, // 7
+ OP_ColumnWidth, // 8
+ NI, // 9
+ NI, // 10
+ OP_NamedRange, // 11
+ OP_Blank, // 12
+ OP_Integer, // 13
+ OP_Number, // 14
+ OP_Label, // 15
+ OP_Formula, // 16
+ NI, // 17
+ NI, // 18
+ NI, // 19
+ NI, // 20
+ NI, // 21
+ NI, // 22
+ NI, // 23
+ NI, // 24
+ NI, // 25
+ NI, // 26
+ NI, // 27
+ NI, // 28
+ NI, // 29
+ NI, // 30
+ NI, // 31
+ NI, // 32
+ NI, // 33
+ NI, // 34
+ NI, // 35
+ NI, // 36
+ OP_Footer, // 37
+ OP_Header, // 38
+ NI, // 39
+ OP_Margins, // 40
+ NI, // 41
+ NI, // 42
+ NI, // 43
+ NI, // 44
+ NI, // 45
+ NI, // 46
+ NI, // 47
+ NI, // 48
+ NI, // 49
+ NI, // 50
+ NI, // 51
+ NI, // 52
+ NI, // 53
+ NI, // 54
+ NI, // 55
+ NI, // 56
+ NI, // 57
+ NI, // 58
+ NI, // 59
+ NI, // 60
+ NI, // 61
+ NI, // 62
+ NI, // 63
+ NI, // 64
+ NI, // 65
+ NI, // 66
+ NI, // 67
+ NI, // 68
+ NI, // 69
+ NI, // 70
+ OP_SymphNamedRange, // 71
+ NI, // 72
+ NI, // 73
+ NI, // 74
+ NI, // 75
+ NI, // 76
+ NI, // 77
+ NI, // 78
+ NI, // 79
+ NI, // 80
+ NI, // 81
+ NI, // 82
+ NI, // 83
+ NI, // 84
+ NI, // 85
+ NI, // 86
+ NI, // 87
+ NI, // 88
+ NI, // 89
+ NI, // 90
+ NI, // 91
+ NI, // 92
+ NI, // 93
+ NI, // 94
+ NI, // 95
+ NI, // 96
+ NI, // 97
+ NI, // 98
+ NI, // 99
+ OP_HiddenCols, // 100
+};
+
+
+OPCODE_FKT pOpFkt123[ FKT_LIMIT123 ] =
+{ // Code
+ OP_BOF123, // 0
+ OP_EOF123, // 1
+ NI, // 2
+ NI, // 3
+ NI, // 4
+ NI, // 5
+ NI, // 6
+ NI, // 7
+ NI, // 8
+ NI, // 9
+ NI, // 10
+ NI, // 11
+ NI, // 12
+ NI, // 13
+ NI, // 14
+ NI, // 15
+ NI, // 16
+ NI, // 17
+ NI, // 18
+ NI, // 19
+ NI, // 20
+ NI, // 21
+ OP_Label123, // 22
+ NI, // 23
+ NI, // 24
+ NI, // 25
+ NI, // 26
+ OP_CreatePattern123, // 27
+ NI, // 28
+ NI, // 29
+ NI, // 30
+ NI, // 31
+ NI, // 32
+ NI, // 33
+ NI, // 34
+ OP_SheetName123, // 35
+ NI, // 36
+ OP_Number123, // 37
+ OP_Note123, // 38
+ OP_IEEENumber123, // 39
+ OP_Formula123, // 40
+ NI, // 41
+ NI, // 42
+ NI, // 43
+ NI, // 44
+ NI, // 45
+ NI, // 46
+ NI, // 47
+ NI, // 48
+ NI, // 49
+ NI, // 50
+ NI, // 51
+ NI, // 52
+ NI, // 53
+ NI, // 54
+ NI, // 55
+ NI, // 56
+ NI, // 57
+ NI, // 58
+ NI, // 59
+ NI, // 60
+ NI, // 61
+ NI, // 62
+ NI, // 63
+ NI, // 64
+ NI, // 65
+ NI, // 66
+ NI, // 67
+ NI, // 68
+ NI, // 69
+ NI, // 70
+ NI, // 71
+ NI, // 72
+ NI, // 73
+ NI, // 74
+ NI, // 75
+ NI, // 76
+ NI, // 77
+ NI, // 78
+ NI, // 79
+ NI, // 80
+ NI, // 81
+ NI, // 82
+ NI, // 83
+ NI, // 84
+ NI, // 85
+ NI, // 86
+ NI, // 87
+ NI, // 88
+ NI, // 89
+ NI, // 90
+ NI, // 91
+ NI, // 92
+ NI, // 93
+ NI, // 94
+ NI, // 95
+ NI, // 96
+ NI, // 97
+ NI, // 98
+ NI, // 99
+ NI // 100
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/lotus/tool.cxx b/sc/source/filter/lotus/tool.cxx
new file mode 100644
index 000000000000..3688066fcb6a
--- /dev/null
+++ b/sc/source/filter/lotus/tool.cxx
@@ -0,0 +1,654 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/algitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/zforlist.hxx>
+#include <tools/solar.h>
+
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "compiler.hxx"
+
+#include "tool.h"
+#include "decl.h"
+#include "root.hxx"
+#include "lotrange.hxx"
+#include "namebuff.hxx"
+#include "ftools.hxx"
+
+#include <math.h>
+
+#ifdef _MSC_VER
+#pragma optimize("",off)
+#endif
+
+//--------------------------------------------------------- EXTERNE VARIABLEN -
+extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
+extern sal_Char* pDummy2; // -> memory.cxx
+extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
+extern CharSet eCharNach; // -> filter.cxx, Zeichenkonvertierung von->nach
+
+extern sal_Bool bFormInit; // -> memory.cxx, fuer GetFormHandle()
+
+//--------------------------------------------------------- GLOBALE VARIABLEN -
+sal_uInt8 nDefaultFormat; // -> op.cpp, Standard-Zellenformat
+
+extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
+extern ScProtectionAttr* pAttrUnprot;
+extern SfxUInt32Item** pAttrValForms;
+
+SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
+ // -> in memory.cxx initialisiert
+ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
+
+extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
+FormCache* pValueFormCache;
+
+SCCOL LotusRangeList::nEingCol;
+SCROW LotusRangeList::nEingRow;
+
+
+
+
+void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
+{
+ // Label-Format-Auswertung
+ DBG_ASSERT( pString != NULL, "PutFormString(): pString == NULL" );
+
+ sal_Char cForm;
+ SvxHorJustifyItem* pJustify = NULL;
+
+ cForm = *pString;
+
+ switch( cForm )
+ {
+ case '"': // rechtsbuendig
+ pJustify = pAttrRight;
+ pString++;
+ break;
+ case '\'': // linksbuendig
+ pJustify = pAttrLeft;
+ pString++;
+ break;
+ case '^': // zentriert
+ pJustify = pAttrCenter;
+ pString++;
+ break;
+ case '|': // printer command
+ pString = NULL;
+ break;
+ case '\\': // Wiederholung
+ pJustify = pAttrRepeat;
+ pString++;
+ break;
+ default: // kenn' ich nicht!
+ pJustify = pAttrStandard;
+ }
+
+ if( pString )
+ {
+ pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
+ ScStringCell* pZelle = new ScStringCell( String( pString, pLotusRoot->eCharsetQ ) );
+ pDoc->PutCell( nCol, nRow, nTab, pZelle, ( sal_Bool ) sal_True );
+ }
+}
+
+
+
+
+void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt )
+{
+ // PREC: nSt = Standard-Dezimalstellenanzahl
+ pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
+
+ ScProtectionAttr aAttr;
+
+ aAttr.SetProtection( nFormat & 0x80 );
+
+ pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
+}
+
+void InitPage( void )
+{ // Seitenformat initialisieren, d.h. Default-Werte von SC holen
+ //scGetPageFormat( 0, &aPage );
+}
+
+
+double SnumToDouble( sal_Int16 nVal )
+{
+ const double pFacts[ 8 ] = {
+ 5000.0,
+ 500.0,
+ 0.05,
+ 0.005,
+ 0.0005,
+ 0.00005,
+ 0.0625,
+ 0.015625 };
+
+ double fVal;
+
+ if( nVal & 0x0001 )
+ {
+ fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
+ fVal *= ( sal_Int16 ) ( nVal >> 4 );
+ }
+ else
+ fVal = ( sal_Int16 ) ( nVal >> 1 );
+
+ return fVal;
+}
+
+double Snum32ToDouble( sal_uInt32 nValue )
+{
+ double fValue, temp;
+
+ fValue = nValue >> 6;
+ temp = nValue & 0x0f;
+ if (temp)
+ {
+ if (nValue & 0x00000010)
+ fValue /= pow((double)10, temp);
+ else
+ fValue *= pow((double)10, temp);
+ }
+
+ if ((nValue & 0x00000020))
+ fValue = -fValue;
+ return fValue;
+}
+
+
+FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
+{ // Default-Format ist 'Default'
+ nDefaultFormat = nNewDefaultFormat;
+ pFormTable = pDoc1->GetFormatTable();
+ for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
+ bValid[ nC ] = false;
+ eLanguage = ScGlobal::eLnge;
+}
+
+
+FormCache::~FormCache()
+{
+ for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
+ delete aIdents[ nC ].GetAttr();
+}
+
+
+SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
+{
+ // neues Format erzeugen
+ sal_uInt8 nL, nH; // Low-/High-Nibble
+ sal_uInt8 nForm = nFormat;
+ String aFormString;
+ const sal_Char* pFormString = 0;
+ sal_Int16 eType = NUMBERFORMAT_ALL;
+ sal_uInt32 nIndex1;
+ sal_uInt32 nHandle;
+ sal_Bool bDefault = false;
+ //void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
+ // sal_Bool bThousand, sal_Bool IsRed, sal_uInt16 nPrecision, sal_uInt16 nAnzLeading );
+
+ if( nForm == 0xFF ) // Default-Format?
+ nForm = nDefaultFormat;
+
+ // Aufdroeseln in Low- und High-Nibble
+ nL = nFormat & 0x0F;
+ nH = ( nFormat & 0xF0 ) / 16;
+
+ nH &= 0x07; // Bits 4-6 'rausziehen
+ switch( nH )
+ {
+ case 0x00: // Festkommaformat (fixed)
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ break;
+ case 0x01: // Exponentdarstellung (scientific notation)
+ //fExponent;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_SCIENTIFIC, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ break;
+ case 0x02: // Waehrungsdarstellung (currency)
+ //fMoney;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_CURRENCY, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ break;
+ case 0x03: // Prozent
+ //fPercent;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_PERCENT, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ break;
+ case 0x04: // Komma
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, sal_True, false, nL, 1 );
+ break;
+ case 0x05: // frei
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ break;
+ case 0x06: // frei
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ nIndex1 = 0;
+ break;
+ case 0x07: // Spezialformat
+ switch( nL )
+ {
+ case 0x00: // +/-
+ //fStandard;nSt;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, sal_True, nSt, 1 );
+ break;
+ case 0x01: // generelles Format
+ //fStandard;nSt;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nSt, 1 );
+ break;
+ case 0x02: // Datum: Tag, Monat, Jahr
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x03: // Datum: Tag, Monat
+ //fDate;dfDayMonthLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MMMM";
+ break;
+ case 0x04: // Datum: Monat, Jahr
+ //fDate;dfMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "MM.JJJJ";
+ break;
+ case 0x05: // Textformate
+ //fString;nSt;
+ eType = NUMBERFORMAT_TEXT;
+ pFormString = "@";
+ break;
+ case 0x06: // versteckt
+ //wFlag |= paHideAll;bSetFormat = sal_False;
+ eType = NUMBERFORMAT_NUMBER;
+ pFormString = "";
+ break;
+ case 0x07: // Time: hour, min, sec
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x08: // Time: hour, min
+ //fTime;tfHourMin24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM";
+ break;
+ case 0x09: // Date, intern sal_Int32 1
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x0A: // Date, intern sal_Int32 2
+ //fDate;dfDayMonthYearLong;
+ eType = NUMBERFORMAT_DATE;
+ pFormString = "TT.MM.JJJJ";
+ break;
+ case 0x0B: // Time, intern sal_Int32 1
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x0C: // Time, intern sal_Int32 2
+ //fTime;tfHourMinSec24;
+ eType = NUMBERFORMAT_TIME;
+ pFormString = "HH:MM:SS";
+ break;
+ case 0x0F: // Standardeinstellung
+ //fStandard;nSt;
+ bDefault = sal_True;
+ break;
+ default:
+ //fStandard;nSt;
+ bDefault = sal_True;
+ break;
+ }
+ break;
+ default:
+ //fStandard;nL;
+ nIndex1 = pFormTable->GetStandardFormat(
+ NUMBERFORMAT_NUMBER, eLanguage );
+ pFormTable->GenerateFormat( aFormString, nIndex1,
+ eLanguage, false, false, nL, 1 );
+ nIndex1 = 0;
+ break;
+ }
+
+ // Format in Table schieben
+ if( bDefault )
+ nHandle = 0;
+ else
+ {
+ if( pFormString )
+ aFormString.AssignAscii( pFormString );
+
+ xub_StrLen nDummy;
+ pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
+ }
+
+ return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
+}
+
+
+
+
+void LotusRange::MakeHash( void )
+{
+ // 33222222222211111111110000000000
+ // 10987654321098765432109876543210
+ // ******** nColS
+ // ******** nColE
+ // **************** nRowS
+ // **************** nRowE
+ nHash = static_cast<sal_uInt32>(nColStart);
+ nHash += static_cast<sal_uInt32>(nColEnd) << 6;
+ nHash += static_cast<sal_uInt32>(nRowStart) << 12;
+ nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
+}
+
+
+LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
+{
+ nColStart = nColEnd = nCol;
+ nRowStart = nRowEnd = nRow;
+ nId = ID_FAIL;
+ MakeHash();
+}
+
+
+LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
+{
+ nColStart = nCS;
+ nColEnd = nCE;
+ nRowStart = nRS;
+ nRowEnd = nRE;
+ nId = ID_FAIL;
+ MakeHash();
+}
+
+
+LotusRange::LotusRange( const LotusRange& rCpy )
+{
+ Copy( rCpy );
+}
+
+
+
+
+
+LotusRangeList::LotusRangeList( void )
+{
+ aComplRef.InitFlags();
+
+ ScSingleRefData* pSingRef;
+ nIdCnt = 1;
+
+ pSingRef = &aComplRef.Ref1;
+ pSingRef->nTab = pSingRef->nRelTab = 0;
+ pSingRef->SetColRel( false );
+ pSingRef->SetRowRel( false );
+ pSingRef->SetTabRel( sal_True );
+ pSingRef->SetFlag3D( false );
+
+ pSingRef = &aComplRef.Ref2;
+ pSingRef->nTab = pSingRef->nRelTab = 0;
+ pSingRef->SetColRel( false );
+ pSingRef->SetRowRel( false );
+ pSingRef->SetTabRel( sal_True );
+ pSingRef->SetFlag3D( false );
+}
+
+
+LotusRangeList::~LotusRangeList( void )
+ {
+ LotusRange *pDel = ( LotusRange * ) List::First();
+
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( LotusRange * ) List::Next();
+ }
+ }
+
+
+LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
+{
+ LotusRange* pComp = ( LotusRange* ) List::First();
+
+ while( pComp )
+ {
+ if( *pComp == rRef )
+ return pComp->nId;
+ pComp = ( LotusRange* ) List::Next();
+ }
+
+ return ID_FAIL;
+}
+
+
+void LotusRangeList::Append( LotusRange* pLR, const String& rName )
+{
+ DBG_ASSERT( pLR, "*LotusRangeList::Append(): das wird nichts!" );
+ List::Insert( pLR, CONTAINER_APPEND );
+
+ ScTokenArray aTokArray;
+
+ ScSingleRefData* pSingRef = &aComplRef.Ref1;
+
+ pSingRef->nCol = pLR->nColStart;
+ pSingRef->nRow = pLR->nRowStart;
+
+ if( pLR->IsSingle() )
+ aTokArray.AddSingleReference( *pSingRef );
+ else
+ {
+ pSingRef = &aComplRef.Ref2;
+ pSingRef->nCol = pLR->nColEnd;
+ pSingRef->nRow = pLR->nRowEnd;
+ aTokArray.AddDoubleReference( aComplRef );
+ }
+
+ ScRangeData* pData = new ScRangeData(
+ pLotusRoot->pDoc, rName, aTokArray );
+
+ pLotusRoot->pScRangeName->insert( pData );
+
+ pLR->SetId( nIdCnt );
+
+ nIdCnt++;
+}
+
+
+
+
+RangeNameBufferWK3::RangeNameBufferWK3( void )
+{
+ pScTokenArray = new ScTokenArray;
+ nIntCount = 1;
+}
+
+
+RangeNameBufferWK3::~RangeNameBufferWK3()
+{
+ ENTRY* pDel = ( ENTRY* ) List::First();
+
+ while( pDel )
+ {
+ delete pDel;
+ pDel = ( ENTRY* ) List::Next();
+ }
+
+ delete pScTokenArray;
+}
+
+
+void RangeNameBufferWK3::Add( const String& rOrgName, const ScComplexRefData& rCRD )
+{
+ String aScName( rOrgName );
+ ScfTools::ConvertToScDefinedName( aScName );
+
+ register ENTRY* pInsert = new ENTRY( rOrgName, aScName, rCRD );
+
+ List::Insert( pInsert, CONTAINER_APPEND );
+
+ pScTokenArray->Clear();
+
+ register const ScSingleRefData& rRef1 = rCRD.Ref1;
+ register const ScSingleRefData& rRef2 = rCRD.Ref2;
+
+ if( rRef1.nCol == rRef2.nCol && rRef1.nRow == rRef2.nRow && rRef1.nTab == rRef2.nTab )
+ {
+ pScTokenArray->AddSingleReference( rCRD.Ref1 );
+ pInsert->bSingleRef = sal_True;
+ }
+ else
+ {
+ pScTokenArray->AddDoubleReference( rCRD );
+ pInsert->bSingleRef = false;
+ }
+
+ ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
+
+ pInsert->nRelInd = nIntCount;
+ pData->SetIndex( nIntCount );
+ nIntCount++;
+
+ pLotusRoot->pScRangeName->insert( pData );
+}
+
+
+sal_Bool RangeNameBufferWK3::FindRel( const String& rRef, sal_uInt16& rIndex )
+{
+ StringHashEntry aRef( rRef );
+
+ ENTRY* pFind = ( ENTRY* ) List::First();
+
+ while( pFind )
+ {
+ if( aRef == pFind->aStrHashEntry )
+ {
+ rIndex = pFind->nRelInd;
+ return sal_True;
+ }
+ pFind = ( ENTRY* ) List::Next();
+ }
+
+ return false;
+}
+
+
+sal_Bool RangeNameBufferWK3::FindAbs( const String& rRef, sal_uInt16& rIndex )
+{
+ String aTmp( rRef );
+ StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
+
+ ENTRY* pFind = ( ENTRY* ) List::First();
+
+ while( pFind )
+ {
+ if( aRef == pFind->aStrHashEntry )
+ {
+ // eventuell neuen Range Name aufbauen
+ if( pFind->nAbsInd )
+ rIndex = pFind->nAbsInd;
+ else
+ {
+ ScSingleRefData* pRef = &pFind->aScComplexRefDataRel.Ref1;
+ pScTokenArray->Clear();
+
+ pRef->SetColRel( false );
+ pRef->SetRowRel( false );
+ pRef->SetTabRel( sal_True );
+
+ if( pFind->bSingleRef )
+ pScTokenArray->AddSingleReference( *pRef );
+ else
+ {
+ pRef = &pFind->aScComplexRefDataRel.Ref2;
+ pRef->SetColRel( false );
+ pRef->SetRowRel( false );
+ pRef->SetTabRel( sal_True );
+ pScTokenArray->AddDoubleReference( pFind->aScComplexRefDataRel );
+ }
+
+ ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, pFind->aScAbsName, *pScTokenArray );
+
+ rIndex = pFind->nAbsInd = nIntCount;
+ pData->SetIndex( rIndex );
+ nIntCount++;
+
+ pLotusRoot->pScRangeName->insert( pData );
+ }
+
+ return sal_True;
+ }
+ pFind = ( ENTRY* ) List::Next();
+ }
+
+ return false;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/qpro/biff.cxx b/sc/source/filter/qpro/biff.cxx
new file mode 100644
index 000000000000..8aa59a986b99
--- /dev/null
+++ b/sc/source/filter/qpro/biff.cxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "biff.hxx"
+
+ScBiffReader::ScBiffReader( SfxMedium & rMedium ) :
+ mnId(0),
+ mnLength(0),
+ mnOffset(0)
+{
+ mpStream = rMedium.GetInStream();
+ if( mpStream )
+ {
+ mpStream->SetBufferSize( 65535 );
+ mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
+ }
+}
+
+ScBiffReader::~ScBiffReader()
+{
+ if( mpStream )
+ mpStream->SetBufferSize( 0 );
+}
+
+bool ScBiffReader::nextRecord()
+{
+ if( !recordsLeft() )
+ return false;
+
+ if( IsEndOfFile() )
+ return false;
+
+ sal_uInt32 nPos = mpStream->Tell();
+ if( nPos != mnOffset + mnLength )
+ mpStream->Seek( mnOffset + mnLength );
+
+ mnLength = mnId = 0;
+ *mpStream >> mnId >> mnLength;
+
+ mnOffset = mpStream->Tell();
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
+ (unsigned)mnId, (unsigned)mnLength, (unsigned)mnOffset );
+
+#if 1 // rather verbose
+ int len = mnLength;
+ while (len > 0) {
+ int i, chunk = len < 16 ? len : 16;
+ unsigned char data[16];
+ mpStream->Read( data, chunk );
+
+ for (i = 0; i < chunk; i++)
+ fprintf( stderr, "%.2x ", data[i] );
+ fprintf( stderr, "| " );
+ for (i = 0; i < chunk; i++)
+ fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
+ fprintf( stderr, "\n" );
+
+ len -= chunk;
+ }
+ mpStream->Seek( mnOffset );
+#endif
+#endif
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/qpro/qpro.cxx b/sc/source/filter/qpro/qpro.cxx
new file mode 100644
index 000000000000..9f170d1bf7ec
--- /dev/null
+++ b/sc/source/filter/qpro/qpro.cxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "qproform.hxx"
+#include "qpro.hxx"
+#include "qprostyle.hxx"
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "biff.hxx"
+#include <tools/stream.hxx>
+
+FltError ScQProReader::readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pStyle )
+{
+ FltError eRet = eERR_OK;
+ sal_uInt8 nCol, nDummy;
+ sal_uInt16 nRow;
+ sal_uInt16 nStyle;
+ bool bEndOfSheet = false;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "Read sheet (%d)\n", nTab );
+#endif
+
+ while( eERR_OK == eRet && !bEndOfSheet && nextRecord() )
+ {
+ switch( getId() )
+ {
+ case 0x000f:{ // Label cell
+ String aLabel;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nDummy;
+ readString( aLabel, getLength() - 7 );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( aLabel, pDoc ), (sal_Bool) sal_True );
+ }
+ break;
+
+ case 0x00cb: // End of sheet
+ bEndOfSheet = true;
+ break;
+
+ case 0x000c: // Blank cell
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle;
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ break;
+
+ case 0x000d:{ // Integer cell
+ sal_Int16 nValue;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
+ ScValueCell* pInteger = new ScValueCell( ( double ) nValue );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell(nCol ,nRow, nTab ,pInteger,(sal_Bool) sal_True);
+ }
+ break;
+
+ case 0x000e:{ // Floating point cell
+ double nValue;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
+ ScValueCell* pFloat = new ScValueCell( nValue );
+ nStyle = nStyle >> 3;
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, pFloat, (sal_Bool) sal_True );
+ }
+ break;
+
+ case 0x0010:{ // Formula cell
+ double nValue;
+ sal_uInt16 nState, nLen;
+ *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue >> nState >> nLen;
+ ScAddress aAddr( nCol, nRow, nTab );
+ const ScTokenArray *pArray;
+ QProToSc aConv( *mpStream, aAddr );
+ if (ConvOK != aConv.Convert( pArray, nLen ))
+ eRet = eERR_FORMAT;
+ else
+ {
+ ScFormulaCell *pFormula = new ScFormulaCell( pDoc, aAddr, pArray );
+ nStyle = nStyle >> 3;
+ pFormula->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
+ pDoc->PutCell( nCol, nRow, nTab, pFormula, ( sal_Bool ) sal_True );
+ }
+ }
+ break;
+ }
+ }
+ return eRet;
+}
+
+FltError ScFormatFilterPluginImpl::ScImportQuattroPro( SfxMedium &rMedium, ScDocument *pDoc )
+{
+ FltError eRet = eERR_OK;
+ ScQProReader aReader( rMedium );
+ eRet = aReader.import( pDoc );
+ return eRet;
+}
+
+ScQProReader::ScQProReader( SfxMedium &rMedium ):
+ ScBiffReader( rMedium )
+{
+}
+
+FltError ScQProReader::import( ScDocument *pDoc )
+{
+ FltError eRet = eERR_OK;
+ sal_uInt16 nVersion;
+ sal_uInt16 i = 1, j = 1;
+ SCTAB nTab = 0;
+ SetEof( false );
+
+ if( !recordsLeft() )
+ return eERR_OPEN;
+
+ ScQProStyle *pStyleElement = new ScQProStyle;
+
+ while( nextRecord() && eRet == eERR_OK)
+ {
+ switch( getId() )
+ {
+ case 0x0000: // Begginning of file
+ *mpStream >> nVersion;
+ break;
+
+ case 0x00ca: // Beginning of sheet
+ if( nTab <= MAXTAB )
+ {
+ if( nTab < 26 )
+ {
+ String aName;
+ aName.Append( sal_Unicode( 'A' + nTab ) );
+ if (!nTab)
+ pDoc->RenameTab( nTab, aName, false, false);
+ else
+ pDoc->InsertTab( nTab, aName );
+ }
+ eRet = readSheet( nTab, pDoc, pStyleElement );
+ nTab++;
+ }
+ break;
+
+ case 0x0001: // End of file
+ SetEof( sal_True );
+ break;
+
+ case 0x00ce:{ // Attribute cell
+ sal_uInt8 nFormat, nAlign, nFont;
+ sal_Int16 nColor;
+ *mpStream >> nFormat >> nAlign >> nColor >> nFont;
+ pStyleElement->setAlign( i, nAlign );
+ pStyleElement->setFont( i, nFont );
+ i++;
+ }
+ break;
+
+ case 0x00cf:{ // Font description
+ sal_uInt16 nPtSize, nFontAttr;
+ String aLabel;
+ *mpStream >> nPtSize >> nFontAttr;
+ pStyleElement->setFontRecord( j, nFontAttr, nPtSize );
+ readString( aLabel, getLength() - 4 );
+ pStyleElement->setFontType( j, aLabel );
+ j++;
+ }
+ break;
+ }
+ }
+ pDoc->CalcAfterLoad();
+ delete pStyleElement;
+ return eRet;
+}
+
+bool ScQProReader::recordsLeft()
+{
+ bool bValue = ScBiffReader::recordsLeft();
+ return bValue;
+}
+
+bool ScQProReader::nextRecord()
+{
+ bool bValue = ScBiffReader::nextRecord();
+ return bValue;
+}
+
+void ScQProReader::readString( String &rString, sal_uInt16 nLength )
+{
+ sal_Char* pText = new sal_Char[ nLength + 1 ];
+ mpStream->Read( pText, nLength );
+ pText[ nLength ] = 0;
+ rString = String( pText, mpStream->GetStreamCharSet() );
+ delete [] pText;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/qpro/qproform.cxx b/sc/source/filter/qpro/qproform.cxx
new file mode 100644
index 000000000000..b3c17cd5becd
--- /dev/null
+++ b/sc/source/filter/qpro/qproform.cxx
@@ -0,0 +1,749 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <sal/config.h>
+#include <sal/macros.h>
+#include "qpro.hxx"
+
+#include "qproform.hxx"
+#include "formel.hxx"
+#include "compiler.hxx"
+#include <tokstack.hxx>
+#include "ftools.hxx"
+
+void QProToSc::ReadSRD( ScSingleRefData& rSRD, sal_Int8 nPage, sal_Int8 nCol, sal_uInt16 nRelBit )
+{
+ sal_uInt16 nTmp = nRelBit & 0x1fff;
+ rSRD.InitAddress( ScAddress( nCol, (~nTmp + 1), 0 ) );
+ if( nRelBit & 0x4000 )
+ {
+ rSRD.nRelCol = nCol;
+ rSRD.SetColRel( sal_True );
+ }
+ else
+ {
+ rSRD.nCol = nCol;
+ rSRD.SetColRel( false );
+ }
+ if( nRelBit & 0x2000 )
+ {
+ rSRD.nRelRow = (~nTmp + 1);
+ rSRD.nRelRow = (sal_Int16)(nTmp << 3);
+ rSRD.nRelRow /= 8;
+ rSRD.SetRowRel( sal_True );
+ }
+ else
+ {
+ rSRD.nRow = nTmp;
+ rSRD.SetRowRel( false );
+ }
+ if( nRelBit & 0x8000 )
+ {
+ rSRD.nRelTab = nPage;
+ rSRD.SetTabRel( sal_True );
+ // absolute tab needed in caller for comparison in case of DoubleRef
+ rSRD.nTab = aEingPos.Tab() + nPage;
+ }
+ else
+ {
+ rSRD.nTab = nPage;
+ rSRD.SetTabRel( false );
+ }
+ if (rSRD.nTab != aEingPos.Tab())
+ rSRD.SetFlag3D( sal_True);
+}
+
+QProToSc::QProToSc( SvStream& rStream, const ScAddress& rRefPos ) :
+ ConverterBase( 128 ),
+ maIn( rStream )
+{
+ aEingPos = rRefPos;
+}
+
+void QProToSc::DoFunc( DefTokenId eOc, sal_uInt16 nArgs, const sal_Char* pExtString )
+{
+ TokenId eParam[ nBufSize ];
+ sal_Int32 nCount;
+ TokenId nPush, nPush1;
+
+ sal_Bool bAddIn = false;
+ sal_Bool bNeg = false;
+
+ if( eOc == ocNoName )
+ {
+ bAddIn = sal_True;
+ if( pExtString )
+ {
+ ByteString s;
+ s = pExtString;
+ s.Insert( "QPRO_", 0 );
+ nPush = aPool.Store( eOc, String( s, maIn.GetStreamCharSet() ) );
+ aPool << nPush;
+ }
+ else
+ aPool << ocNoName;
+ }
+
+ if( nArgs < nBufSize )
+ {
+ for( nCount = 0; nCount < nArgs ; nCount++ )
+ aStack >> eParam[ nCount ];
+ }
+ else
+ return;
+
+ switch( eOc )
+ {
+ case ocIndex:
+ nPush = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nPush;
+ IncToken( eParam[ 0 ] );
+ IncToken( eParam[ 1 ] );
+ break;
+
+ case ocIRR:
+ nPush = eParam[ 0 ];
+ eParam[ 0 ] = eParam[ 1 ];
+ eParam[ 1 ] = nPush;
+ break;
+
+ case ocGetYear:
+ nPush = aPool.Store( 1900.0 );
+ aPool << ocOpen;
+ break;
+
+ default:
+ break;
+ }
+
+ if( !bAddIn )
+ aPool << eOc;
+
+ aPool << ocOpen;
+
+ if( nArgs> 0 )
+ {
+ sal_Int16 nLast = nArgs- 1;
+
+ if( eOc == ocZGZ )
+ aPool << eParam[ 2 ] << ocSep << eParam[ 1 ] << ocSep << eParam[ 0 ];
+ if( eOc == ocZinsZ )
+ aPool << eParam[ 3 ] << ocSep << eParam[ 2 ] << ocSep << eParam[ 1 ] << ocSep << eParam[ 0 ];
+ else
+ {
+ sal_Int16 nNull = -1;
+ aPool << eParam[ nLast ];
+ for( nCount = nLast - 1 ; nCount >= 0 ; nCount-- )
+ {
+ if( nCount != nNull )
+ aPool << ocSep << eParam[ nCount ];
+ }
+ }
+ }
+
+ if( eOc == ocGetYear )
+ aPool << ocClose << ocSub << nPush;
+ else if( eOc == ocFixed )
+ aPool << ocSep << ocTrue << ocOpen << ocClose;
+
+ aPool << ocClose;
+ aPool >> aStack;
+
+ if( bNeg )
+ {
+ aPool << ocOpen << ocSub << aStack << ocClose;
+ aPool >> aStack;
+ }
+}
+
+void QProToSc::IncToken( TokenId &rParam )
+{
+ aPool << ocOpen << rParam << mnAddToken;
+ rParam = aPool.Store();
+}
+
+#define SAFEDEC_OR_RET(nRef, amt, ret) \
+do { \
+ if (nRef < amt)\
+ return ret; \
+ nRef-=amt; \
+} while(0)
+
+ConvErr QProToSc::Convert( const ScTokenArray*& pArray, sal_uInt16 /*nLen*/, const FORMULA_TYPE /*eFT*/ )
+{
+ sal_uInt8 nFmla[ nBufSize ], i, nArg, nArgArray[ nBufSize ];
+ sal_Int8 nCol, nPage;
+ sal_uInt16 nInt, nIntCount = 0, nStringCount = 0, nFloatCount = 0, nDLLCount = 0, nIntArray[ nBufSize ], nArgCount = 0;
+ String sStringArray[ nBufSize ];
+ sal_uInt16 nDummy, nDLLId, nDLLArray[ nBufSize ];
+ sal_uInt16 nNote, nRef, nRelBits;
+ TokenId nPush;
+ ScComplexRefData aCRD;
+ ScSingleRefData aSRD;
+ FUNC_TYPE eType;
+ DefTokenId eOc;
+ double nFloatArray[ nBufSize ], nFloat;
+ const sal_Char* pExtString = 0;
+
+ aCRD.InitFlags();
+ aSRD.InitFlags();
+ maIn >> nRef;
+
+ if( nRef < nBufSize )
+ {
+ for( i=0; i < nRef; i++)
+ {
+ maIn >> nFmla[i];
+
+ if( nFmla[ i ] == 0x05 )
+ {
+ maIn >> nInt;
+ nIntArray[ nIntCount ] = nInt;
+ SAFEDEC_OR_RET(nRef, 2, ConvErrCount);
+ nIntCount++;
+ }
+
+ if( nFmla[ i ] == 0x00 )
+ {
+ maIn >> nFloat;
+ nFloatArray[ nFloatCount ] = nFloat;
+ SAFEDEC_OR_RET(nRef, 8, ConvErrCount);
+ nFloatCount++;
+ }
+
+ if( nFmla[ i ] == 0x1a )
+ {
+ maIn >> nArg >> nDummy >> nDLLId;
+ nArgArray[ nArgCount ] = nArg;
+ nDLLArray[ nDLLCount ] = nDLLId;
+ SAFEDEC_OR_RET(nRef, 5, ConvErrCount);
+ nDLLCount++;
+ nArgCount++;
+ }
+ if( nFmla[ i ] == 0x06 )
+ {
+ String aTmp( ScfTools::ReadCString( maIn ), maIn.GetStreamCharSet() );
+ sStringArray[ nStringCount ] = aTmp;
+ nStringCount++;
+ SAFEDEC_OR_RET(nRef, aTmp.Len() + 1, ConvErrCount);
+ }
+ }
+ }
+ else
+ return ConvErrCount;
+
+ i = 0, nIntCount = 0, nFloatCount = 0, nDLLCount = 0, nArgCount = 0, nStringCount =0;
+
+ while( i < nRef && ( nFmla[ i ] != 0x03 ) )
+ {
+ eType = IndexToType( nFmla[ i ] );
+ eOc = IndexToToken( nFmla[ i ] );
+ if( eOc == ocNoName )
+ pExtString = getString( nFmla[ i ] );
+
+ switch( eType )
+ {
+ case FT_NotImpl:
+ DoFunc( ocNoName, 0, pExtString );
+ break;
+
+ case FT_FuncFix0:
+ DoFunc( eOc, 0, NULL );
+ break;
+
+ case FT_FuncFix1:
+ DoFunc( eOc, 1, NULL );
+ break;
+
+ case FT_FuncFix2:
+ DoFunc( eOc, 2, NULL );
+ break;
+
+ case FT_FuncFix3:
+ DoFunc( eOc, 3, NULL );
+ break;
+
+ case FT_FuncFix4:
+ DoFunc( eOc, 4, NULL );
+ break;
+
+ case FT_FuncFix5:
+ DoFunc( eOc, 5, NULL );
+ break;
+
+ case FT_FuncFix6:
+ DoFunc( eOc, 6, NULL );
+ break;
+
+ case FT_DLL:{
+ eOc = IndexToDLLId( nDLLArray[ nDLLCount ] );
+ sal_uInt8 nPar = nArgArray[ nArgCount ];
+ DoFunc( eOc, nPar, NULL );
+ nDLLCount++;
+ nArgCount++;
+ }
+ break;
+
+ case FT_Cref : // Single cell reference
+ maIn >> nNote >> nCol >> nPage >> nRelBits;
+ ReadSRD( aSRD, nPage, nCol, nRelBits );
+ aStack << aPool.Store( aSRD );
+ break;
+
+ case FT_Range: // Block reference
+ maIn >> nNote >> nCol >> nPage >> nRelBits;
+ ReadSRD( aCRD.Ref1, nPage, nCol, nRelBits );
+ maIn >> nCol >> nPage >> nRelBits;
+ ReadSRD( aCRD.Ref2, nPage, nCol, nRelBits );
+ // Sheet name of second corner is not displayed if identical
+ if (aCRD.Ref1.IsFlag3D() && aCRD.Ref1.nTab == aCRD.Ref2.nTab &&
+ aCRD.Ref1.IsTabRel() == aCRD.Ref2.IsTabRel())
+ aCRD.Ref2.SetFlag3D( false);
+ aStack << aPool.Store( aCRD );
+ break;
+
+ case FT_FuncVar:{ // Sum of a sequence of numbers
+ sal_uInt8 nArgs;
+ i++;
+ nArgs = nFmla[ i ];
+ DoFunc( eOc, nArgs, NULL );
+ }
+ break;
+
+ case FT_Op: // operators
+ aStack >> nPush;
+ aPool << aStack << eOc << nPush;
+ aPool >> aStack;
+ break;
+
+ case FT_Braces:
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+
+ case FT_ConstInt:{
+ sal_uInt16 nVal;
+ nVal = nIntArray[ nIntCount ];
+ aStack << aPool.Store( ( double ) nVal );
+ nIntCount++;
+ }
+ break;
+
+ case FT_ConstFloat:{
+ double nVal;
+ nVal = nFloatArray[ nFloatCount ];
+ aStack << aPool.Store( nVal );
+ nFloatCount++;
+ }
+ break;
+
+ case FT_ConstString:{
+ String aLabel;
+ aLabel = sStringArray[ nStringCount ];
+ aStack << aPool.Store( aLabel );
+ nStringCount++;
+ }
+ break;
+
+ case FT_Neg:
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+
+ case FT_NOP: // indicates invalid opcode.
+ case FT_Return: // indicates end of formula
+ break;
+ }
+ i++;
+ }
+ pArray = aPool[ aStack.Get() ];
+ return ConvOK;
+}
+
+static const struct
+{
+ DefTokenId nToken;
+ FUNC_TYPE nType;
+} aFuncMap[] = {
+ { ocPush, FT_ConstFloat },
+ { ocPush, FT_Cref },
+ { ocPush, FT_Range },
+ { ocPush, FT_Return },
+ { ocPush, FT_Braces },
+ { ocPush, FT_ConstInt },
+ { ocPush, FT_ConstString },
+ { ocPush, FT_NOP },
+ { ocNegSub, FT_Neg }, // 0x08
+ { ocAdd, FT_Op },
+ { ocSub, FT_Op },
+ { ocMul, FT_Op },
+ { ocDiv, FT_Op },
+ { ocPow, FT_Op },
+ { ocEqual, FT_Op },
+ { ocNotEqual, FT_Op },
+ { ocLessEqual, FT_Op }, // 0x10
+ { ocGreaterEqual, FT_Op },
+ { ocLess, FT_Op },
+ { ocGreater, FT_Op },
+ { ocAnd, FT_Op },
+ { ocOr, FT_Op },
+ { ocNot, FT_FuncFix1 },
+ { ocPush, FT_NOP }, // Unary plus
+ { ocAddress, FT_FuncFix4 }, // Address of
+ { ocNoName, FT_NotImpl }, // Halt function
+ { ocNoName, FT_DLL }, // DLL function
+ { ocNoName, FT_NOP }, // Extended operands
+ { ocNoName, FT_NOP }, // Extended operands
+ { ocNoName, FT_NOP }, // Reserved
+ { ocNoName, FT_NOP }, // Reserved
+ { ocNotAvail, FT_FuncFix0 }, // NA
+ { ocNoName, FT_FuncFix0 }, // Error // 0x20
+ { ocAbs, FT_FuncFix1 },
+ { ocInt, FT_FuncFix1 },
+ { ocSqrt, FT_FuncFix1 },
+ { ocLog10, FT_FuncFix1 },
+ { ocLn, FT_FuncFix1 },
+ { ocPi, FT_FuncFix0 },
+ { ocSin, FT_FuncFix1 },
+ { ocCos, FT_FuncFix1 },
+ { ocTan, FT_FuncFix1 },
+ { ocArcTan2, FT_FuncFix2 },
+ { ocArcTan, FT_FuncFix1 },
+ { ocArcSin, FT_FuncFix1 },
+ { ocArcCos, FT_FuncFix1 },
+ { ocExp, FT_FuncFix1 },
+ { ocMod, FT_FuncFix2 },
+ { ocChose, FT_FuncVar }, // 0x30
+ { ocIsNA, FT_FuncFix1 },
+ { ocIsError, FT_FuncFix1 },
+ { ocFalse, FT_FuncFix0 },
+ { ocTrue, FT_FuncFix0 },
+ { ocRandom, FT_FuncFix0 },
+ { ocGetDate, FT_FuncFix3 },
+ { ocGetActTime, FT_FuncFix0 },
+ { ocNoName, FT_NotImpl }, // QPro Pmt
+ { ocNoName, FT_NotImpl }, // QPro Pv
+ { ocNoName, FT_NotImpl }, // QPro Fv
+ { ocIf, FT_FuncFix3 },
+ { ocGetDay, FT_FuncFix1 },
+ { ocGetMonth, FT_FuncFix1 },
+ { ocGetYear, FT_FuncFix1 },
+ { ocRound, FT_FuncFix2 },
+ { ocGetTime, FT_FuncFix3 }, // 0x40
+ { ocGetHour, FT_FuncFix1 },
+ { ocGetMin, FT_FuncFix1 },
+ { ocGetSec, FT_FuncFix1 },
+ { ocIsValue, FT_FuncFix1 },
+ { ocIsString, FT_FuncFix1 },
+ { ocLen, FT_FuncFix1 },
+ { ocValue, FT_FuncFix1 },
+ { ocFixed, FT_FuncFix2 },
+ { ocMid, FT_FuncFix3 },
+ { ocChar, FT_FuncFix1 },
+ { ocCode, FT_FuncFix1 },
+ { ocFind, FT_FuncFix3 },
+ { ocGetDateValue, FT_FuncFix1 },
+ { ocGetTimeValue, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocSum, FT_FuncVar }, // 0x50
+ { ocAverage, FT_FuncVar },
+ { ocCount, FT_FuncVar },
+ { ocMin, FT_FuncVar },
+ { ocMax, FT_FuncVar },
+ { ocVLookup, FT_FuncFix3 },
+ { ocNPV, FT_FuncFix2 },
+ { ocVar, FT_FuncVar },
+ { ocNormDist, FT_FuncVar },
+ { ocIRR, FT_FuncFix2 },
+ { ocHLookup, FT_FuncFix3 },
+ { ocDBSum, FT_FuncFix3 },
+ { ocDBAverage, FT_FuncFix3 },
+ { ocDBCount, FT_FuncFix3 },
+ { ocDBMin, FT_FuncFix3 },
+ { ocDBMax, FT_FuncFix3 },
+ { ocDBVar, FT_FuncFix3 }, // 0x60
+ { ocDBStdDev, FT_FuncFix3 },
+ { ocNoName, FT_NotImpl },
+ { ocColumns, FT_FuncFix1 },
+ { ocRows, FT_FuncFix1 },
+ { ocRept, FT_FuncFix2 },
+ { ocUpper, FT_FuncFix1 },
+ { ocLower, FT_FuncFix1 },
+ { ocLeft, FT_FuncFix2 },
+ { ocRight, FT_FuncFix2 },
+ { ocReplace, FT_FuncFix4 },
+ { ocPropper, FT_FuncFix1 },
+ { ocCell, FT_FuncFix2 },
+ { ocTrim, FT_FuncFix1 },
+ { ocClean, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl }, // 0x70
+ { ocExact, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl }, // Call()
+ { ocIndirect, FT_FuncFix1 },
+ { ocZGZ, FT_FuncFix3 }, // Interest
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocLIA, FT_FuncFix3 },
+ { ocDIA, FT_FuncFix4 },
+ { ocGDA, FT_FuncFix4 },
+ { ocStDevP, FT_FuncVar },
+ { ocVarP, FT_FuncVar },
+ { ocDBStdDevP, FT_FuncVar },
+ { ocDBVarP, FT_FuncVar },
+ { ocBW, FT_FuncFix3 }, // QPro Pval
+ { ocRMZ, FT_FuncFix5 }, // QPro Paymt
+ { ocZW, FT_FuncFix3 }, // QPro Fval // 0x80
+ { ocZZR, FT_FuncFix5 },
+ { ocZins, FT_FuncFix5 },
+ { ocZinsZ, FT_FuncFix4 },
+ { ocKapz, FT_FuncFix6 },
+ { ocSumProduct, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocDeg, FT_FuncFix1 },
+ { ocRad, FT_FuncFix1 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl },
+ { ocGetActDate, FT_FuncFix0 },
+ { ocNPV, FT_FuncFix2 },
+ { ocNoName, FT_NotImpl }, // 0x90
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NOP },
+ { ocNoName, FT_NOP }, // 147
+ { ocNoName, FT_NOP }, // 148
+ { ocNoName, FT_NOP }, // 149
+ { ocNoName, FT_NOP }, // 150
+ { ocNoName, FT_NOP }, // 151
+ { ocNoName, FT_NOP }, // 152
+ { ocNoName, FT_NOP }, // 153
+ { ocTable, FT_FuncFix1 },
+ { ocNoName, FT_NOP }, // 155 - opcodes do not represent any function.
+ { ocNoName, FT_NOP }, // 156
+ { ocIndex, FT_FuncFix4 },
+ { ocNoName, FT_NotImpl },
+ { ocNoName, FT_NotImpl }, // Gives the property of the particular object
+ { ocNoName, FT_NotImpl }, // Dynamic Data Exchange Link // 0x100
+ { ocNoName, FT_NotImpl } // gives properties of DOS menus
+};
+
+const int nIndexCount = SAL_N_ELEMENTS(aFuncMap);
+
+DefTokenId QProToSc::IndexToToken( sal_uInt16 nIndex )
+{
+ if( nIndex < nIndexCount )
+ return aFuncMap[ nIndex ].nToken;
+ return ocNoName;
+}
+
+FUNC_TYPE QProToSc::IndexToType( sal_uInt8 nIndex )
+{
+ if( nIndex < nIndexCount )
+ return aFuncMap[ nIndex ].nType;
+ return FT_NotImpl;
+}
+
+DefTokenId QProToSc::IndexToDLLId( sal_uInt16 nIndex )
+{
+ DefTokenId eId;
+ switch( nIndex )
+ {
+ case 0x0001:
+ eId = ocAveDev;
+ break;
+
+ case 0x0024:
+ eId = ocGCD;
+ break;
+
+ case 0x0025:
+ eId = ocLCM;
+ break;
+
+ case 0x0027:
+ eId = ocCeil;
+ break;
+
+ case 0x0028:
+ eId = ocEven;
+ break;
+
+ case 0x0022:
+ eId = ocFact;
+ break;
+
+ case 0x002a:
+ eId = ocFloor;
+ break;
+
+ case 0x002d:
+ eId = ocOdd;
+ break;
+
+ case 0x0006:
+ eId = ocBetaDist;
+ break;
+
+ case 0x0008:
+ eId = ocBetaInv;
+ break;
+
+ case 0x0010:
+ eId = ocCovar;
+ break;
+
+ case 0x000b:
+ eId = ocChiInv;
+ break;
+
+ case 0x003d:
+ eId = ocLaufz;
+ break;
+
+ case 0x0019:
+ eId = ocFInv;
+ break;
+
+ case 0x001a:
+ eId = ocFisher;
+ break;
+
+ case 0x001b:
+ eId = ocFisherInv;
+ break;
+
+ case 0x0030:
+ eId = ocMedian;
+ break;
+
+ default:
+ eId = ocNoName;
+ break;
+ }
+ return eId;
+}
+
+const sal_Char* QProToSc::getString( sal_uInt8 nIndex )
+{
+ const sal_Char* pExtString = 0;
+ switch( nIndex )
+ {
+ case 57:
+ pExtString = "Pv";
+ break;
+
+ case 58:
+ pExtString = "Fv";
+ break;
+
+ case 98:
+ pExtString = "Index2D";
+ break;
+
+ case 111:
+ pExtString = "S";
+ break;
+
+ case 112:
+ pExtString = "N";
+ break;
+
+ case 114:
+ pExtString = "CALL";
+ break;
+
+ case 117:
+ pExtString = "TERM";
+ break;
+
+ case 118:
+ pExtString = "CTERM";
+ break;
+
+ case 134:
+ pExtString = "MEMAVAIL";
+ break;
+
+ case 135:
+ pExtString = "MEMEMSAVAIL";
+ break;
+
+ case 136:
+ pExtString = "FILEEXISTS";
+ break;
+
+ case 137:
+ pExtString = "CURVALUE";
+ break;
+
+ case 140:
+ pExtString = "HEX";
+ break;
+
+ case 141:
+ pExtString = "NUM";
+ break;
+
+ case 145:
+ pExtString = "VERSION";
+ break;
+
+ case 157:
+ pExtString = "INDEX3D";
+ break;
+
+ case 158:
+ pExtString = "CELLINDEX3D";
+ break;
+
+ case 159:
+ pExtString = "PROPERTY";
+ break;
+
+ case 160:
+ pExtString = "DDE";
+ break;
+
+ case 161:
+ pExtString = "COMMAND";
+ break;
+
+ default:
+ pExtString = NULL;
+ break;
+ }
+ return pExtString;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/qpro/qprostyle.cxx b/sc/source/filter/qpro/qprostyle.cxx
new file mode 100644
index 000000000000..364fabdb436c
--- /dev/null
+++ b/sc/source/filter/qpro/qprostyle.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <sal/config.h>
+#include <stdio.h>
+#include <sfx2/docfile.hxx>
+
+#include "qproform.hxx"
+#include "qpro.hxx"
+#include "qprostyle.hxx"
+
+#include <tools/color.hxx>
+#include <scitems.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <map>
+
+#include "global.hxx"
+#include "scerrors.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+
+ScQProStyle::ScQProStyle()
+{
+ rtl_fillMemory (maAlign, sizeof (maAlign), 0);
+ rtl_fillMemory (maFont, sizeof (maFont), 0);
+ rtl_fillMemory (maFontRecord, sizeof (maFontRecord), 0);
+ rtl_fillMemory (maFontHeight, sizeof (maFontHeight), 0);
+}
+
+void ScQProStyle::SetFormat( ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle )
+{
+ if (nStyle >= maxsize)
+ return;
+
+ ScPatternAttr aPattern(pDoc->GetPool());
+ SfxItemSet& rItemSet = aPattern.GetItemSet();
+
+ sal_uInt8 nTmp = maAlign[ nStyle ];
+ sal_uInt8 nHor = ( nTmp & 0x07 );
+ sal_uInt8 nVer = ( nTmp & 0x18 );
+ sal_uInt8 nOrient = ( nTmp & 0x60 );
+
+ // Horizontal Alignment
+ SvxCellHorJustify eJustify = SVX_HOR_JUSTIFY_STANDARD;
+ switch( nHor )
+ {
+ case 0x00:
+ eJustify = SVX_HOR_JUSTIFY_STANDARD;
+ break;
+
+ case 0x01:
+ eJustify = SVX_HOR_JUSTIFY_LEFT;
+ break;
+
+ case 0x02:
+ eJustify = SVX_HOR_JUSTIFY_CENTER;
+ break;
+
+ case 0x03:
+ eJustify = SVX_HOR_JUSTIFY_RIGHT;
+ break;
+
+ case 0x04:
+ eJustify = SVX_HOR_JUSTIFY_BLOCK;
+ break;
+ }
+ rItemSet.Put( SvxHorJustifyItem( eJustify, ATTR_HOR_JUSTIFY ) );
+
+ // Vertical Alignment
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+ switch( nVer )
+ {
+ case 0x00:
+ eVerJustify = SVX_VER_JUSTIFY_BOTTOM;
+ break;
+
+ case 0x08:
+ eVerJustify = SVX_VER_JUSTIFY_CENTER;
+ break;
+
+ case 0x10:
+ eVerJustify = SVX_VER_JUSTIFY_TOP;
+ break;
+ }
+
+ rItemSet.Put(SvxVerJustifyItem( eVerJustify, ATTR_VER_JUSTIFY ) );
+
+ // Orientation
+ SvxCellOrientation eOrient = SVX_ORIENTATION_STANDARD;
+ switch( nOrient )
+ {
+ case 0x20:
+ eOrient = SVX_ORIENTATION_TOPBOTTOM;
+ break;
+
+ }
+ rItemSet.Put( SvxOrientationItem( eOrient, 0) );
+
+ // Wrap cell contents
+ if( nTmp & 0x80 )
+ {
+ SfxBoolItem aWrapItem( ATTR_LINEBREAK );
+ aWrapItem.SetValue( sal_True );
+ rItemSet.Put( aWrapItem );
+ }
+
+ // Font Attributes
+ sal_uInt16 nTmpFnt = maFontRecord[ maFont[ nStyle ] ];
+ sal_Bool bIsBold, bIsItalic, bIsUnderLine;
+
+ bIsBold = ( nTmpFnt & 0x0001 ) != 0;
+ bIsItalic = ( nTmpFnt & 0x0002 ) != 0;
+ bIsUnderLine = ( nTmpFnt & 0x0004 ) != 0;
+ //(nTmpFnt & 0x0020 ) for StrikeThrough
+
+ if( bIsBold )
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
+ if( bIsItalic )
+ rItemSet.Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if( bIsUnderLine )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+
+ if (maFontHeight[ maFont [ nStyle ] ])
+ rItemSet.Put( SvxFontHeightItem( (sal_uLong) (20 * maFontHeight[ maFont[ nStyle ] ] ), 100, ATTR_FONT_HEIGHT ) );
+
+ String fntName = maFontType[ maFont[ nStyle ] ];
+ rItemSet.Put( SvxFontItem( FAMILY_SYSTEM, fntName, EMPTY_STRING, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+
+ pDoc->ApplyPattern( nCol, nRow, nTab, aPattern );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx
new file mode 100644
index 000000000000..ec01c82efce1
--- /dev/null
+++ b/sc/source/filter/rtf/eeimpars.cxx
@@ -0,0 +1,645 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/adjitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/sfxhtml.hxx>
+#include <svtools/parhtml.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/charclass.hxx>
+
+#include "eeimport.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+#include "stlsheet.hxx"
+#include "docpool.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "eeparser.hxx"
+#include "drwlayer.hxx"
+#include "rangenam.hxx"
+#include "progress.hxx"
+#include "stringutil.hxx"
+
+#include "globstr.hrc"
+
+// in fuins1.cxx
+extern void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage );
+
+//------------------------------------------------------------------------
+
+ScEEImport::ScEEImport( ScDocument* pDocP, const ScRange& rRange ) :
+ maRange( rRange ),
+ mpDoc( pDocP ),
+ mpParser( NULL ),
+ mpRowHeights( new Table )
+{
+ const ScPatternAttr* pPattern = mpDoc->GetPattern(
+ maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
+ mpEngine = new ScTabEditEngine( *pPattern, mpDoc->GetEditPool() );
+ mpEngine->SetUpdateMode( false );
+ mpEngine->EnableUndo( false );
+}
+
+
+ScEEImport::~ScEEImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete mpEngine; // nach Parser!
+ delete mpRowHeights;
+}
+
+
+sal_uLong ScEEImport::Read( SvStream& rStream, const String& rBaseURL )
+{
+ sal_uLong nErr = mpParser->Read( rStream, rBaseURL );
+
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ mpParser->GetDimensions( nEndCol, nEndRow );
+ if ( nEndCol != 0 )
+ {
+ nEndCol += maRange.aStart.Col() - 1;
+ if ( nEndCol > MAXCOL )
+ nEndCol = MAXCOL;
+ }
+ else
+ nEndCol = maRange.aStart.Col();
+ if ( nEndRow != 0 )
+ {
+ nEndRow += maRange.aStart.Row() - 1;
+ if ( nEndRow > MAXROW )
+ nEndRow = MAXROW;
+ }
+ else
+ nEndRow = maRange.aStart.Row();
+ maRange.aEnd.Set( nEndCol, nEndRow, maRange.aStart.Tab() );
+
+ return nErr;
+}
+
+
+void ScEEImport::WriteToDocument( sal_Bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
+{
+ ScProgress* pProgress = new ScProgress( mpDoc->GetDocumentShell(),
+ ScGlobal::GetRscString( STR_LOAD_DOC ), mpParser->ListSize() );
+ sal_uLong nProgress = 0;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nTab;
+ SCROW nOverlapRowMax, nLastMergedRow;
+ SCCOL nMergeColAdd;
+ nStartCol = maRange.aStart.Col();
+ nStartRow = maRange.aStart.Row();
+ nTab = maRange.aStart.Tab();
+ nEndCol = maRange.aEnd.Col();
+ nEndRow = maRange.aEnd.Row();
+ nOverlapRowMax = 0;
+ nMergeColAdd = 0;
+ nLastMergedRow = SCROW_MAX;
+ sal_Bool bHasGraphics = false;
+ ScEEParseEntry* pE;
+ if (!pFormatter)
+ pFormatter = mpDoc->GetFormatTable();
+ bool bNumbersEnglishUS = false;
+ if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM)
+ {
+ // Automatic language option selected. Check for the global 'use US English' option.
+ SvxHtmlOptions aOpt;
+ bNumbersEnglishUS = aOpt.IsNumbersEnglishUS();
+ }
+ ScDocumentPool* pDocPool = mpDoc->GetPool();
+ ScRangeName* pRangeNames = mpDoc->GetRangeName();
+ for ( size_t i = 0, nListSize = mpParser->ListSize(); i < nListSize; ++i )
+ {
+ pE = mpParser->ListEntry( i );
+ SCROW nRow = nStartRow + pE->nRow;
+ if ( nRow != nLastMergedRow )
+ nMergeColAdd = 0;
+ SCCOL nCol = nStartCol + pE->nCol + nMergeColAdd;
+ // RowMerge feststellen, pures ColMerge und ColMerge der ersten
+ // MergeRow bereits beim parsen
+ if ( nRow <= nOverlapRowMax )
+ {
+ while ( nCol <= MAXCOL && mpDoc->HasAttrib( nCol, nRow, nTab,
+ nCol, nRow, nTab, HASATTR_OVERLAPPED ) )
+ {
+ nCol++;
+ nMergeColAdd++;
+ }
+ nLastMergedRow = nRow;
+ }
+ // fuer zweiten Durchlauf eintragen
+ pE->nCol = nCol;
+ pE->nRow = nRow;
+ if ( ValidCol(nCol) && ValidRow(nRow) )
+ {
+ SfxItemSet aSet = mpEngine->GetAttribs( pE->aSel );
+ // Default raus, wir setzen selber links/rechts je nachdem ob Text
+ // oder Zahl; EditView.GetAttribs liefert immer kompletten Set
+ // mit Defaults aufgefuellt
+ const SfxPoolItem& rItem = aSet.Get( EE_PARA_JUST );
+ if ( ((const SvxAdjustItem&)rItem).GetAdjust() == SVX_ADJUST_LEFT )
+ aSet.ClearItem( EE_PARA_JUST );
+
+ // Testen, ob einfacher String ohne gemischte Attribute
+ sal_Bool bSimple = ( pE->aSel.nStartPara == pE->aSel.nEndPara );
+ for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && bSimple; nId++)
+ {
+ const SfxPoolItem* pItem = 0;
+ SfxItemState eState = aSet.GetItemState( nId, sal_True, &pItem );
+ if (eState == SFX_ITEM_DONTCARE)
+ bSimple = false;
+ else if (eState == SFX_ITEM_SET)
+ {
+ if ( nId == EE_CHAR_ESCAPEMENT ) // Hoch-/Tiefstellen immer ueber EE
+ {
+ if ( (SvxEscapement)((const SvxEscapementItem*)pItem)->GetEnumValue()
+ != SVX_ESCAPEMENT_OFF )
+ bSimple = false;
+ }
+ }
+ }
+ if ( bSimple )
+ { // Feldbefehle enthalten?
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, false );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bSimple = false;
+ }
+
+ // HTML
+ String aValStr, aNumStr;
+ double fVal;
+ sal_uInt32 nNumForm = 0;
+ LanguageType eNumLang = LANGUAGE_NONE;
+ if ( pE->pNumStr )
+ { // SDNUM muss sein wenn SDVAL
+ aNumStr = *pE->pNumStr;
+ if ( pE->pValStr )
+ aValStr = *pE->pValStr;
+ fVal = SfxHTMLParser::GetTableDataOptionsValNum(
+ nNumForm, eNumLang, aValStr, aNumStr, *pFormatter );
+ }
+
+ // Attribute setzen
+ ScPatternAttr aAttr( pDocPool );
+ aAttr.GetFromEditItemSet( &aSet );
+ SfxItemSet& rSet = aAttr.GetItemSet();
+ if ( aNumStr.Len() )
+ {
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumForm ) );
+ rSet.Put( SvxLanguageItem( eNumLang, ATTR_LANGUAGE_FORMAT ) );
+ }
+ const SfxItemSet& rESet = pE->aItemSet;
+ if ( rESet.Count() )
+ {
+ const SfxPoolItem* pItem;
+ if ( rESet.GetItemState( ATTR_BACKGROUND, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_BORDER, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_SHADOW, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ // HTML
+ if ( rESet.GetItemState( ATTR_HOR_JUSTIFY, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_VER_JUSTIFY, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_LINEBREAK, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_FONT_COLOR, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ if ( rESet.GetItemState( ATTR_FONT_UNDERLINE, false, &pItem) == SFX_ITEM_SET )
+ rSet.Put( *pItem );
+ // HTML LATIN/CJK/CTL script type dependent
+ const SfxPoolItem* pFont;
+ if ( rESet.GetItemState( ATTR_FONT, false, &pFont) != SFX_ITEM_SET )
+ pFont = 0;
+ const SfxPoolItem* pHeight;
+ if ( rESet.GetItemState( ATTR_FONT_HEIGHT, false, &pHeight) != SFX_ITEM_SET )
+ pHeight = 0;
+ const SfxPoolItem* pWeight;
+ if ( rESet.GetItemState( ATTR_FONT_WEIGHT, false, &pWeight) != SFX_ITEM_SET )
+ pWeight = 0;
+ const SfxPoolItem* pPosture;
+ if ( rESet.GetItemState( ATTR_FONT_POSTURE, false, &pPosture) != SFX_ITEM_SET )
+ pPosture = 0;
+ if ( pFont || pHeight || pWeight || pPosture )
+ {
+ String aStr( mpEngine->GetText( pE->aSel ) );
+ sal_uInt8 nScriptType = mpDoc->GetStringScriptType( aStr );
+ const sal_uInt8 nScripts[3] = { SCRIPTTYPE_LATIN,
+ SCRIPTTYPE_ASIAN, SCRIPTTYPE_COMPLEX };
+ for ( sal_uInt8 j=0; j<3; ++j )
+ {
+ if ( nScriptType & nScripts[j] )
+ {
+ if ( pFont )
+ rSet.Put( *pFont, ScGlobal::GetScriptedWhichID(
+ nScripts[j], ATTR_FONT ));
+ if ( pHeight )
+ rSet.Put( *pHeight, ScGlobal::GetScriptedWhichID(
+ nScripts[j], ATTR_FONT_HEIGHT ));
+ if ( pWeight )
+ rSet.Put( *pWeight, ScGlobal::GetScriptedWhichID(
+ nScripts[j], ATTR_FONT_WEIGHT ));
+ if ( pPosture )
+ rSet.Put( *pPosture, ScGlobal::GetScriptedWhichID(
+ nScripts[j], ATTR_FONT_POSTURE ));
+ }
+ }
+ }
+ }
+ if ( pE->nColOverlap > 1 || pE->nRowOverlap > 1 )
+ { // merged cells, mit SfxItemSet Put schneller als mit
+ // nachtraeglichem ScDocument DoMerge
+ ScMergeAttr aMerge( pE->nColOverlap, pE->nRowOverlap );
+ rSet.Put( aMerge );
+ SCROW nRO = 0;
+ if ( pE->nColOverlap > 1 )
+ mpDoc->ApplyFlagsTab( nCol+1, nRow,
+ nCol + pE->nColOverlap - 1, nRow, nTab,
+ SC_MF_HOR );
+ if ( pE->nRowOverlap > 1 )
+ {
+ nRO = nRow + pE->nRowOverlap - 1;
+ mpDoc->ApplyFlagsTab( nCol, nRow+1,
+ nCol, nRO , nTab,
+ SC_MF_VER );
+ if ( nRO > nOverlapRowMax )
+ nOverlapRowMax = nRO;
+ }
+ if ( pE->nColOverlap > 1 && pE->nRowOverlap > 1 )
+ mpDoc->ApplyFlagsTab( nCol+1, nRow+1,
+ nCol + pE->nColOverlap - 1, nRO, nTab,
+ SC_MF_HOR | SC_MF_VER );
+ }
+ const ScStyleSheet* pStyleSheet =
+ mpDoc->GetPattern( nCol, nRow, nTab )->GetStyleSheet();
+ aAttr.SetStyleSheet( (ScStyleSheet*)pStyleSheet );
+ mpDoc->SetPattern( nCol, nRow, nTab, aAttr, sal_True );
+
+ // Daten eintragen
+ if (bSimple)
+ {
+ ScSetStringParam aParam;
+ aParam.mpNumFormatter = pFormatter;
+ aParam.mbDetectNumberFormat = true;
+ aParam.mbSetTextCellFormat = true;
+
+ if ( aValStr.Len() )
+ mpDoc->SetValue( nCol, nRow, nTab, fVal );
+ else if ( !pE->aSel.HasRange() )
+ {
+ // maybe ALT text of IMG or similar
+ mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, &aParam );
+ // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen!
+ }
+ else
+ {
+ String aStr;
+ if( pE->bEntirePara )
+ {
+ aStr = mpEngine->GetText( pE->aSel.nStartPara );
+ }
+ else
+ {
+ aStr = mpEngine->GetText( pE->aSel );
+ aStr.EraseLeadingAndTrailingChars();
+ }
+
+ // TODO: RTF import should follow the language tag,
+ // currently this follows the HTML options for both, HTML
+ // and RTF.
+ bool bEnUsRecognized = false;
+ if (bNumbersEnglishUS)
+ {
+ pFormatter->ChangeIntl( LANGUAGE_ENGLISH_US);
+ sal_uInt32 nIndex = pFormatter->GetStandardIndex( LANGUAGE_ENGLISH_US);
+ double fEnVal = 0.0;
+ if (pFormatter->IsNumberFormat( aStr, nIndex, fEnVal))
+ {
+ bEnUsRecognized = true;
+ sal_uInt32 nNewIndex =
+ pFormatter->GetFormatForLanguageIfBuiltIn(
+ nIndex, LANGUAGE_SYSTEM);
+ DBG_ASSERT( nNewIndex != nIndex, "ScEEImport::WriteToDocument: NumbersEnglishUS not a built-in format?");
+ pFormatter->GetInputLineString( fEnVal, nNewIndex, aStr);
+ }
+ pFormatter->ChangeIntl( LANGUAGE_SYSTEM);
+ }
+
+ // #105460#, #i4180# String cells can't contain tabs or linebreaks
+ // -> replace with spaces
+ aStr.SearchAndReplaceAll( (sal_Unicode)'\t', (sal_Unicode)' ' );
+ aStr.SearchAndReplaceAll( (sal_Unicode)'\n', (sal_Unicode)' ' );
+
+ if (bNumbersEnglishUS && !bEnUsRecognized)
+ mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr));
+ else
+ {
+ aParam.mbDetectNumberFormat = bConvertDate;
+ mpDoc->SetString( nCol, nRow, nTab, aStr, &aParam );
+ }
+ }
+ }
+ else
+ {
+ EditTextObject* pObject = mpEngine->CreateTextObject( pE->aSel );
+ mpDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pObject,
+ mpDoc, mpEngine->GetEditTextObjectPool() ) );
+ delete pObject;
+ }
+ if ( pE->maImageList.size() )
+ bHasGraphics |= GraphicSize( nCol, nRow, nTab, pE );
+ if ( pE->pName )
+ { // Anchor Name => RangeName
+ if (!pRangeNames->findByName(*pE->pName))
+ {
+ ScRangeData* pData = new ScRangeData( mpDoc, *pE->pName,
+ ScAddress( nCol, nRow, nTab ) );
+ pRangeNames->insert( pData );
+ }
+ }
+ }
+ pProgress->SetStateOnPercent( ++nProgress );
+ }
+ if ( bSizeColsRows )
+ {
+ // Spaltenbreiten
+ Table* pColWidths = mpParser->GetColWidths();
+ if ( pColWidths->Count() )
+ {
+ nProgress = 0;
+ pProgress->SetState( nProgress, nEndCol - nStartCol + 1 );
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; nCol++ )
+ {
+ sal_uInt16 nWidth = (sal_uInt16)(sal_uLong) pColWidths->Get( nCol );
+ if ( nWidth )
+ mpDoc->SetColWidth( nCol, nTab, nWidth );
+ pProgress->SetState( ++nProgress );
+ }
+ }
+ DELETEZ( pProgress ); // SetOptimalHeight hat seinen eigenen ProgressBar
+ // Zeilenhoehen anpassen, Basis 100% Zoom
+ Fraction aZoom( 1, 1 );
+ double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
+ / nOutputFactor; // Faktor ist Drucker zu Bildschirm
+ double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
+ VirtualDevice aVirtDev;
+ mpDoc->SetOptimalHeight( 0, nEndRow, 0,
+ static_cast< sal_uInt16 >( ScGlobal::nLastRowHeightExtra ), &aVirtDev,
+ nPPTX, nPPTY, aZoom, aZoom, false );
+ if ( mpRowHeights->Count() )
+ {
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow++ )
+ {
+ sal_uInt16 nHeight = (sal_uInt16)(sal_uLong) mpRowHeights->Get( nRow );
+ if ( nHeight > mpDoc->GetRowHeight( nRow, nTab ) )
+ mpDoc->SetRowHeight( nRow, nTab, nHeight );
+ }
+ }
+ }
+ if ( bHasGraphics )
+ {
+ // Grafiken einfuegen
+ for ( size_t i = 0, nListSize = mpParser->ListSize(); i < nListSize; ++i )
+ {
+ pE = mpParser->ListEntry( i );
+ if ( !pE->maImageList.empty() )
+ {
+ SCCOL nCol = pE->nCol;
+ SCROW nRow = pE->nRow;
+ if ( ValidCol(nCol) && ValidRow(nRow) )
+ InsertGraphic( nCol, nRow, nTab, pE );
+ }
+ }
+ }
+ if ( pProgress )
+ delete pProgress;
+}
+
+
+sal_Bool ScEEImport::GraphicSize( SCCOL nCol, SCROW nRow, SCTAB /*nTab*/, ScEEParseEntry* pE )
+{
+ if ( !pE->maImageList.size() )
+ return false;
+ sal_Bool bHasGraphics = false;
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ long nWidth, nHeight;
+ nWidth = nHeight = 0;
+ sal_Char nDir = nHorizontal;
+ for ( sal_uInt32 i = 0; i < pE->maImageList.size() ; ++i )
+ {
+ ScHTMLImage* pI = &pE->maImageList[ i ];
+ if ( pI->pGraphic )
+ bHasGraphics = sal_True;
+ Size aSizePix = pI->aSize;
+ aSizePix.Width() += 2 * pI->aSpace.X();
+ aSizePix.Height() += 2 * pI->aSpace.Y();
+ Size aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_TWIP ) );
+ if ( nDir & nHorizontal )
+ nWidth += aLogicSize.Width();
+ else if ( nWidth < aLogicSize.Width() )
+ nWidth = aLogicSize.Width();
+ if ( nDir & nVertical )
+ nHeight += aLogicSize.Height();
+ else if ( nHeight < aLogicSize.Height() )
+ nHeight = aLogicSize.Height();
+ nDir = pI->nDir;
+ }
+ // Spaltenbreiten
+ Table* pColWidths = mpParser->GetColWidths();
+ long nThisWidth = (long) pColWidths->Get( nCol );
+ long nColWidths = nThisWidth;
+ SCCOL nColSpanCol = nCol + pE->nColOverlap;
+ for ( SCCOL nC = nCol + 1; nC < nColSpanCol; nC++ )
+ {
+ nColWidths += (long) pColWidths->Get( nC );
+ }
+ if ( nWidth > nColWidths )
+ { // Differenz nur in der ersten Spalte eintragen
+ if ( nThisWidth )
+ pColWidths->Replace( nCol, (void*)(nWidth - nColWidths + nThisWidth) );
+ else
+ pColWidths->Insert( nCol, (void*)(nWidth - nColWidths) );
+ }
+ // Zeilenhoehen, Differenz auf alle betroffenen Zeilen verteilen
+ SCROW nRowSpan = pE->nRowOverlap;
+ nHeight /= nRowSpan;
+ if ( nHeight == 0 )
+ nHeight = 1; // fuer eindeutigen Vergleich
+ for ( SCROW nR = nRow; nR < nRow + nRowSpan; nR++ )
+ {
+ long nRowHeight = (long) mpRowHeights->Get( nR );
+ if ( nHeight > nRowHeight )
+ {
+ if ( nRowHeight )
+ mpRowHeights->Replace( nR, (void*)nHeight );
+ else
+ mpRowHeights->Insert( nR, (void*)nHeight );
+ }
+ }
+ return bHasGraphics;
+}
+
+
+void ScEEImport::InsertGraphic( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ ScEEParseEntry* pE )
+{
+ if ( !pE->maImageList.size() )
+ return ;
+ ScDrawLayer* pModel = mpDoc->GetDrawLayer();
+ if (!pModel)
+ {
+ mpDoc->InitDrawLayer();
+ pModel = mpDoc->GetDrawLayer();
+ }
+ SdrPage* pPage = pModel->GetPage( static_cast<sal_uInt16>(nTab) );
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+
+ Point aCellInsertPos(
+ (long)((double) mpDoc->GetColOffset( nCol, nTab ) * HMM_PER_TWIPS),
+ (long)((double) mpDoc->GetRowOffset( nRow, nTab ) * HMM_PER_TWIPS) );
+
+ Point aInsertPos( aCellInsertPos );
+ Point aSpace;
+ Size aLogicSize;
+ sal_Char nDir = nHorizontal;
+ for ( sal_uInt32 i = 0; i < pE->maImageList.size(); ++i )
+ {
+ ScHTMLImage* pI = &pE->maImageList[ i ];
+ if ( nDir & nHorizontal )
+ { // horizontal
+ aInsertPos.X() += aLogicSize.Width();
+ aInsertPos.X() += aSpace.X();
+ aInsertPos.Y() = aCellInsertPos.Y();
+ }
+ else
+ { // vertikal
+ aInsertPos.X() = aCellInsertPos.X();
+ aInsertPos.Y() += aLogicSize.Height();
+ aInsertPos.Y() += aSpace.Y();
+ }
+ // Offset des Spacings drauf
+ aSpace = pDefaultDev->PixelToLogic( pI->aSpace, MapMode( MAP_100TH_MM ) );
+ aInsertPos += aSpace;
+
+ Size aSizePix = pI->aSize;
+ aLogicSize = pDefaultDev->PixelToLogic( aSizePix, MapMode( MAP_100TH_MM ) );
+ // Groesse begrenzen
+ ::ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
+
+ if ( pI->pGraphic )
+ {
+ Rectangle aRect ( aInsertPos, aLogicSize );
+ SdrGrafObj* pObj = new SdrGrafObj( *pI->pGraphic, aRect );
+ // calling SetGraphicLink here doesn't work
+ pObj->SetName( pI->aURL );
+
+ pPage->InsertObject( pObj );
+
+ // SetGraphicLink has to be used after inserting the object,
+ // otherwise an empty graphic is swapped in and the contact stuff crashes.
+ // See #i37444#.
+ pObj->SetGraphicLink( pI->aURL, pI->aFilterName );
+
+ pObj->SetLogicRect( aRect ); // erst nach InsertObject !!!
+ }
+ nDir = pI->nDir;
+ }
+}
+
+
+ScEEParser::ScEEParser( EditEngine* pEditP ) :
+ pEdit( pEditP ),
+ pPool( EditEngine::CreatePool() ),
+ pDocPool( new ScDocumentPool ),
+ pColWidths( new Table ),
+ nLastToken(0),
+ nColCnt(0),
+ nRowCnt(0),
+ nColMax(0),
+ nRowMax(0)
+{
+ // pPool wird spaeter bei RTFIMP_START dem SvxRTFParser untergejubelt
+ pPool->SetSecondaryPool( pDocPool );
+ pPool->FreezeIdRanges();
+ NewActEntry( NULL );
+}
+
+
+ScEEParser::~ScEEParser()
+{
+ delete pActEntry;
+ delete pColWidths;
+ if ( !maList.empty() ) maList.clear();
+
+ // Pool erst loeschen nachdem die Listen geloescht wurden
+ pPool->SetSecondaryPool( NULL );
+ SfxItemPool::Free(pDocPool);
+ SfxItemPool::Free(pPool);
+}
+
+
+void ScEEParser::NewActEntry( ScEEParseEntry* pE )
+{ // neuer freifliegender pActEntry
+ pActEntry = new ScEEParseEntry( pPool );
+ pActEntry->aSel.nStartPara = (pE ? pE->aSel.nEndPara + 1 : 0);
+ pActEntry->aSel.nStartPos = 0;
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/rtf/expbase.cxx b/sc/source/filter/rtf/expbase.cxx
new file mode 100644
index 000000000000..ee90ff1b4ec7
--- /dev/null
+++ b/sc/source/filter/rtf/expbase.cxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "expbase.hxx"
+#include "document.hxx"
+#include "editutil.hxx"
+
+
+//------------------------------------------------------------------
+
+#if defined(UNX)
+const sal_Char ScExportBase::sNewLine = '\012';
+#else
+const sal_Char ScExportBase::sNewLine[] = "\015\012";
+#endif
+
+
+ScExportBase::ScExportBase( SvStream& rStrmP, ScDocument* pDocP,
+ const ScRange& rRangeP )
+ :
+ rStrm( rStrmP ),
+ aRange( rRangeP ),
+ pDoc( pDocP ),
+ pFormatter( pDocP->GetFormatTable() ),
+ pEditEngine( NULL )
+{
+}
+
+
+ScExportBase::~ScExportBase()
+{
+ delete pEditEngine;
+}
+
+
+sal_Bool ScExportBase::GetDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const
+{
+ pDoc->GetDataStart( nTab, nStartCol, nStartRow );
+ pDoc->GetPrintArea( nTab, nEndCol, nEndRow, sal_True );
+ return TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+
+sal_Bool ScExportBase::TrimDataArea( SCTAB nTab, SCCOL& nStartCol,
+ SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const
+{
+ while ( nStartCol <= nEndCol && pDoc->ColHidden(nStartCol, nTab))
+ ++nStartCol;
+ while ( nStartCol <= nEndCol && pDoc->ColHidden(nEndCol, nTab))
+ --nEndCol;
+ nStartRow = pDoc->FirstVisibleRow(nStartRow, nEndRow, nTab);
+ nEndRow = pDoc->LastVisibleRow(nStartRow, nEndRow, nTab);
+ return nStartCol <= nEndCol && nStartRow <= nEndRow && nEndRow !=
+ ::std::numeric_limits<SCROW>::max();
+}
+
+
+sal_Bool ScExportBase::IsEmptyTable( SCTAB nTab ) const
+{
+ if ( !pDoc->HasTable( nTab ) || !pDoc->IsVisible( nTab ) )
+ return sal_True;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ return !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+}
+
+
+ScFieldEditEngine& ScExportBase::GetEditEngine() const
+{
+ if ( !pEditEngine )
+ ((ScExportBase*)this)->pEditEngine = new ScFieldEditEngine( pDoc->GetEditPool() );
+ return *pEditEngine;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/rtf/rtfexp.cxx b/sc/source/filter/rtf/rtfexp.cxx
new file mode 100644
index 000000000000..8a81b6c97660
--- /dev/null
+++ b/sc/source/filter/rtf/rtfexp.cxx
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svx/algitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/style.hxx>
+#include <svtools/rtfout.hxx>
+#include <svtools/rtfkeywd.hxx>
+
+#include "rtfexp.hxx"
+#include "filter.hxx"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "attrib.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "editutil.hxx"
+#include "stlpool.hxx"
+#include "ftools.hxx"
+
+//------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScExportRTF( SvStream& rStrm, ScDocument* pDoc,
+ const ScRange& rRange, const CharSet /*eNach*/ )
+{
+ ScRTFExport aEx( rStrm, pDoc, rRange );
+ return aEx.Write();
+}
+
+
+ScRTFExport::ScRTFExport( SvStream& rStrmP, ScDocument* pDocP, const ScRange& rRangeP )
+ :
+ ScExportBase( rStrmP, pDocP, rRangeP ),
+ pCellX( new sal_uLong[ MAXCOL+2 ] )
+{
+}
+
+
+ScRTFExport::~ScRTFExport()
+{
+ delete [] pCellX;
+}
+
+
+sal_uLong ScRTFExport::Write()
+{
+ rStrm << '{' << OOO_STRING_SVTOOLS_RTF_RTF;
+ rStrm << OOO_STRING_SVTOOLS_RTF_ANSI << sNewLine;
+
+ // Daten
+ for ( SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); nTab++ )
+ {
+ if ( nTab > aRange.aStart.Tab() )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PAR;
+ WriteTab( nTab );
+ }
+
+ rStrm << '}' << sNewLine;
+ return rStrm.GetError();
+}
+
+
+void ScRTFExport::WriteTab( SCTAB nTab )
+{
+ rStrm << '{' << sNewLine;
+ if ( pDoc->HasTable( nTab ) )
+ {
+ memset( &pCellX[0], 0, (MAXCOL+2) * sizeof(sal_uLong) );
+ SCCOL nCol;
+ SCCOL nEndCol = aRange.aEnd.Col();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ pCellX[nCol+1] = pCellX[nCol] + pDoc->GetColWidth( nCol, nTab );
+ }
+
+ SCROW nEndRow = aRange.aEnd.Row();
+ for ( SCROW nRow = aRange.aStart.Row(); nRow <= nEndRow; nRow++ )
+ {
+ WriteRow( nTab, nRow );
+ }
+ }
+ rStrm << '}' << sNewLine;
+}
+
+
+void ScRTFExport::WriteRow( SCTAB nTab, SCROW nRow )
+{
+ rStrm << OOO_STRING_SVTOOLS_RTF_TROWD << OOO_STRING_SVTOOLS_RTF_TRGAPH << "30" << OOO_STRING_SVTOOLS_RTF_TRLEFT << "-30";
+ rStrm << OOO_STRING_SVTOOLS_RTF_TRRH << ByteString::CreateFromInt32( pDoc->GetRowHeight( nRow, nTab ) ).GetBuffer();
+ SCCOL nCol;
+ SCCOL nEndCol = aRange.aEnd.Col();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+ const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE );
+ const SvxVerJustifyItem& rVerJustifyItem= (const SvxVerJustifyItem&)pAttr->GetItem( ATTR_VER_JUSTIFY );
+
+ const sal_Char* pChar;
+
+ if ( rMergeAttr.GetColMerge() != 0 )
+ rStrm << OOO_STRING_SVTOOLS_RTF_CLMGF;
+ else
+ {
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG );
+ if ( rMergeFlagAttr.IsHorOverlapped() )
+ rStrm << OOO_STRING_SVTOOLS_RTF_CLMRG;
+ }
+
+ switch( rVerJustifyItem.GetValue() )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
+ case SVX_VER_JUSTIFY_STANDARD: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break; //! Bottom
+ default: pChar = NULL; break;
+ }
+ if ( pChar )
+ rStrm << pChar;
+
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELLX << ByteString::CreateFromInt32( pCellX[nCol+1] ).GetBuffer();
+ if ( (nCol & 0x0F) == 0x0F )
+ rStrm << sNewLine; // Zeilen nicht zu lang werden lassen
+ }
+ rStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << OOO_STRING_SVTOOLS_RTF_INTBL << sNewLine;
+
+ sal_uLong nStrmPos = rStrm.Tell();
+ for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
+ {
+ WriteCell( nTab, nRow, nCol );
+ if ( rStrm.Tell() - nStrmPos > 255 )
+ { // Zeilen nicht zu lang werden lassen
+ rStrm << sNewLine;
+ nStrmPos = rStrm.Tell();
+ }
+ }
+ rStrm << OOO_STRING_SVTOOLS_RTF_ROW << sNewLine;
+}
+
+
+void ScRTFExport::WriteCell( SCTAB nTab, SCROW nRow, SCCOL nCol )
+{
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG );
+ if ( rMergeFlagAttr.IsHorOverlapped() )
+ {
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+ return ;
+ }
+
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ sal_Bool bValueData;
+ String aContent;
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_NOTE :
+ bValueData = false;
+ break; // nix
+ case CELLTYPE_EDIT :
+ {
+ bValueData = false;
+ EditEngine& rEngine = GetEditEngine();
+ const EditTextObject* pObj;
+ ((const ScEditCell*)pCell)->GetData( pObj );
+ if ( pObj )
+ {
+ rEngine.SetText( *pObj );
+ aContent = rEngine.GetText( LINEEND_LF ); // LineFeed zwischen Absaetzen!
+ }
+ }
+ break;
+ default:
+ {
+ bValueData = pCell->HasValueData();
+ sal_uLong nFormat = pAttr->GetNumberFormat( pFormatter );
+ Color* pColor;
+ ScCellFormat::GetString( pCell, nFormat, aContent, &pColor, *pFormatter );
+ }
+ }
+ }
+ else
+ bValueData = false;
+
+ sal_Bool bResetPar, bResetAttr;
+ bResetPar = bResetAttr = false;
+
+ const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)pAttr->GetItem( ATTR_HOR_JUSTIFY );
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem( ATTR_FONT_WEIGHT );
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&) pAttr->GetItem( ATTR_FONT_POSTURE );
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&) pAttr->GetItem( ATTR_FONT_UNDERLINE );
+
+ const sal_Char* pChar;
+
+ switch( rHorJustifyItem.GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ pChar = (bValueData ? OOO_STRING_SVTOOLS_RTF_QR : OOO_STRING_SVTOOLS_RTF_QL);
+ break;
+ case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
+ case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_RTF_QJ; break;
+ case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default: pChar = OOO_STRING_SVTOOLS_RTF_QL; break;
+ }
+ rStrm << pChar;
+
+ if ( rWeightItem.GetWeight() >= WEIGHT_BOLD )
+ { // bold
+ bResetAttr = sal_True;
+ rStrm << OOO_STRING_SVTOOLS_RTF_B;
+ }
+ if ( rPostureItem.GetPosture() != ITALIC_NONE )
+ { // italic
+ bResetAttr = sal_True;
+ rStrm << OOO_STRING_SVTOOLS_RTF_I;
+ }
+ if ( rUnderlineItem.GetLineStyle() != UNDERLINE_NONE )
+ { // underline
+ bResetAttr = sal_True;
+ rStrm << OOO_STRING_SVTOOLS_RTF_UL;
+ }
+
+ rStrm << ' ';
+ RTFOutFuncs::Out_String( rStrm, aContent );
+ rStrm << OOO_STRING_SVTOOLS_RTF_CELL;
+
+ if ( bResetPar )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
+ if ( bResetAttr )
+ rStrm << OOO_STRING_SVTOOLS_RTF_PLAIN;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/rtf/rtfimp.cxx b/sc/source/filter/rtf/rtfimp.cxx
new file mode 100644
index 000000000000..acf14f5620cc
--- /dev/null
+++ b/sc/source/filter/rtf/rtfimp.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#ifndef PCH
+#include "global.hxx"
+#include "document.hxx"
+#include "filter.hxx"
+#endif
+#include "editutil.hxx"
+#include "rtfimp.hxx"
+#include "rtfparse.hxx"
+#include "ftools.hxx"
+
+
+FltError ScFormatFilterPluginImpl::ScImportRTF( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc, ScRange& rRange )
+{
+ ScRTFImport aImp( pDoc, rRange );
+ FltError nErr = (FltError) aImp.Read( rStream, rBaseURL );
+ ScRange aR = aImp.GetRange();
+ rRange.aEnd = aR.aEnd;
+ aImp.WriteToDocument();
+ return nErr;
+}
+
+ScEEAbsImport *ScFormatFilterPluginImpl::CreateRTFImport( ScDocument* pDoc, const ScRange& rRange )
+{
+ return new ScRTFImport( pDoc, rRange );
+}
+
+
+ScRTFImport::ScRTFImport( ScDocument* pDocP, const ScRange& rRange ) :
+ ScEEImport( pDocP, rRange )
+{
+ mpParser = new ScRTFParser( mpEngine );
+}
+
+
+ScRTFImport::~ScRTFImport()
+{
+ // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
+ // Ist gewaehrleistet, da ScEEImport Basisklasse ist
+ delete (ScRTFParser*) mpParser; // vor EditEngine!
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/rtf/rtfparse.cxx b/sc/source/filter/rtf/rtfparse.cxx
new file mode 100644
index 000000000000..69c78c0b8ec0
--- /dev/null
+++ b/sc/source/filter/rtf/rtfparse.cxx
@@ -0,0 +1,434 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/editeng.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/svxrtf.hxx>
+#include <vcl/outdev.hxx>
+#include <svtools/rtftoken.h>
+
+#define SC_RTFPARSE_CXX
+#include "rtfparse.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+
+#define SC_RTFTWIPTOL 10 // 10 Twips Toleranz bei Spaltenbestimmung
+
+
+
+SV_IMPL_VARARR_SORT( ScRTFColTwips, sal_uLong );
+
+
+
+ScRTFParser::ScRTFParser( EditEngine* pEditP ) :
+ ScEEParser( pEditP ),
+ pDefaultList( new ScRTFDefaultList ),
+ pColTwips( new ScRTFColTwips ),
+ pActDefault( NULL ),
+ pDefMerge( NULL ),
+ nStartAdjust( (sal_uLong)~0 ),
+ nLastWidth(0),
+ bNewDef( false )
+{
+ // RTF default FontSize 12Pt
+ long nMM = OutputDevice::LogicToLogic( 12, MAP_POINT, MAP_100TH_MM );
+ pPool->SetPoolDefaultItem( SvxFontHeightItem( nMM, 100, EE_CHAR_FONTHEIGHT ) );
+ // freifliegender pInsDefault
+ pInsDefault = new ScRTFCellDefault( pPool );
+}
+
+
+ScRTFParser::~ScRTFParser()
+{
+ delete pInsDefault;
+ delete pColTwips;
+ pDefaultList->clear();
+ delete pDefaultList;
+}
+
+
+sal_uLong ScRTFParser::Read( SvStream& rStream, const String& rBaseURL )
+{
+ Link aOldLink = pEdit->GetImportHdl();
+ pEdit->SetImportHdl( LINK( this, ScRTFParser, RTFImportHdl ) );
+ sal_uLong nErr = pEdit->Read( rStream, rBaseURL, EE_FORMAT_RTF );
+ if ( nLastToken == RTF_PAR )
+ {
+ if ( !maList.empty() )
+ {
+ ScEEParseEntry* pE = maList.back();
+ if ( // komplett leer
+ ( ( pE->aSel.nStartPara == pE->aSel.nEndPara
+ && pE->aSel.nStartPos == pE->aSel.nEndPos
+ )
+ || // leerer Paragraph
+ ( pE->aSel.nStartPara + 1 == pE->aSel.nEndPara
+ && pE->aSel.nStartPos == pEdit->GetTextLen( pE->aSel.nStartPara )
+ && pE->aSel.nEndPos == 0
+ )
+ )
+ )
+ { // den letzten leeren Absatz nicht uebernehmen
+ maList.pop_back();
+ }
+ }
+ }
+ ColAdjust();
+ pEdit->SetImportHdl( aOldLink );
+ return nErr;
+}
+
+
+void ScRTFParser::EntryEnd( ScEEParseEntry* pE, const ESelection& aSel )
+{
+ // Paragraph -2 stript den angehaengten leeren Paragraph
+ pE->aSel.nEndPara = aSel.nEndPara - 2;
+ // obwohl das nEndPos heisst, ist das letzte Position + 1
+ pE->aSel.nEndPos = pEdit->GetTextLen( aSel.nEndPara - 1 );
+}
+
+
+inline void ScRTFParser::NextRow()
+{
+ if ( nRowMax < ++nRowCnt )
+ nRowMax = nRowCnt;
+}
+
+
+sal_Bool ScRTFParser::SeekTwips( sal_uInt16 nTwips, SCCOL* pCol )
+{
+ sal_uInt16 nPos;
+ sal_Bool bFound = pColTwips->Seek_Entry( nTwips, &nPos );
+ *pCol = static_cast<SCCOL>(nPos);
+ if ( bFound )
+ return sal_True;
+ sal_uInt16 nCount = pColTwips->Count();
+ if ( !nCount )
+ return false;
+ SCCOL nCol = *pCol;
+ // nCol ist Einfuegeposition, da liegt der Naechsthoehere (oder auch nicht)
+ if ( nCol < static_cast<SCCOL>(nCount) && (((*pColTwips)[nCol] - SC_RTFTWIPTOL) <= nTwips) )
+ return sal_True;
+ // nicht kleiner als alles andere? dann mit Naechstniedrigerem vergleichen
+ else if ( nCol != 0 && (((*pColTwips)[nCol-1] + SC_RTFTWIPTOL) >= nTwips) )
+ {
+ (*pCol)--;
+ return sal_True;
+ }
+ return false;
+}
+
+
+void ScRTFParser::ColAdjust()
+{
+ if ( nStartAdjust != (sal_uLong)~0 )
+ {
+ SCCOL nCol = 0;
+ ScEEParseEntry* pE;
+ for ( size_t i = nStartAdjust, nListSize = maList.size(); i < nListSize; ++ i )
+ {
+ pE = maList[ i ];
+ if ( pE->nCol == 0 )
+ nCol = 0;
+ pE->nCol = nCol;
+ if ( pE->nColOverlap > 1 )
+ nCol = nCol + pE->nColOverlap; // merged cells mit \clmrg
+ else
+ {
+ SeekTwips( pE->nTwips, &nCol );
+ if ( ++nCol <= pE->nCol )
+ nCol = pE->nCol + 1; // verschobene Zell-X
+ pE->nColOverlap = nCol - pE->nCol; // merged cells ohne \clmrg
+ }
+ if ( nCol > nColMax )
+ nColMax = nCol;
+ }
+ nStartAdjust = (sal_uLong)~0;
+ pColTwips->Remove( (sal_uInt16)0, pColTwips->Count() );
+ }
+}
+
+
+IMPL_LINK( ScRTFParser, RTFImportHdl, ImportInfo*, pInfo )
+{
+ switch ( pInfo->eState )
+ {
+ case RTFIMP_NEXTTOKEN:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_UNKNOWNATTR:
+ ProcToken( pInfo );
+ break;
+ case RTFIMP_START:
+ {
+ SvxRTFParser* pParser = (SvxRTFParser*) pInfo->pParser;
+ pParser->SetAttrPool( pPool );
+ RTFPardAttrMapIds& rMap = pParser->GetPardMap();
+ rMap.nBrush = ATTR_BACKGROUND;
+ rMap.nBox = ATTR_BORDER;
+ rMap.nShadow = ATTR_SHADOW;
+ }
+ break;
+ case RTFIMP_END:
+ if ( pInfo->aSelection.nEndPos )
+ { // falls noch Text: letzten Absatz erzeugen
+ pActDefault = NULL;
+ pInfo->nToken = RTF_PAR;
+ // EditEngine hat keinen leeren Paragraph mehr angehaengt
+ // den EntryEnd strippen koennte
+ pInfo->aSelection.nEndPara++;
+ ProcToken( pInfo );
+ }
+ break;
+ case RTFIMP_SETATTR:
+ break;
+ case RTFIMP_INSERTTEXT:
+ break;
+ case RTFIMP_INSERTPARA:
+ break;
+ default:
+ DBG_ERRORFILE("unknown ImportInfo.eState");
+ }
+ return 0;
+}
+
+
+// bei RTF_INTBL bzw. am Anfang von erstem RTF_CELL nach RTF_CELLX wenn es
+// kein RTF_INTBL gab, bad behavior
+void ScRTFParser::NewCellRow( ImportInfo* /*pInfo*/ )
+{
+ if ( bNewDef )
+ {
+ ScRTFCellDefault* pD;
+ bNewDef = false;
+ // rechts nicht buendig? => neue Tabelle
+ if ( nLastWidth
+ && ( (pD = &(pDefaultList->back())) != 0 )
+ && pD->nTwips != nLastWidth
+ )
+ {
+ SCCOL n1, n2;
+ if ( !( SeekTwips( nLastWidth, &n1 )
+ && SeekTwips( pD->nTwips, &n2 ) && n1 == n2) )
+ ColAdjust();
+ }
+ // TwipCols aufbauen, erst nach nLastWidth Vergleich!
+ for ( size_t i = 0, nListSize = pDefaultList->size(); i < nListSize; ++i )
+ {
+ pD = &( pDefaultList->at( i ) );
+ SCCOL n;
+ if ( !SeekTwips( pD->nTwips, &n ) )
+ pColTwips->Insert( pD->nTwips );
+ }
+ }
+ pDefMerge = NULL;
+ pActDefault = &(pDefaultList->front());
+ DBG_ASSERT( pActDefault, "NewCellRow: pActDefault==0" );
+}
+
+
+/*
+ SW:
+ ~~~
+ [\par]
+ \trowd \cellx \cellx ...
+ \intbl \cell \cell ...
+ \row
+ [\par]
+ [\trowd \cellx \cellx ...]
+ \intbl \cell \cell ...
+ \row
+ [\par]
+
+ M$-Word:
+ ~~~~~~~~
+ [\par]
+ \trowd \cellx \cellx ...
+ \intbl \cell \cell ...
+ \intbl \row
+ [\par]
+ [\trowd \cellx \cellx ...]
+ \intbl \cell \cell ...
+ \intbl \row
+ [\par]
+
+ */
+
+void ScRTFParser::ProcToken( ImportInfo* pInfo )
+{
+ ScRTFCellDefault* pD;
+ ScEEParseEntry* pE;
+ switch ( pInfo->nToken )
+ {
+ case RTF_TROWD: // denotes table row defauls, before RTF_CELLX
+ {
+ if ( !pDefaultList->empty() && (pD = &(pDefaultList->back())) != 0 )
+ nLastWidth = pD->nTwips;
+ nColCnt = 0;
+ pDefaultList->clear();
+ pDefMerge = NULL;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMGF: // The first cell of cells to be merged
+ {
+ pDefMerge = pInsDefault;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CLMRG: // A cell to be merged with the preceding cell
+ {
+ if ( !pDefMerge
+ && !(pDefaultList->empty())
+ )
+ pDefMerge = &( pDefaultList->back() );
+ DBG_ASSERT( pDefMerge, "RTF_CLMRG: pDefMerge==0" );
+ if ( pDefMerge ) // sonst rottes RTF
+ pDefMerge->nColOverlap++; // mehrere nacheinander moeglich
+ pInsDefault->nColOverlap = 0; // Flag: ignoriere diese
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_CELLX: // closes cell default
+ {
+ bNewDef = sal_True;
+ pInsDefault->nCol = nColCnt;
+ pInsDefault->nTwips = pInfo->nTokenValue; // rechter Zellenrand
+ pDefaultList->push_back( pInsDefault );
+ // neuer freifliegender pInsDefault
+ pInsDefault = new ScRTFCellDefault( pPool );
+ if ( ++nColCnt > nColMax )
+ nColMax = nColCnt;
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_INTBL: // before the first RTF_CELL
+ {
+ // einmal ueber NextToken und einmal ueber UnknownAttrToken
+ // oder z.B. \intbl ... \cell \pard \intbl ... \cell
+ if ( nLastToken != RTF_INTBL && nLastToken != RTF_CELL && nLastToken != RTF_PAR )
+ {
+ NewCellRow( pInfo );
+ nLastToken = pInfo->nToken;
+ }
+ }
+ break;
+ case RTF_CELL: // denotes the end of a cell.
+ {
+ DBG_ASSERT( pActDefault, "RTF_CELL: pActDefault==0" );
+ if ( bNewDef || !pActDefault )
+ NewCellRow( pInfo ); // davor war kein \intbl, bad behavior
+ // rottes RTF? retten was zu retten ist
+ if ( !pActDefault )
+ pActDefault = pInsDefault;
+ if ( pActDefault->nColOverlap > 0 )
+ { // nicht merged mit vorheriger
+ pActEntry->nCol = pActDefault->nCol;
+ pActEntry->nColOverlap = pActDefault->nColOverlap;
+ pActEntry->nTwips = pActDefault->nTwips;
+ pActEntry->nRow = nRowCnt;
+ pActEntry->aItemSet.Set( pActDefault->aItemSet );
+ EntryEnd( pActEntry, pInfo->aSelection );
+
+ if ( nStartAdjust == (sal_uLong)~0 )
+ nStartAdjust = maList.size();
+ maList.push_back( pActEntry );
+ NewActEntry( pActEntry ); // neuer freifliegender pActEntry
+ }
+ else
+ { // aktuelle Twips der MergeCell zuweisen
+ if ( !maList.empty() )
+ {
+ pE = maList.back();
+ pE->nTwips = pActDefault->nTwips;
+ }
+ // Selection des freifliegenden pActEntry anpassen
+ // Paragraph -1 wg. Textaufbruch in EditEngine waehrend Parse
+ pActEntry->aSel.nStartPara = pInfo->aSelection.nEndPara - 1;
+ }
+ if ( pDefaultList->empty() )
+ pActDefault = NULL;
+ else
+ pActDefault = &( pDefaultList->back() );
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_ROW: // means the end of a row
+ {
+ NextRow();
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ case RTF_PAR: // Paragraph
+ {
+ if ( !pActDefault )
+ { // text not in table
+ ColAdjust(); // close the processing table
+ pActEntry->nCol = 0;
+ pActEntry->nRow = nRowCnt;
+ EntryEnd( pActEntry, pInfo->aSelection );
+ maList.push_back( pActEntry );
+ NewActEntry( pActEntry ); // new pActEntry
+ NextRow();
+ }
+ nLastToken = pInfo->nToken;
+ }
+ break;
+ default:
+ { // do not set nLastToken
+ switch ( pInfo->nToken & ~(0xff | RTF_TABLEDEF) )
+ {
+ case RTF_SHADINGDEF:
+ ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(
+ pInfo->nToken, pInsDefault->aItemSet, sal_True );
+ break;
+ case RTF_BRDRDEF:
+ ((SvxRTFParser*)pInfo->pParser)->ReadBorderAttr(
+ pInfo->nToken, pInsDefault->aItemSet, sal_True );
+ break;
+ }
+ }
+ }
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx
new file mode 100644
index 000000000000..0a349a36697c
--- /dev/null
+++ b/sc/source/filter/starcalc/scflt.cxx
@@ -0,0 +1,2406 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "global.hxx"
+#include "sc.hrc"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "document.hxx"
+#include "collect.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "filter.hxx"
+#include "scflt.hxx"
+#include "cell.hxx"
+#include "scfobj.hxx"
+#include "docoptio.hxx"
+#include "viewopti.hxx"
+#include "postit.hxx"
+#include "globstr.hrc"
+#include "ftools.hxx"
+#include "tabprotection.hxx"
+
+#include "fprogressbar.hxx"
+
+using namespace com::sun::star;
+
+#define DEFCHARSET RTL_TEXTENCODING_MS_1252
+
+#define SC10TOSTRING(p) String(p,DEFCHARSET)
+
+const SCCOL SC10MAXCOL = 255; // #i85906# don't try to load more columns than there are in the file
+
+
+void lcl_ReadFileHeader(SvStream& rStream, Sc10FileHeader& rFileHeader)
+{
+ rStream.Read(&rFileHeader.CopyRight, sizeof(rFileHeader.CopyRight));
+ rStream >> rFileHeader.Version;
+ rStream.Read(&rFileHeader.Reserved, sizeof(rFileHeader.Reserved));
+}
+
+
+void lcl_ReadTabProtect(SvStream& rStream, Sc10TableProtect& rProtect)
+{
+ rStream.Read(&rProtect.PassWord, sizeof(rProtect.PassWord));
+ rStream >> rProtect.Flags;
+ rStream >> rProtect.Protect;
+}
+
+
+void lcl_ReadSheetProtect(SvStream& rStream, Sc10SheetProtect& rProtect)
+{
+ rStream.Read(&rProtect.PassWord, sizeof(rProtect.PassWord));
+ rStream >> rProtect.Flags;
+ rStream >> rProtect.Protect;
+}
+
+
+void lcl_ReadRGB(SvStream& rStream, Sc10Color& rColor)
+{
+ rStream >> rColor.Dummy;
+ rStream >> rColor.Blue;
+ rStream >> rColor.Green;
+ rStream >> rColor.Red;
+}
+
+
+void lcl_ReadPalette(SvStream& rStream, Sc10Color* pPalette)
+{
+ for (sal_uInt16 i = 0; i < 16; i++)
+ lcl_ReadRGB(rStream, pPalette[i]);
+}
+
+
+void lcl_ReadValueFormat(SvStream& rStream, Sc10ValueFormat& rFormat)
+{
+ rStream >> rFormat.Format;
+ rStream >> rFormat.Info;
+}
+
+
+void lcl_ReadLogFont(SvStream& rStream, Sc10LogFont& rFont)
+{
+ rStream >> rFont.lfHeight;
+ rStream >> rFont.lfWidth;
+ rStream >> rFont.lfEscapement;
+ rStream >> rFont.lfOrientation;
+ rStream >> rFont.lfWeight;
+ rStream >> rFont.lfItalic;
+ rStream >> rFont.lfUnderline;
+ rStream >> rFont.lfStrikeOut;
+ rStream >> rFont.lfCharSet;
+ rStream >> rFont.lfOutPrecision;
+ rStream >> rFont.lfClipPrecision;
+ rStream >> rFont.lfQuality;
+ rStream >> rFont.lfPitchAndFamily;
+ rStream.Read(&rFont.lfFaceName, sizeof(rFont.lfFaceName));
+}
+
+
+void lcl_ReadBlockRect(SvStream& rStream, Sc10BlockRect& rBlock)
+{
+ rStream >> rBlock.x1;
+ rStream >> rBlock.y1;
+ rStream >> rBlock.x2;
+ rStream >> rBlock.y2;
+}
+
+
+void lcl_ReadHeadFootLine(SvStream& rStream, Sc10HeadFootLine& rLine)
+{
+ rStream.Read(&rLine.Title, sizeof(rLine.Title));
+ lcl_ReadLogFont(rStream, rLine.LogFont);
+ rStream >> rLine.HorJustify;
+ rStream >> rLine.VerJustify;
+ rStream >> rLine.Raster;
+ rStream >> rLine.Frame;
+ lcl_ReadRGB(rStream, rLine.TextColor);
+ lcl_ReadRGB(rStream, rLine.BackColor);
+ lcl_ReadRGB(rStream, rLine.RasterColor);
+ rStream >> rLine.FrameColor;
+ rStream >> rLine.Reserved;
+}
+
+
+void lcl_ReadPageFormat(SvStream& rStream, Sc10PageFormat& rFormat)
+{
+ lcl_ReadHeadFootLine(rStream, rFormat.HeadLine);
+ lcl_ReadHeadFootLine(rStream, rFormat.FootLine);
+ rStream >> rFormat.Orientation;
+ rStream >> rFormat.Width;
+ rStream >> rFormat.Height;
+ rStream >> rFormat.NonPrintableX;
+ rStream >> rFormat.NonPrintableY;
+ rStream >> rFormat.Left;
+ rStream >> rFormat.Top;
+ rStream >> rFormat.Right;
+ rStream >> rFormat.Bottom;
+ rStream >> rFormat.Head;
+ rStream >> rFormat.Foot;
+ rStream >> rFormat.HorCenter;
+ rStream >> rFormat.VerCenter;
+ rStream >> rFormat.PrintGrid;
+ rStream >> rFormat.PrintColRow;
+ rStream >> rFormat.PrintNote;
+ rStream >> rFormat.TopBottomDir;
+ rStream.Read(&rFormat.PrintAreaName, sizeof(rFormat.PrintAreaName));
+ lcl_ReadBlockRect(rStream, rFormat.PrintArea);
+ rStream.Read(&rFormat.PrnZoom, sizeof(rFormat.PrnZoom));
+ rStream >> rFormat.FirstPageNo;
+ rStream >> rFormat.RowRepeatStart;
+ rStream >> rFormat.RowRepeatEnd;
+ rStream >> rFormat.ColRepeatStart;
+ rStream >> rFormat.ColRepeatEnd;
+ rStream.Read(&rFormat.Reserved, sizeof(rFormat.Reserved));
+}
+
+
+void lcl_ReadGraphHeader(SvStream& rStream, Sc10GraphHeader& rHeader)
+{
+ rStream >> rHeader.Typ;
+ rStream >> rHeader.CarretX;
+ rStream >> rHeader.CarretY;
+ rStream >> rHeader.CarretZ;
+ rStream >> rHeader.x;
+ rStream >> rHeader.y;
+ rStream >> rHeader.w;
+ rStream >> rHeader.h;
+ rStream >> rHeader.IsRelPos;
+ rStream >> rHeader.DoPrint;
+ rStream >> rHeader.FrameType;
+ rStream >> rHeader.IsTransparent;
+ lcl_ReadRGB(rStream, rHeader.FrameColor);
+ lcl_ReadRGB(rStream, rHeader.BackColor);
+ rStream.Read(&rHeader.Reserved, sizeof(rHeader.Reserved));
+}
+
+
+void lcl_ReadImageHeaer(SvStream& rStream, Sc10ImageHeader& rHeader)
+{
+ rStream.Read(&rHeader.FileName, sizeof(rHeader.FileName));
+ rStream >> rHeader.Typ;
+ rStream >> rHeader.Linked;
+ rStream >> rHeader.x1;
+ rStream >> rHeader.y1;
+ rStream >> rHeader.x2;
+ rStream >> rHeader.y2;
+ rStream >> rHeader.Size;
+}
+
+
+void lcl_ReadChartHeader(SvStream& rStream, Sc10ChartHeader& rHeader)
+{
+ rStream >> rHeader.MM;
+ rStream >> rHeader.xExt;
+ rStream >> rHeader.yExt;
+ rStream >> rHeader.Size;
+}
+
+
+void lcl_ReadChartSheetData(SvStream& rStream, Sc10ChartSheetData& rSheetData)
+{
+ rStream >> rSheetData.HasTitle;
+ rStream >> rSheetData.TitleX;
+ rStream >> rSheetData.TitleY;
+ rStream >> rSheetData.HasSubTitle;
+ rStream >> rSheetData.SubTitleX;
+ rStream >> rSheetData.SubTitleY;
+ rStream >> rSheetData.HasLeftTitle;
+ rStream >> rSheetData.LeftTitleX;
+ rStream >> rSheetData.LeftTitleY;
+ rStream >> rSheetData.HasLegend;
+ rStream >> rSheetData.LegendX1;
+ rStream >> rSheetData.LegendY1;
+ rStream >> rSheetData.LegendX2;
+ rStream >> rSheetData.LegendY2;
+ rStream >> rSheetData.HasLabel;
+ rStream >> rSheetData.LabelX1;
+ rStream >> rSheetData.LabelY1;
+ rStream >> rSheetData.LabelX2;
+ rStream >> rSheetData.LabelY2;
+ rStream >> rSheetData.DataX1;
+ rStream >> rSheetData.DataY1;
+ rStream >> rSheetData.DataX2;
+ rStream >> rSheetData.DataY2;
+ rStream.Read(&rSheetData.Reserved, sizeof(rSheetData.Reserved));
+}
+
+
+void lcl_ReadChartTypeData(SvStream& rStream, Sc10ChartTypeData& rTypeData)
+{
+ rStream >> rTypeData.NumSets;
+ rStream >> rTypeData.NumPoints;
+ rStream >> rTypeData.DrawMode;
+ rStream >> rTypeData.GraphType;
+ rStream >> rTypeData.GraphStyle;
+ rStream.Read(&rTypeData.GraphTitle, sizeof(rTypeData.GraphTitle));
+ rStream.Read(&rTypeData.BottomTitle, sizeof(rTypeData.BottomTitle));
+ sal_uInt16 i;
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.SymbolData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.ColorData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.ThickLines[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.PatternData[i];
+ for (i = 0; i < 256; i++)
+ rStream >> rTypeData.LinePatternData[i];
+ for (i = 0; i < 11; i++)
+ rStream >> rTypeData.NumGraphStyles[i];
+ rStream >> rTypeData.ShowLegend;
+ for (i = 0; i < 256; i++)
+ rStream.Read(&rTypeData.LegendText[i], sizeof(Sc10ChartText));
+ rStream >> rTypeData.ExplodePie;
+ rStream >> rTypeData.FontUse;
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontFamily[i];
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontStyle[i];
+ for (i = 0; i < 5; i++)
+ rStream >> rTypeData.FontSize[i];
+ rStream >> rTypeData.GridStyle;
+ rStream >> rTypeData.Labels;
+ rStream >> rTypeData.LabelEvery;
+ for (i = 0; i < 50; i++)
+ rStream.Read(&rTypeData.LabelText[i], sizeof(Sc10ChartText));
+ rStream.Read(&rTypeData.LeftTitle, sizeof(rTypeData.LeftTitle));
+ rStream.Read(&rTypeData.Reserved, sizeof(rTypeData.Reserved));
+}
+
+double lcl_PascalToDouble(sal_Char* tp6)
+{
+ sal_uInt8* pnUnsigned = reinterpret_cast< sal_uInt8* >( tp6 );
+ // biased exponent
+ sal_uInt8 be = pnUnsigned[ 0 ];
+ // lower 16 bits of mantissa
+ sal_uInt16 v1 = static_cast< sal_uInt16 >( pnUnsigned[ 2 ] * 256 + pnUnsigned[ 1 ] );
+ // next 16 bits of mantissa
+ sal_uInt16 v2 = static_cast< sal_uInt16 >( pnUnsigned[ 4 ] * 256 + pnUnsigned[ 3 ] );
+ // upper 7 bits of mantissa
+ sal_uInt8 v3 = static_cast< sal_uInt8 >( pnUnsigned[ 5 ] & 0x7F );
+ // sign bit
+ bool s = (pnUnsigned[ 5 ] & 0x80) != 0;
+
+ if (be == 0)
+ return 0.0;
+ return (((((128 + v3) * 65536.0) + v2) * 65536.0 + v1) *
+ ldexp ((s ? -1.0 : 1.0), be - (129+39)));
+}
+
+
+void lcl_ChangeColor( sal_uInt16 nIndex, Color& rColor )
+{
+ ColorData aCol;
+
+ switch( nIndex )
+ {
+ case 1: aCol = COL_RED; break;
+ case 2: aCol = COL_GREEN; break;
+ case 3: aCol = COL_BROWN; break;
+ case 4: aCol = COL_BLUE; break;
+ case 5: aCol = COL_MAGENTA; break;
+ case 6: aCol = COL_CYAN; break;
+ case 7: aCol = COL_GRAY; break;
+ case 8: aCol = COL_LIGHTGRAY; break;
+ case 9: aCol = COL_LIGHTRED; break;
+ case 10: aCol = COL_LIGHTGREEN; break;
+ case 11: aCol = COL_YELLOW; break;
+ case 12: aCol = COL_LIGHTBLUE; break;
+ case 13: aCol = COL_LIGHTMAGENTA; break;
+ case 14: aCol = COL_LIGHTCYAN; break;
+ case 15: aCol = COL_WHITE; break;
+ default: aCol = COL_BLACK;
+ }
+
+ rColor.SetColor( aCol );
+}
+
+String lcl_MakeOldPageStyleFormatName( sal_uInt16 i )
+{
+ String aName = ScGlobal::GetRscString( STR_PAGESTYLE );
+ aName.AppendAscii( " " );
+ aName += String::CreateFromInt32( i + 1 );
+
+ return aName;
+}
+
+//--------------------------------------------
+// Font
+//--------------------------------------------
+
+Sc10FontData::Sc10FontData(SvStream& rStream)
+{
+ rStream >> Height;
+ rStream >> CharSet;
+ rStream >> PitchAndFamily;
+ sal_uInt16 nLen;
+ rStream >> nLen;
+ if (nLen < sizeof(FaceName))
+ rStream.Read(FaceName, nLen);
+ else
+ rStream.SetError(ERRCODE_IO_WRONGFORMAT);
+}
+
+
+Sc10FontCollection::Sc10FontCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ sal_uInt16 ID;
+ rStream >> ID;
+ if (ID == FontID)
+ {
+ sal_uInt16 nAnz;
+ rStream >> nAnz;
+ for (sal_uInt16 i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10FontData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ OSL_FAIL( "FontID" );
+ nError = errUnknownID;
+ }
+}
+
+//--------------------------------------------
+// Benannte-Bereiche
+//--------------------------------------------
+
+Sc10NameData::Sc10NameData(SvStream& rStream)
+{
+ sal_uInt8 nLen;
+ rStream >> nLen;
+ rStream.Read(Name, sizeof(Name) - 1);
+ if (nLen >= sizeof(Name))
+ nLen = sizeof(Name) - 1;
+ Name[nLen] = 0;
+
+ rStream >> nLen;
+ rStream.Read(Reference, sizeof(Reference) - 1);
+ if (nLen >= sizeof(Reference))
+ nLen = sizeof(Reference) - 1;
+ Reference[nLen] = 0;
+ rStream.Read(Reserved, sizeof(Reserved));
+}
+
+
+Sc10NameCollection::Sc10NameCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ sal_uInt16 ID;
+ rStream >> ID;
+ if (ID == NameID)
+ {
+ sal_uInt16 nAnz;
+ rStream >> nAnz;
+ for (sal_uInt16 i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10NameData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ OSL_FAIL( "NameID" );
+ nError = errUnknownID;
+ }
+}
+
+//--------------------------------------------
+// Vorlagen
+//--------------------------------------------
+
+Sc10PatternData::Sc10PatternData(SvStream& rStream)
+{
+ rStream.Read(Name, sizeof(Name));
+ lcl_ReadValueFormat(rStream, ValueFormat);
+ lcl_ReadLogFont(rStream, LogFont);
+
+ rStream >> Attr;
+ rStream >> Justify;
+ rStream >> Frame;
+ rStream >> Raster;
+ rStream >> nColor;
+ rStream >> FrameColor;
+ rStream >> Flags;
+ rStream >> FormatFlags;
+ rStream.Read(Reserved, sizeof(Reserved));
+}
+
+
+Sc10PatternCollection::Sc10PatternCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ sal_uInt16 ID;
+ rStream >> ID;
+ if (ID == PatternID)
+ {
+ sal_uInt16 nAnz;
+ rStream >> nAnz;
+ for (sal_uInt16 i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10PatternData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ OSL_FAIL( "PatternID" );
+ nError = errUnknownID;
+ }
+}
+
+//--------------------------------------------
+// Datenbank
+//--------------------------------------------
+
+Sc10DataBaseData::Sc10DataBaseData(SvStream& rStream)
+{
+ rStream.Read(&DataBaseRec.Name, sizeof(DataBaseRec.Name));
+ rStream >> DataBaseRec.Tab;
+ lcl_ReadBlockRect(rStream, DataBaseRec.Block);
+ rStream >> DataBaseRec.RowHeader;
+ rStream >> DataBaseRec.SortField0;
+ rStream >> DataBaseRec.SortUpOrder0;
+ rStream >> DataBaseRec.SortField1;
+ rStream >> DataBaseRec.SortUpOrder1;
+ rStream >> DataBaseRec.SortField2;
+ rStream >> DataBaseRec.SortUpOrder2;
+ rStream >> DataBaseRec.IncludeFormat;
+
+ rStream >> DataBaseRec.QueryField0;
+ rStream >> DataBaseRec.QueryOp0;
+ rStream >> DataBaseRec.QueryByString0;
+ rStream.Read(&DataBaseRec.QueryString0, sizeof(DataBaseRec.QueryString0));
+ DataBaseRec.QueryValue0 = ScfTools::ReadLongDouble(rStream);
+
+ rStream >> DataBaseRec.QueryConnect1;
+ rStream >> DataBaseRec.QueryField1;
+ rStream >> DataBaseRec.QueryOp1;
+ rStream >> DataBaseRec.QueryByString1;
+ rStream.Read(&DataBaseRec.QueryString1, sizeof(DataBaseRec.QueryString1));
+ DataBaseRec.QueryValue1 = ScfTools::ReadLongDouble(rStream);
+
+ rStream >> DataBaseRec.QueryConnect2;
+ rStream >> DataBaseRec.QueryField2;
+ rStream >> DataBaseRec.QueryOp2;
+ rStream >> DataBaseRec.QueryByString2;
+ rStream.Read(&DataBaseRec.QueryString2, sizeof(DataBaseRec.QueryString2));
+ DataBaseRec.QueryValue2 = ScfTools::ReadLongDouble(rStream);
+}
+
+
+Sc10DataBaseCollection::Sc10DataBaseCollection(SvStream& rStream) :
+ ScCollection (4, 4),
+ nError (0)
+{
+ sal_uInt16 ID;
+ rStream >> ID;
+ if (ID == DataBaseID)
+ {
+ rStream.Read(ActName, sizeof(ActName));
+ sal_uInt16 nAnz;
+ rStream >> nAnz;
+ for (sal_uInt16 i=0; (i < nAnz) && (nError == 0); i++)
+ {
+ Insert(new Sc10DataBaseData(rStream));
+ nError = rStream.GetError();
+ }
+ }
+ else
+ {
+ OSL_FAIL( "DataBaseID" );
+ nError = errUnknownID;
+ }
+}
+
+
+int Sc10LogFont::operator==( const Sc10LogFont& rData ) const
+{
+ return !strcmp( lfFaceName, rData.lfFaceName )
+ && lfHeight == rData.lfHeight
+ && lfWidth == rData.lfWidth
+ && lfEscapement == rData.lfEscapement
+ && lfOrientation == rData.lfOrientation
+ && lfWeight == rData.lfWeight
+ && lfItalic == rData.lfItalic
+ && lfUnderline == rData.lfUnderline
+ && lfStrikeOut == rData.lfStrikeOut
+ && lfCharSet == rData.lfCharSet
+ && lfOutPrecision == rData.lfOutPrecision
+ && lfClipPrecision == rData.lfClipPrecision
+ && lfQuality == rData.lfQuality
+ && lfPitchAndFamily == rData.lfPitchAndFamily;
+}
+
+
+int Sc10Color::operator==( const Sc10Color& rColor ) const
+{
+ return ((Red == rColor.Red) && (Green == rColor.Green) && (Blue == rColor.Blue));
+}
+
+
+int Sc10HeadFootLine::operator==( const Sc10HeadFootLine& rData ) const
+{
+ return !strcmp(Title, rData.Title)
+ && LogFont == rData.LogFont
+ && HorJustify == rData.HorJustify
+ && VerJustify == rData.VerJustify
+ && Raster == rData.Raster
+ && Frame == rData.Frame
+ && TextColor == rData.TextColor
+ && BackColor == rData.BackColor
+ && RasterColor == rData.RasterColor
+ && FrameColor == rData.FrameColor
+ && Reserved == rData.Reserved;
+}
+
+
+int Sc10PageFormat::operator==( const Sc10PageFormat& rData ) const
+{
+ return !strcmp(PrintAreaName, rData.PrintAreaName)
+ && HeadLine == rData.HeadLine
+ && FootLine == rData.FootLine
+ && Orientation == rData.Orientation
+ && Width == rData.Width
+ && Height == rData.Height
+ && NonPrintableX == rData.NonPrintableX
+ && NonPrintableY == rData.NonPrintableY
+ && Left == rData.Left
+ && Top == rData.Top
+ && Right == rData.Right
+ && Bottom == rData.Bottom
+ && Head == rData.Head
+ && Foot == rData.Foot
+ && HorCenter == rData.HorCenter
+ && VerCenter == rData.VerCenter
+ && PrintGrid == rData.PrintGrid
+ && PrintColRow == rData.PrintColRow
+ && PrintNote == rData.PrintNote
+ && TopBottomDir == rData.TopBottomDir
+ && FirstPageNo == rData.FirstPageNo
+ && RowRepeatStart == rData.RowRepeatStart
+ && RowRepeatEnd == rData.RowRepeatEnd
+ && ColRepeatStart == rData.ColRepeatStart
+ && ColRepeatEnd == rData.ColRepeatEnd
+ && !memcmp( PrnZoom, rData.PrnZoom, sizeof(PrnZoom) )
+ && !memcmp( &PrintArea, &rData.PrintArea, sizeof(PrintArea) );
+}
+
+
+sal_uInt16 Sc10PageCollection::InsertFormat( const Sc10PageFormat& rData )
+{
+ for (sal_uInt16 i=0; i<nCount; i++)
+ if (At(i)->aPageFormat == rData)
+ return i;
+
+ Insert( new Sc10PageData(rData) );
+
+ return nCount-1;
+}
+
+
+static inline sal_uInt8 GetMixedCol( const sal_uInt8 nB, const sal_uInt8 nF, const sal_uInt16 nFak )
+{
+ sal_Int32 nT = nB - nF;
+ nT *= ( sal_Int32 ) nFak;
+ nT /= 0xFFFF;
+ nT += nF;
+ return ( sal_uInt8 ) nT;
+}
+static inline Color GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt16 nFact )
+{
+ return Color( GetMixedCol( rBack.GetRed(), rFore.GetRed(), nFact ),
+ GetMixedCol( rBack.GetGreen(), rFore.GetGreen(), nFact ),
+ GetMixedCol( rBack.GetBlue(), rFore.GetBlue(), nFact ) );
+}
+
+
+void Sc10PageCollection::PutToDoc( ScDocument* pDoc )
+{
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ EditEngine aEditEngine( pDoc->GetEnginePool() );
+ EditTextObject* pEmptyObject = aEditEngine.CreateTextObject();
+
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ Sc10PageFormat* pPage = &At(i)->aPageFormat;
+
+ pPage->Width = (short) ( pPage->Width * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Height = (short) ( pPage->Height * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Top = (short) ( pPage->Top * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Bottom = (short) ( pPage->Bottom * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Left = (short) ( pPage->Left * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Right = (short) ( pPage->Right * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Head = (short) ( pPage->Head * ( 72.0 / 72.27 ) + 0.5 );
+ pPage->Foot = (short) ( pPage->Foot * ( 72.0 / 72.27 ) + 0.5 );
+
+ String aName = lcl_MakeOldPageStyleFormatName( i );
+
+ ScStyleSheet* pSheet = (ScStyleSheet*) &pStylePool->Make( aName,
+ SFX_STYLE_FAMILY_PAGE,
+ SFXSTYLEBIT_USERDEF | SCSTYLEBIT_STANDARD );
+ // #i68483# set page style name at sheet...
+ pDoc->SetPageStyle( static_cast< SCTAB >( i ), aName );
+
+ SfxItemSet* pSet = &pSheet->GetItemSet();
+
+ for (sal_uInt16 nHeadFoot=0; nHeadFoot<2; nHeadFoot++)
+ {
+ Sc10HeadFootLine* pHeadFootLine = nHeadFoot ? &pPage->FootLine : &pPage->HeadLine;
+
+ SfxItemSet aEditAttribs(aEditEngine.GetEmptyItemSet());
+ FontFamily eFam = FAMILY_DONTKNOW;
+ switch (pPage->HeadLine.LogFont.lfPitchAndFamily & 0xF0)
+ {
+ case ffDontCare: eFam = FAMILY_DONTKNOW; break;
+ case ffRoman: eFam = FAMILY_ROMAN; break;
+ case ffSwiss: eFam = FAMILY_SWISS; break;
+ case ffModern: eFam = FAMILY_MODERN; break;
+ case ffScript: eFam = FAMILY_SCRIPT; break;
+ case ffDecorative: eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ aEditAttribs.Put( SvxFontItem(
+ eFam,
+ SC10TOSTRING( pHeadFootLine->LogFont.lfFaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ),
+ EE_CHAR_FONTINFO );
+ aEditAttribs.Put( SvxFontHeightItem( Abs( pHeadFootLine->LogFont.lfHeight ), 100, EE_CHAR_FONTHEIGHT ),
+ EE_CHAR_FONTHEIGHT);
+
+ Sc10Color nColor = pHeadFootLine->TextColor;
+ Color TextColor( nColor.Red, nColor.Green, nColor.Blue );
+ aEditAttribs.Put(SvxColorItem(TextColor, EE_CHAR_COLOR), EE_CHAR_COLOR);
+ // FontAttr
+ if (pHeadFootLine->LogFont.lfWeight != fwNormal)
+ aEditAttribs.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT), EE_CHAR_WEIGHT);
+ if (pHeadFootLine->LogFont.lfItalic != 0)
+ aEditAttribs.Put(SvxPostureItem(ITALIC_NORMAL, EE_CHAR_ITALIC), EE_CHAR_ITALIC);
+ if (pHeadFootLine->LogFont.lfUnderline != 0)
+ aEditAttribs.Put(SvxUnderlineItem(UNDERLINE_SINGLE, EE_CHAR_UNDERLINE), EE_CHAR_UNDERLINE);
+ if (pHeadFootLine->LogFont.lfStrikeOut != 0)
+ aEditAttribs.Put(SvxCrossedOutItem(STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT), EE_CHAR_STRIKEOUT);
+ String aText( pHeadFootLine->Title, DEFCHARSET );
+ aEditEngine.SetText( aText );
+ aEditEngine.QuickSetAttribs( aEditAttribs, ESelection( 0, 0, 0, aText.Len() ) );
+
+ EditTextObject* pObject = aEditEngine.CreateTextObject();
+ ScPageHFItem aHeaderItem(nHeadFoot ? ATTR_PAGE_FOOTERRIGHT : ATTR_PAGE_HEADERRIGHT);
+ switch (pHeadFootLine->HorJustify)
+ {
+ case hjCenter:
+ aHeaderItem.SetLeftArea(*pEmptyObject);
+ aHeaderItem.SetCenterArea(*pObject);
+ aHeaderItem.SetRightArea(*pEmptyObject);
+ break;
+ case hjRight:
+ aHeaderItem.SetLeftArea(*pEmptyObject);
+ aHeaderItem.SetCenterArea(*pEmptyObject);
+ aHeaderItem.SetRightArea(*pObject);
+ break;
+ default:
+ aHeaderItem.SetLeftArea(*pObject);
+ aHeaderItem.SetCenterArea(*pEmptyObject);
+ aHeaderItem.SetRightArea(*pEmptyObject);
+ break;
+ }
+ delete pObject;
+ pSet->Put( aHeaderItem );
+
+ SfxItemSet aSetItemItemSet( *pDoc->GetPool(),
+ ATTR_BACKGROUND, ATTR_BACKGROUND,
+ ATTR_BORDER, ATTR_SHADOW,
+ ATTR_PAGE_SIZE, ATTR_PAGE_SIZE,
+ ATTR_LRSPACE, ATTR_ULSPACE,
+ ATTR_PAGE_ON, ATTR_PAGE_SHARED,
+ 0 );
+ nColor = pHeadFootLine->BackColor;
+ Color aBColor( nColor.Red, nColor.Green, nColor.Blue );
+ nColor = pHeadFootLine->RasterColor;
+ Color aRColor( nColor.Red, nColor.Green, nColor.Blue );
+
+ sal_uInt16 nFact;
+ sal_Bool bSwapCol = false;
+ switch (pHeadFootLine->Raster)
+ {
+ case raNone: nFact = 0xffff; bSwapCol = sal_True; break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff;
+ }
+ if( bSwapCol )
+ aSetItemItemSet.Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ aSetItemItemSet.Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+
+ if (pHeadFootLine->Frame != 0)
+ {
+ sal_uInt16 nLeft = 0;
+ sal_uInt16 nTop = 0;
+ sal_uInt16 nRight = 0;
+ sal_uInt16 nBottom = 0;
+ sal_uInt16 fLeft = (pHeadFootLine->Frame & 0x000F);
+ sal_uInt16 fTop = (pHeadFootLine->Frame & 0x00F0) / 0x0010;
+ sal_uInt16 fRight = (pHeadFootLine->Frame & 0x0F00) / 0x0100;
+ sal_uInt16 fBottom = (pHeadFootLine->Frame & 0xF000) / 0x1000;
+ if (fLeft > 1)
+ nLeft = 50;
+ else if (fLeft > 0)
+ nLeft = 20;
+ if (fTop > 1)
+ nTop = 50;
+ else if (fTop > 0)
+ nTop = 20;
+ if (fRight > 1)
+ nRight = 50;
+ else if (fRight > 0)
+ nRight = 20;
+ if (fBottom > 1)
+ nBottom = 50;
+ else if (fBottom > 0)
+ nBottom = 20;
+ Color ColorLeft(COL_BLACK);
+ Color ColorTop(COL_BLACK);
+ Color ColorRight(COL_BLACK);
+ Color ColorBottom(COL_BLACK);
+ sal_uInt16 cLeft = (pHeadFootLine->FrameColor & 0x000F);
+ sal_uInt16 cTop = (pHeadFootLine->FrameColor & 0x00F0) >> 4;
+ sal_uInt16 cRight = (pHeadFootLine->FrameColor & 0x0F00) >> 8;
+ sal_uInt16 cBottom = (pHeadFootLine->FrameColor & 0xF000) >> 12;
+ lcl_ChangeColor(cLeft, ColorLeft);
+ lcl_ChangeColor(cTop, ColorTop);
+ lcl_ChangeColor(cRight, ColorRight);
+ lcl_ChangeColor(cBottom, ColorBottom);
+ ::editeng::SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+ aLine.SetWidth(nLeft);
+ aLine.SetColor(ColorLeft);
+ aBox.SetLine(&aLine, BOX_LINE_LEFT);
+ aLine.SetWidth(nTop);
+ aLine.SetColor(ColorTop);
+ aBox.SetLine(&aLine, BOX_LINE_TOP);
+ aLine.SetWidth(nRight);
+ aLine.SetColor(ColorRight);
+ aBox.SetLine(&aLine, BOX_LINE_RIGHT);
+ aLine.SetWidth(nBottom);
+ aLine.SetColor(ColorBottom);
+ aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
+
+ aSetItemItemSet.Put(aBox);
+ }
+
+ pSet->Put( SvxULSpaceItem( 0, 0, ATTR_ULSPACE ) );
+
+ if (nHeadFoot==0)
+ aSetItemItemSet.Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, pPage->Top - pPage->Head ) ) );
+ else
+ aSetItemItemSet.Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( 0, pPage->Bottom - pPage->Foot ) ) );
+
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_ON, sal_True ));
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_DYNAMIC, false ));
+ aSetItemItemSet.Put(SfxBoolItem( ATTR_PAGE_SHARED, sal_True ));
+
+ pSet->Put( SvxSetItem( nHeadFoot ? ATTR_PAGE_FOOTERSET : ATTR_PAGE_HEADERSET,
+ aSetItemItemSet ) );
+ }
+
+ SvxPageItem aPageItem(ATTR_PAGE);
+ aPageItem.SetPageUsage( SVX_PAGE_ALL );
+ aPageItem.SetLandscape( pPage->Orientation != 1 );
+ aPageItem.SetNumType( SVX_ARABIC );
+ pSet->Put(aPageItem);
+
+ pSet->Put(SvxLRSpaceItem( pPage->Left, pPage->Right, 0,0, ATTR_LRSPACE ));
+ pSet->Put(SvxULSpaceItem( pPage->Top, pPage->Bottom, ATTR_ULSPACE ));
+
+ pSet->Put(SfxBoolItem( ATTR_PAGE_HORCENTER, pPage->HorCenter ));
+ pSet->Put(SfxBoolItem( ATTR_PAGE_VERCENTER, pPage->VerCenter ));
+
+ //----------------
+ // Area-Parameter:
+ //----------------
+ {
+ ScRange* pRepeatRow = NULL;
+ ScRange* pRepeatCol = NULL;
+
+ if ( pPage->ColRepeatStart >= 0 )
+ pRepeatCol = new ScRange( static_cast<SCCOL> (pPage->ColRepeatStart), 0, 0 );
+ if ( pPage->RowRepeatStart >= 0 )
+ pRepeatRow = new ScRange( 0, static_cast<SCROW> (pPage->RowRepeatStart), 0 );
+
+
+ if ( pRepeatRow || pRepeatCol )
+ {
+ //
+ // an allen Tabellen setzen
+ //
+ for ( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ pDoc->SetRepeatColRange( nTab, pRepeatCol );
+ pDoc->SetRepeatRowRange( nTab, pRepeatRow );
+ }
+ }
+
+ delete pRepeatRow;
+ delete pRepeatCol;
+ }
+
+ //-----------------
+ // Table-Parameter:
+ //-----------------
+ pSet->Put( SfxBoolItem( ATTR_PAGE_NOTES, pPage->PrintNote ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_GRID, pPage->PrintGrid ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_HEADERS, pPage->PrintColRow ) );
+ pSet->Put( SfxBoolItem( ATTR_PAGE_TOPDOWN, pPage->TopBottomDir ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_CHARTS, VOBJ_MODE_SHOW ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_OBJECTS, VOBJ_MODE_SHOW ) );
+ pSet->Put( ScViewObjectModeItem( ATTR_PAGE_DRAWINGS, VOBJ_MODE_SHOW ) );
+ pSet->Put( SfxUInt16Item( ATTR_PAGE_SCALE,
+ (sal_uInt16)( lcl_PascalToDouble( pPage->PrnZoom ) * 100 ) ) );
+ pSet->Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 1 ) );
+
+ pSet->Put( SvxSizeItem( ATTR_PAGE_SIZE, Size( pPage->Width, pPage->Height ) ) );
+ }
+
+ delete pEmptyObject;
+}
+
+
+ScDataObject* Sc10PageData::Clone() const
+{
+ return new Sc10PageData(aPageFormat);
+}
+
+
+//--------------------------------------------
+// Import
+//--------------------------------------------
+
+
+Sc10Import::Sc10Import(SvStream& rStr, ScDocument* pDocument ) :
+ rStream (rStr),
+ pDoc (pDocument),
+ pFontCollection (NULL),
+ pNameCollection (NULL),
+ pPatternCollection (NULL),
+ pDataBaseCollection (NULL),
+ nError (0),
+ nShowTab (0)
+{
+ pPrgrsBar = NULL;
+}
+
+
+Sc10Import::~Sc10Import()
+{
+ pDoc->CalcAfterLoad();
+ pDoc->UpdateAllCharts();
+
+ delete pFontCollection;
+ delete pNameCollection;
+ delete pPatternCollection;
+ delete pDataBaseCollection;
+
+ DBG_ASSERT( pPrgrsBar == NULL,
+ "*Sc10Import::Sc10Import(): Progressbar lebt noch!?" );
+}
+
+
+sal_uLong Sc10Import::Import()
+{
+ pPrgrsBar = new ScfStreamProgressBar( rStream, pDoc->GetDocumentShell() );
+
+ ScDocOptions aOpt = pDoc->GetDocOptions();
+ aOpt.SetDate( 1, 1, 1900 );
+ aOpt.SetYear2000( 18 + 1901 ); // ab SO51 src513e vierstellig
+ pDoc->SetDocOptions( aOpt );
+ pDoc->GetFormatTable()->ChangeNullDate( 1, 1, 1900 );
+
+ LoadFileHeader(); pPrgrsBar->Progress();
+ if (!nError) { LoadFileInfo(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadEditStateInfo(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadProtect(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadViewColRowBar(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadScrZoom(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadPalette(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadFontCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadNameCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadPatternCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadDataBaseCollection(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadTables(); pPrgrsBar->Progress(); }
+ if (!nError) { LoadObjects(); pPrgrsBar->Progress(); }
+ if (!nError) { ImportNameCollection(); pPrgrsBar->Progress(); }
+ pDoc->SetViewOptions( aSc30ViewOpt );
+
+#ifdef DBG_UTIL
+ if (nError)
+ {
+ OSL_FAIL( ByteString::CreateFromInt32( nError ).GetBuffer() );
+ }
+#endif
+
+ delete pPrgrsBar;
+#ifdef DBG_UTIL
+ pPrgrsBar = NULL;
+#endif
+
+ return nError;
+}
+
+
+void Sc10Import::LoadFileHeader()
+{
+ Sc10FileHeader FileHeader;
+ lcl_ReadFileHeader(rStream, FileHeader);
+
+ nError = rStream.GetError();
+ if ( nError == 0 )
+ {
+ sal_Char Sc10CopyRight[32];
+ strcpy(Sc10CopyRight, "Blaise-Tabelle");
+ Sc10CopyRight[14] = 10;
+ Sc10CopyRight[15] = 13;
+ Sc10CopyRight[16] = 0;
+ if ((strcmp(FileHeader.CopyRight, Sc10CopyRight) != 0)
+ || (FileHeader.Version < 101)
+ || (FileHeader.Version > 102))
+ nError = errUnknownFormat;
+ }
+}
+
+
+void Sc10Import::LoadFileInfo()
+{
+ Sc10FileInfo FileInfo;
+ rStream.Read(&FileInfo, sizeof(FileInfo));
+
+ nError = rStream.GetError();
+ // Achtung Info Uebertragen
+}
+
+
+
+void Sc10Import::LoadEditStateInfo()
+{
+ Sc10EditStateInfo EditStateInfo;
+ rStream.Read(&EditStateInfo, sizeof(EditStateInfo));
+
+ nError = rStream.GetError();
+ nShowTab = static_cast<SCTAB>(EditStateInfo.DeltaZ);
+ // Achtung Cursorposition und Offset der Tabelle Uebertragen (soll man das machen??)
+}
+
+
+void Sc10Import::LoadProtect()
+{
+ lcl_ReadSheetProtect(rStream, SheetProtect);
+ nError = rStream.GetError();
+
+ ScDocProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(SheetProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(SheetProtect.PassWord));
+ pDoc->SetDocProtection(&aProtection);
+}
+
+
+void Sc10Import::LoadViewColRowBar()
+{
+ sal_uInt8 ViewColRowBar;
+ rStream >> ViewColRowBar;
+ nError = rStream.GetError();
+ aSc30ViewOpt.SetOption( VOPT_HEADER, (sal_Bool)ViewColRowBar );
+}
+
+
+void Sc10Import::LoadScrZoom()
+{
+ // Achtung Zoom ist leider eine 6Byte TP real Zahl (keine Ahnung wie die Umzusetzen ist)
+ sal_Char cZoom[6];
+ rStream.Read(cZoom, sizeof(cZoom));
+ nError = rStream.GetError();
+}
+
+
+void Sc10Import::LoadPalette()
+{
+ lcl_ReadPalette(rStream, TextPalette);
+ lcl_ReadPalette(rStream, BackPalette);
+ lcl_ReadPalette(rStream, RasterPalette);
+ lcl_ReadPalette(rStream, FramePalette);
+
+ nError = rStream.GetError();
+}
+
+
+void Sc10Import::LoadFontCollection()
+{
+ pFontCollection = new Sc10FontCollection(rStream);
+}
+
+
+void Sc10Import::LoadNameCollection()
+{
+ pNameCollection = new Sc10NameCollection(rStream);
+}
+
+
+void Sc10Import::ImportNameCollection()
+{
+ ScRangeName* pRN = pDoc->GetRangeName();
+
+ for (sal_uInt16 i = 0; i < pNameCollection->GetCount(); i++)
+ {
+ Sc10NameData* pName = pNameCollection->At( i );
+ pRN->insert(
+ new ScRangeData(
+ pDoc, SC10TOSTRING(pName->Name), SC10TOSTRING(pName->Reference)));
+ }
+}
+
+
+void Sc10Import::LoadPatternCollection()
+{
+ pPatternCollection = new Sc10PatternCollection( rStream );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ for( sal_uInt16 i = 0 ; i < pPatternCollection->GetCount() ; i++ )
+ {
+ Sc10PatternData* pPattern = pPatternCollection->At( i );
+ String aName( pPattern->Name, DEFCHARSET );
+ SfxStyleSheetBase* pStyle = pStylePool->Find( aName, SFX_STYLE_FAMILY_PARA );
+ if( pStyle == NULL )
+ pStylePool->Make( aName, SFX_STYLE_FAMILY_PARA );
+ else
+ {
+ pPattern->Name[ 27 ] = 0;
+ strcat( pPattern->Name, "_Old" );
+ aName = SC10TOSTRING( pPattern->Name );
+ pStylePool->Make( aName, SFX_STYLE_FAMILY_PARA );
+ }
+ pStyle = pStylePool->Find( aName, SFX_STYLE_FAMILY_PARA );
+ if( pStyle != NULL )
+ {
+ SfxItemSet &rItemSet = pStyle->GetItemSet();
+ // Font
+ if( ( pPattern->FormatFlags & pfFont ) == pfFont )
+ {
+ FontFamily eFam = FAMILY_DONTKNOW;
+ switch( pPattern->LogFont.lfPitchAndFamily & 0xF0 )
+ {
+ case ffDontCare : eFam = FAMILY_DONTKNOW; break;
+ case ffRoman : eFam = FAMILY_ROMAN; break;
+ case ffSwiss : eFam = FAMILY_SWISS; break;
+ case ffModern : eFam = FAMILY_MODERN; break;
+ case ffScript : eFam = FAMILY_SCRIPT; break;
+ case ffDecorative : eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ rItemSet.Put( SvxFontItem( eFam, SC10TOSTRING( pPattern->LogFont.lfFaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ) );
+ rItemSet.Put( SvxFontHeightItem( Abs( pPattern->LogFont.lfHeight ), 100, ATTR_FONT_HEIGHT ) );
+ Color TextColor( COL_BLACK );
+ lcl_ChangeColor( ( pPattern->nColor & 0x000F ), TextColor );
+ rItemSet.Put( SvxColorItem( TextColor, ATTR_FONT_COLOR ) );
+ // FontAttr
+ if( pPattern->LogFont.lfWeight != fwNormal )
+ rItemSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
+ if( pPattern->LogFont.lfItalic != 0 )
+ rItemSet.Put( SvxPostureItem( ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
+ if( pPattern->LogFont.lfUnderline != 0 )
+ rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
+ if( pPattern->LogFont.lfStrikeOut != 0 )
+ rItemSet.Put( SvxCrossedOutItem( STRIKEOUT_SINGLE, ATTR_FONT_CROSSEDOUT ) );
+ }
+ // Ausrichtung
+ if( ( pPattern->FormatFlags & pfJustify ) == pfJustify )
+ {
+ sal_uInt16 HorJustify = ( pPattern->Justify & 0x000F );
+ sal_uInt16 VerJustify = ( pPattern->Justify & 0x00F0 ) >> 4;
+ sal_uInt16 OJustify = ( pPattern->Justify & 0x0F00 ) >> 8;
+ sal_uInt16 EJustify = ( pPattern->Justify & 0xF000 ) >> 12;
+ if( HorJustify != 0 )
+ switch( HorJustify )
+ {
+ case hjLeft:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
+ break;
+ case hjCenter:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+ break;
+ case hjRight:
+ rItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
+ break;
+ }
+ if( VerJustify != 0 )
+ switch( VerJustify )
+ {
+ case vjTop:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY ) );
+ break;
+ case vjCenter:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
+ break;
+ case vjBottom:
+ rItemSet.Put( SvxVerJustifyItem( SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY ) );
+ break;
+ }
+
+ if( ( OJustify & ojWordBreak ) == ojWordBreak )
+ rItemSet.Put( SfxBoolItem( sal_True ) );
+ if( ( OJustify & ojBottomTop ) == ojBottomTop )
+ rItemSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
+ else if( ( OJustify & ojTopBottom ) == ojTopBottom )
+ rItemSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
+
+ sal_Int16 Margin = Max( ( sal_uInt16 ) 20, ( sal_uInt16 ) ( EJustify * 20 ) );
+ if( ( ( OJustify & ojBottomTop ) == ojBottomTop ) )
+ rItemSet.Put( SvxMarginItem( 20, Margin, 20, Margin, ATTR_MARGIN ) );
+ else
+ rItemSet.Put( SvxMarginItem( Margin, 20, Margin, 20, ATTR_MARGIN ) );
+ }
+
+ // Frame
+ if( ( pPattern->FormatFlags & pfFrame ) == pfFrame )
+ {
+ if( pPattern->Frame != 0 )
+ {
+ sal_uInt16 nLeft = 0;
+ sal_uInt16 nTop = 0;
+ sal_uInt16 nRight = 0;
+ sal_uInt16 nBottom = 0;
+ sal_uInt16 fLeft = ( pPattern->Frame & 0x000F );
+ sal_uInt16 fTop = ( pPattern->Frame & 0x00F0 ) / 0x0010;
+ sal_uInt16 fRight = ( pPattern->Frame & 0x0F00 ) / 0x0100;
+ sal_uInt16 fBottom = ( pPattern->Frame & 0xF000 ) / 0x1000;
+
+ if( fLeft > 1 )
+ nLeft = 50;
+ else if( fLeft > 0 )
+ nLeft = 20;
+
+ if( fTop > 1 )
+ nTop = 50;
+ else if( fTop > 0 )
+ nTop = 20;
+
+ if( fRight > 1 )
+ nRight = 50;
+ else if( fRight > 0 )
+ nRight = 20;
+
+ if( fBottom > 1 )
+ nBottom = 50;
+ else if( fBottom > 0 )
+ nBottom = 20;
+
+ Color ColorLeft( COL_BLACK );
+ Color ColorTop( COL_BLACK );
+ Color ColorRight( COL_BLACK );
+ Color ColorBottom( COL_BLACK );
+
+ sal_uInt16 cLeft = ( pPattern->FrameColor & 0x000F );
+ sal_uInt16 cTop = ( pPattern->FrameColor & 0x00F0 ) >> 4;
+ sal_uInt16 cRight = ( pPattern->FrameColor & 0x0F00 ) >> 8;
+ sal_uInt16 cBottom = ( pPattern->FrameColor & 0xF000 ) >> 12;
+
+ lcl_ChangeColor( cLeft, ColorLeft );
+ lcl_ChangeColor( cTop, ColorTop );
+ lcl_ChangeColor( cRight, ColorRight );
+ lcl_ChangeColor( cBottom, ColorBottom );
+
+ ::editeng::SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+
+ aLine.SetWidth( nLeft );
+ aLine.SetColor( ColorLeft );
+ aBox.SetLine( &aLine, BOX_LINE_LEFT );
+ aLine.SetWidth( nTop );
+ aLine.SetColor( ColorTop );
+ aBox.SetLine( &aLine, BOX_LINE_TOP );
+ aLine.SetWidth( nRight );
+ aLine.SetColor( ColorRight );
+ aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+ aLine.SetWidth( nBottom );
+ aLine.SetColor( ColorBottom );
+ aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+ rItemSet.Put( aBox );
+ }
+ }
+ // Raster
+ if( ( pPattern->FormatFlags & pfRaster ) == pfRaster )
+ {
+ if( pPattern->Raster != 0 )
+ {
+ sal_uInt16 nBColor = ( pPattern->nColor & 0x00F0 ) >> 4;
+ sal_uInt16 nRColor = ( pPattern->nColor & 0x0F00 ) >> 8;
+ Color aBColor( COL_BLACK );
+
+ lcl_ChangeColor( nBColor, aBColor );
+
+ if( nBColor == 0 )
+ aBColor.SetColor( COL_WHITE );
+ else if( nBColor == 15 )
+ aBColor.SetColor( COL_BLACK );
+
+ Color aRColor( COL_BLACK );
+ lcl_ChangeColor( nRColor, aRColor );
+ sal_uInt16 nFact;
+ sal_Bool bSwapCol = false;
+ sal_Bool bSetItem = sal_True;
+ switch (pPattern->Raster)
+ {
+ case raNone: nFact = 0xffff; bSwapCol = sal_True; bSetItem = (nBColor > 0); break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff; bSetItem = (nRColor < 15);
+ }
+ if ( bSetItem )
+ {
+ if( bSwapCol )
+ rItemSet.Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ rItemSet.Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+ }
+ }
+ }
+ // ZahlenFormate
+ if( ( pPattern->ValueFormat.Format != 0 ) &&
+ ( ( pPattern->FormatFlags & pfValue ) == pfValue ) )
+ {
+ sal_uLong nKey = 0;
+ ChangeFormat( pPattern->ValueFormat.Format, pPattern->ValueFormat.Info, nKey );
+ rItemSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nKey ) );
+ }
+
+ // Zellattribute (Schutz, Versteckt...)
+ if( ( pPattern->Flags != 0 ) &&
+ ( ( pPattern->FormatFlags & pfProtection ) == pfProtection ) )
+ {
+ sal_Bool bProtect = ( ( pPattern->Flags & paProtect ) == paProtect );
+ sal_Bool bHFormula = ( ( pPattern->Flags & paHideFormula ) == paHideFormula );
+ sal_Bool bHCell = ( ( pPattern->Flags & paHideAll ) == paHideAll );
+ sal_Bool bHPrint = ( ( pPattern->Flags & paHidePrint ) == paHidePrint );
+ rItemSet.Put( ScProtectionAttr( bProtect, bHFormula, bHCell, bHPrint ) );
+ }
+ } // if Style != 0
+ } // for (i = 0; i < GetCount()
+}
+
+
+void Sc10Import::LoadDataBaseCollection()
+{
+ pDataBaseCollection = new Sc10DataBaseCollection(rStream);
+ for( sal_uInt16 i = 0 ; i < pDataBaseCollection->GetCount() ; i++ )
+ {
+ Sc10DataBaseData* pOldData = pDataBaseCollection->At(i);
+ ScDBData* pNewData = new ScDBData( SC10TOSTRING( pOldData->DataBaseRec.Name ),
+ ( SCTAB ) pOldData->DataBaseRec.Tab,
+ ( SCCOL ) pOldData->DataBaseRec.Block.x1,
+ ( SCROW ) pOldData->DataBaseRec.Block.y1,
+ ( SCCOL ) pOldData->DataBaseRec.Block.x2,
+ ( SCROW ) pOldData->DataBaseRec.Block.y2,
+ sal_True,
+ ( sal_Bool) pOldData->DataBaseRec.RowHeader );
+ pDoc->GetDBCollection()->Insert( pNewData );
+ }
+}
+
+
+void Sc10Import::LoadTables()
+{
+ Sc10PageCollection aPageCollection;
+
+ sal_Int16 nTabCount;
+ rStream >> nTabCount;
+ for (sal_Int16 Tab = 0; (Tab < nTabCount) && (nError == 0); Tab++)
+ {
+ Sc10PageFormat PageFormat;
+ sal_Int16 DataBaseIndex;
+ Sc10TableProtect TabProtect;
+ sal_Int16 TabNo;
+ sal_Char TabName[128];
+ sal_uInt16 Display;
+ sal_uInt8 Visible;
+ sal_uInt16 ID;
+ sal_uInt16 DataCount;
+ sal_uInt16 DataStart;
+ sal_uInt16 DataEnd;
+ sal_uInt16 DataValue;
+ sal_uInt16 Count;
+ sal_uInt16 i;
+ String aStr; // Universal-Konvertierungs-String
+
+
+ lcl_ReadPageFormat(rStream, PageFormat);
+
+ sal_uInt16 nAt = aPageCollection.InsertFormat(PageFormat);
+ String aPageName = lcl_MakeOldPageStyleFormatName( nAt );
+
+ pPrgrsBar->Progress();
+
+ rStream >> DataBaseIndex;
+
+ lcl_ReadTabProtect(rStream, TabProtect);
+
+ ScTableProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(TabProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(TabProtect.PassWord));
+ pDoc->SetTabProtection(static_cast<SCTAB>(Tab), &aProtection);
+
+ rStream >> TabNo;
+
+ sal_uInt8 nLen;
+ rStream >> nLen;
+ rStream.Read(TabName, sizeof(TabName) - 1);
+ if (nLen >= sizeof(TabName))
+ nLen = sizeof(TabName) - 1;
+ TabName[nLen] = 0;
+
+ //----------------------------------------------------------
+ rStream >> Display;
+
+ if ( Tab == (sal_Int16)nShowTab )
+ {
+ ScVObjMode eObjMode = VOBJ_MODE_SHOW;
+
+ aSc30ViewOpt.SetOption( VOPT_FORMULAS, IS_SET(dfFormula,Display) );
+ aSc30ViewOpt.SetOption( VOPT_NULLVALS, IS_SET(dfZerro,Display) );
+ aSc30ViewOpt.SetOption( VOPT_SYNTAX, IS_SET(dfSyntax,Display) );
+ aSc30ViewOpt.SetOption( VOPT_NOTES, IS_SET(dfNoteMark,Display) );
+ aSc30ViewOpt.SetOption( VOPT_VSCROLL, sal_True );
+ aSc30ViewOpt.SetOption( VOPT_HSCROLL, sal_True );
+ aSc30ViewOpt.SetOption( VOPT_TABCONTROLS, sal_True );
+ aSc30ViewOpt.SetOption( VOPT_OUTLINER, sal_True );
+ aSc30ViewOpt.SetOption( VOPT_GRID, IS_SET(dfGrid,Display) );
+
+ // VOPT_HEADER wird in LoadViewColRowBar() gesetzt
+
+ if ( IS_SET(dfObjectAll,Display) ) // Objekte anzeigen
+ eObjMode = VOBJ_MODE_SHOW;
+ else if ( IS_SET(dfObjectFrame,Display) ) // Objekte als Platzhalter
+ eObjMode = VOBJ_MODE_SHOW;
+ else if ( IS_SET(dfObjectNone,Display) ) // Objekte nicht anzeigen
+ eObjMode = VOBJ_MODE_HIDE;
+
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_OLE, eObjMode );
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_CHART, eObjMode );
+ aSc30ViewOpt.SetObjMode( VOBJ_TYPE_DRAW, eObjMode );
+ }
+
+ //--------------------------------------------------------------------
+ rStream >> Visible;
+
+ nError = rStream.GetError();
+ if (nError != 0) return;
+
+ if (TabNo == 0)
+ pDoc->RenameTab(static_cast<SCTAB> (TabNo), SC10TOSTRING( TabName ), false);
+ else
+ pDoc->InsertTab(SC_TAB_APPEND, SC10TOSTRING( TabName ) );
+
+ pDoc->SetPageStyle( static_cast<SCTAB>(Tab), aPageName );
+
+ if (Visible == 0) pDoc->SetVisible(static_cast<SCTAB> (TabNo), false);
+
+ // ColWidth
+ rStream >> ID;
+ if (ID != ColWidthID)
+ {
+ OSL_FAIL( "ColWidthID" );
+ nError = errUnknownID;
+ return;
+ }
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ for (SCCOL j = static_cast<SCCOL>(DataStart); j <= static_cast<SCCOL>(DataEnd); j++) pDoc->SetColWidth(j, static_cast<SCTAB> (TabNo), DataValue);
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // ColAttr
+ rStream >> ID;
+ if (ID != ColAttrID)
+ {
+ OSL_FAIL( "ColAttrID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ if (DataValue != 0)
+ {
+ bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak);
+ bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+ bool bHidden = ((DataValue & crfHidden) == crfHidden);
+ for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++)
+ {
+ pDoc->SetColHidden(k, k, static_cast<SCTAB>(TabNo), bHidden);
+ pDoc->SetColBreak(k, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
+ }
+ }
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // RowHeight
+ rStream >> ID;
+ if (ID != RowHeightID)
+ {
+ OSL_FAIL( "RowHeightID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ pDoc->SetRowHeightRange(static_cast<SCROW> (DataStart), static_cast<SCROW> (DataEnd), static_cast<SCTAB> (TabNo), DataValue);
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // RowAttr
+ rStream >> ID;
+ if (ID != RowAttrID)
+ {
+ OSL_FAIL( "RowAttrID" );
+ nError = errUnknownID;
+ return;
+ }
+
+ rStream >> DataCount;
+ DataStart = 0;
+ for (i=0; i < DataCount; i++)
+ {
+ rStream >> DataEnd;
+ rStream >> DataValue;
+ if (DataValue != 0)
+ {
+ bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak);
+ bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+ bool bHidden = ((DataValue & crfHidden) == crfHidden);
+ for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++)
+ {
+ pDoc->SetRowHidden(l, l, static_cast<SCTAB> (TabNo), bHidden);
+ pDoc->SetRowBreak(l, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
+ }
+ }
+ DataStart = DataEnd + 1;
+ }
+ pPrgrsBar->Progress();
+
+ // DataTable
+ rStream >> ID;
+ if (ID != TableID)
+ {
+ OSL_FAIL( "TableID" );
+ nError = errUnknownID;
+ return;
+ }
+ for (SCCOL Col = 0; (Col <= SC10MAXCOL) && (nError == 0); Col++)
+ {
+ rStream >> Count;
+ nError = rStream.GetError();
+ if ((Count != 0) && (nError == 0))
+ LoadCol(Col, static_cast<SCTAB> (TabNo));
+ }
+ DBG_ASSERT( nError == 0, "Stream" );
+ }
+ pPrgrsBar->Progress();
+
+ aPageCollection.PutToDoc( pDoc );
+}
+
+
+void Sc10Import::LoadCol(SCCOL Col, SCTAB Tab)
+{
+ LoadColAttr(Col, Tab);
+
+ sal_uInt16 CellCount;
+ sal_uInt8 CellType;
+ sal_uInt16 Row;
+ rStream >> CellCount;
+ SCROW nScCount = static_cast< SCROW >( CellCount );
+ if (nScCount > MAXROW) nError = errUnknownFormat;
+ for (sal_uInt16 i = 0; (i < CellCount) && (nError == 0); i++)
+ {
+ rStream >> CellType;
+ rStream >> Row;
+ nError = rStream.GetError();
+ if (nError == 0)
+ {
+ switch (CellType)
+ {
+ case ctValue :
+ {
+ const SfxPoolItem* pValueFormat = pDoc->GetAttr(Col, static_cast<SCROW> (Row), Tab, ATTR_VALUE_FORMAT);
+ sal_uLong nFormat = ((SfxUInt32Item*)pValueFormat)->GetValue();
+ double Value = ScfTools::ReadLongDouble(rStream);
+ //rStream.Read(&Value, sizeof(Value));
+
+ // Achtung hier ist eine Anpassung Notwendig wenn Ihr das Basisdatum aendert
+ // In StarCalc 1.0 entspricht 0 dem 01.01.1900
+ // if ((nFormat >= 30) && (nFormat <= 35))
+ // Value += 0;
+ if ((nFormat >= 40) && (nFormat <= 45))
+ Value /= 86400.0;
+ pDoc->SetValue(Col, static_cast<SCROW> (Row), Tab, Value);
+ break;
+ }
+ case ctString :
+ {
+ sal_uInt8 Len;
+ sal_Char s[256];
+ rStream >> Len;
+ rStream.Read(s, Len);
+ s[Len] = 0;
+
+ pDoc->SetString( Col, static_cast<SCROW> (Row), Tab, SC10TOSTRING( s ) );
+ break;
+ }
+ case ctFormula :
+ {
+ /*double Value =*/ ScfTools::ReadLongDouble(rStream);
+ sal_uInt8 Len;
+ sal_Char s[256+1];
+ rStream >> Len;
+ rStream.Read(&s[1], Len);
+ s[0] = '=';
+ s[Len + 1] = 0;
+ ScFormulaCell* pCell = new ScFormulaCell( pDoc, ScAddress( Col, static_cast<SCROW> (Row), Tab ) );
+ pCell->SetHybridFormula( SC10TOSTRING( s ),formula::FormulaGrammar::GRAM_NATIVE );
+ pDoc->PutCell( Col, static_cast<SCROW> (Row), Tab, pCell, (sal_Bool)sal_True );
+ break;
+ }
+ case ctNote :
+ break;
+ default :
+ nError = errUnknownFormat;
+ break;
+ }
+ sal_uInt16 NoteLen;
+ rStream >> NoteLen;
+ if (NoteLen != 0)
+ {
+ sal_Char* pNote = new sal_Char[NoteLen+1];
+ rStream.Read(pNote, NoteLen);
+ pNote[NoteLen] = 0;
+ String aNoteText( SC10TOSTRING(pNote));
+ delete [] pNote;
+ ScAddress aPos( Col, static_cast<SCROW>(Row), Tab );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
+ }
+ }
+ pPrgrsBar->Progress();
+ }
+}
+
+
+void Sc10Import::LoadColAttr(SCCOL Col, SCTAB Tab)
+{
+ Sc10ColAttr aFont;
+ Sc10ColAttr aAttr;
+ Sc10ColAttr aJustify;
+ Sc10ColAttr aFrame;
+ Sc10ColAttr aRaster;
+ Sc10ColAttr aValue;
+ Sc10ColAttr aColor;
+ Sc10ColAttr aFrameColor;
+ Sc10ColAttr aFlag;
+ Sc10ColAttr aPattern;
+
+ if (nError == 0) LoadAttr(aFont);
+ if (nError == 0) LoadAttr(aAttr);
+ if (nError == 0) LoadAttr(aJustify);
+ if (nError == 0) LoadAttr(aFrame);
+ if (nError == 0) LoadAttr(aRaster);
+ if (nError == 0) LoadAttr(aValue);
+ if (nError == 0) LoadAttr(aColor);
+ if (nError == 0) LoadAttr(aFrameColor);
+ if (nError == 0) LoadAttr(aFlag);
+ if (nError == 0) LoadAttr(aPattern);
+
+ if (nError == 0)
+ {
+ SCROW nStart;
+ SCROW nEnd;
+ sal_uInt16 i;
+ sal_uInt16 nLimit;
+ sal_uInt16 nValue1;
+ Sc10ColData *pColData;
+
+ // Font (Name, Groesse)
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aFont.Count;
+ pColData = aFont.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ if ((nStart <= nEnd) && (pColData->Value))
+ {
+ FontFamily eFam = FAMILY_DONTKNOW;
+ Sc10FontData* pFont = pFontCollection->At(pColData->Value);
+ switch (pFont->PitchAndFamily & 0xF0)
+ {
+ case ffDontCare : eFam = FAMILY_DONTKNOW; break;
+ case ffRoman : eFam = FAMILY_ROMAN; break;
+ case ffSwiss : eFam = FAMILY_SWISS; break;
+ case ffModern : eFam = FAMILY_MODERN; break;
+ case ffScript : eFam = FAMILY_SCRIPT; break;
+ case ffDecorative : eFam = FAMILY_DECORATIVE; break;
+ default: eFam = FAMILY_DONTKNOW; break;
+ }
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SvxFontItem(eFam, SC10TOSTRING( pFont->FaceName ), EMPTY_STRING,
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ));
+ aScPattern.GetItemSet().Put(SvxFontHeightItem(Abs(pFont->Height), 100, ATTR_FONT_HEIGHT ));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Fontfarbe
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aColor.Count;
+ pColData = aColor.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ if ((nStart <= nEnd) && (pColData->Value))
+ {
+ Color TextColor(COL_BLACK);
+ lcl_ChangeColor((pColData->Value & 0x000F), TextColor);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SvxColorItem(TextColor, ATTR_FONT_COLOR ));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Fontattribute (Fett, Kursiv...)
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aAttr.Count;
+ pColData = aAttr.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ if ((nValue1 & atBold) == atBold)
+ aScPattern.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT));
+ if ((nValue1 & atItalic) == atItalic)
+ aScPattern.GetItemSet().Put(SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE));
+ if ((nValue1 & atUnderline) == atUnderline)
+ aScPattern.GetItemSet().Put(SvxUnderlineItem(UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE));
+ if ((nValue1 & atStrikeOut) == atStrikeOut)
+ aScPattern.GetItemSet().Put(SvxCrossedOutItem(STRIKEOUT_SINGLE, ATTR_FONT_CROSSEDOUT));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Zellausrichtung
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aJustify.Count;
+ pColData = aJustify.pData;
+ for( i = 0 ; i < nLimit ; i++, pColData++ )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ sal_uInt16 HorJustify = (nValue1 & 0x000F);
+ sal_uInt16 VerJustify = (nValue1 & 0x00F0) >> 4;
+ sal_uInt16 OJustify = (nValue1 & 0x0F00) >> 8;
+ sal_uInt16 EJustify = (nValue1 & 0xF000) >> 12;
+
+ switch (HorJustify)
+ {
+ case hjLeft:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY));
+ break;
+ case hjCenter:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY));
+ break;
+ case hjRight:
+ aScPattern.GetItemSet().Put(SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY));
+ break;
+ }
+
+ switch (VerJustify)
+ {
+ case vjTop:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY));
+ break;
+ case vjCenter:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY));
+ break;
+ case vjBottom:
+ aScPattern.GetItemSet().Put(SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY));
+ break;
+ }
+
+ if (OJustify & ojWordBreak)
+ aScPattern.GetItemSet().Put(SfxBoolItem(sal_True));
+ if (OJustify & ojBottomTop)
+ aScPattern.GetItemSet().Put(SfxInt32Item(ATTR_ROTATE_VALUE,9000));
+ else if (OJustify & ojTopBottom)
+ aScPattern.GetItemSet().Put(SfxInt32Item(ATTR_ROTATE_VALUE,27000));
+
+ sal_Int16 Margin = Max((sal_uInt16)20, (sal_uInt16)(EJustify * 20));
+ if (((OJustify & ojBottomTop) == ojBottomTop) || ((OJustify & ojBottomTop) == ojBottomTop))
+ aScPattern.GetItemSet().Put(SvxMarginItem(20, Margin, 20, Margin, ATTR_MARGIN));
+ else
+ aScPattern.GetItemSet().Put(SvxMarginItem(Margin, 20, Margin, 20, ATTR_MARGIN));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+ // Umrandung
+ sal_Bool bEnd = false;
+ sal_uInt16 nColorIndex = 0;
+ sal_uInt16 nFrameIndex = 0;
+
+ // Special Fix...
+ const sal_uInt32 nHelpMeStart = 100;
+ sal_uInt32 nHelpMe = nHelpMeStart;
+ sal_uInt16 nColorIndexOld = nColorIndex;
+ sal_uInt16 nFrameIndexOld = nColorIndex;
+
+ nEnd = 0;
+ nStart = 0;
+ while( !bEnd && nHelpMe )
+ {
+ pColData = &aFrame.pData[ nFrameIndex ];
+
+ sal_uInt16 nValue = pColData->Value;
+ sal_uInt16 nLeft = 0;
+ sal_uInt16 nTop = 0;
+ sal_uInt16 nRight = 0;
+ sal_uInt16 nBottom = 0;
+ sal_uInt16 fLeft = ( nValue & 0x000F );
+ sal_uInt16 fTop = ( nValue & 0x00F0 ) >> 4;
+ sal_uInt16 fRight = ( nValue & 0x0F00 ) >> 8;
+ sal_uInt16 fBottom = ( nValue & 0xF000 ) >> 12;
+
+ if( fLeft > 1 )
+ nLeft = 50;
+ else if( fLeft > 0 )
+ nLeft = 20;
+
+ if( fTop > 1 )
+ nTop = 50;
+ else if( fTop > 0 )
+ nTop = 20;
+
+ if( fRight > 1 )
+ nRight = 50;
+ else if( fRight > 0 )
+ nRight = 20;
+
+ if( fBottom > 1 )
+ nBottom = 50;
+ else if( fBottom > 0 )
+ nBottom = 20;
+
+ Color ColorLeft( COL_BLACK );
+ Color ColorTop( COL_BLACK );
+ Color ColorRight( COL_BLACK );
+ Color ColorBottom( COL_BLACK );
+ sal_uInt16 nFrmColVal = aFrameColor.pData[ nColorIndex ].Value;
+ SCROW nFrmColRow = static_cast<SCROW>(aFrameColor.pData[ nColorIndex ].Row);
+ sal_uInt16 cLeft = ( nFrmColVal & 0x000F );
+ sal_uInt16 cTop = ( nFrmColVal & 0x00F0 ) >> 4;
+ sal_uInt16 cRight = ( nFrmColVal & 0x0F00 ) >> 8;
+ sal_uInt16 cBottom = ( nFrmColVal & 0xF000 ) >> 12;
+
+ lcl_ChangeColor( cLeft, ColorLeft );
+ lcl_ChangeColor( cTop, ColorTop );
+ lcl_ChangeColor( cRight, ColorRight );
+ lcl_ChangeColor( cBottom, ColorBottom );
+
+ if( static_cast<SCROW>(pColData->Row) < nFrmColRow )
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ if( nFrameIndex < ( aFrame.Count - 1 ) )
+ nFrameIndex++;
+ }
+ else if( static_cast<SCROW>(pColData->Row) > nFrmColRow )
+ {
+ nEnd = static_cast<SCROW>(aFrameColor.pData[ nColorIndex ].Row);
+ if( nColorIndex < ( aFrameColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ else
+ {
+ nEnd = nFrmColRow;
+ if( nFrameIndex < (aFrame.Count - 1 ) )
+ nFrameIndex++;
+ if( nColorIndex < ( aFrameColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ if( ( nStart <= nEnd ) && ( nValue != 0 ) )
+ {
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ ::editeng::SvxBorderLine aLine;
+ SvxBoxItem aBox( ATTR_BORDER );
+
+ aLine.SetWidth( nLeft );
+ aLine.SetColor( ColorLeft );
+ aBox.SetLine( &aLine, BOX_LINE_LEFT );
+
+ aLine.SetWidth( nTop );
+ aLine.SetColor( ColorTop );
+ aBox.SetLine( &aLine, BOX_LINE_TOP );
+
+ aLine.SetWidth( nRight );
+ aLine.SetColor( ColorRight );
+ aBox.SetLine( &aLine, BOX_LINE_RIGHT );
+
+ aLine.SetWidth( nBottom );
+ aLine.SetColor( ColorBottom );
+ aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
+
+ aScPattern.GetItemSet().Put( aBox );
+ pDoc->ApplyPatternAreaTab( Col, nStart, Col, nEnd, Tab, aScPattern );
+ }
+ nStart = nEnd + 1;
+
+ bEnd = ( nFrameIndex == ( aFrame.Count - 1 ) ) && ( nColorIndex == ( aFrameColor.Count - 1 ) );
+
+ if( nColorIndexOld != nColorIndex || nFrameIndexOld != nFrameIndex )
+ {
+ nColorIndexOld = nColorIndex;
+ nFrameIndexOld = nFrameIndex;
+ nHelpMe = nHelpMeStart;
+ }
+ else
+ nHelpMe--;
+
+ pColData++;
+ }
+
+ // ACHTUNG: Code bis hier ueberarbeitet ... jetzt hab' ich keinen Bock mehr! (GT)
+
+ // Hintergrund (Farbe, Raster)
+ sal_uInt16 nRasterIndex = 0;
+ bEnd = false;
+ nColorIndex = 0;
+ nEnd = 0;
+ nStart = 0;
+
+ // Special Fix...
+ nHelpMe = nHelpMeStart;
+ sal_uInt16 nRasterIndexOld = nRasterIndex;
+
+ while( !bEnd && nHelpMe )
+ {
+ sal_uInt16 nBColor = ( aColor.pData[ nColorIndex ].Value & 0x00F0 ) >> 4;
+ sal_uInt16 nRColor = ( aColor.pData[ nColorIndex ].Value & 0x0F00 ) >> 8;
+ Color aBColor( COL_BLACK );
+
+ lcl_ChangeColor( nBColor, aBColor );
+
+ if( nBColor == 0 )
+ aBColor.SetColor( COL_WHITE );
+ else if( nBColor == 15 )
+ aBColor.SetColor( COL_BLACK );
+
+ Color aRColor( COL_BLACK );
+
+ lcl_ChangeColor( nRColor, aRColor );
+
+ ScPatternAttr aScPattern( pDoc->GetPool() );
+
+ sal_uInt16 nFact;
+ sal_Bool bSwapCol = false;
+ sal_Bool bSetItem = sal_True;
+ switch ( aRaster.pData[ nRasterIndex ].Value )
+ {
+ case raNone: nFact = 0xffff; bSwapCol = sal_True; bSetItem = (nBColor > 0); break;
+ case raGray12: nFact = (0xffff / 100) * 12; break;
+ case raGray25: nFact = (0xffff / 100) * 25; break;
+ case raGray50: nFact = (0xffff / 100) * 50; break;
+ case raGray75: nFact = (0xffff / 100) * 75; break;
+ default: nFact = 0xffff; bSetItem = (nRColor < 15);
+ }
+ if ( bSetItem )
+ {
+ if( bSwapCol )
+ aScPattern.GetItemSet().Put( SvxBrushItem( GetMixedColor( aBColor, aRColor, nFact ), ATTR_BACKGROUND ) );
+ else
+ aScPattern.GetItemSet().Put( SvxBrushItem( GetMixedColor( aRColor, aBColor, nFact ), ATTR_BACKGROUND ) );
+ }
+ if( aRaster.pData[ nRasterIndex ].Row < aColor.pData[ nColorIndex ].Row )
+ {
+ nEnd = static_cast<SCROW>(aRaster.pData[ nRasterIndex ].Row);
+ if( nRasterIndex < ( aRaster.Count - 1 ) )
+ nRasterIndex++;
+ }
+ else if( aRaster.pData[ nRasterIndex ].Row > aColor.pData[ nColorIndex ].Row )
+ {
+ nEnd = static_cast<SCROW>(aColor.pData[ nColorIndex ].Row);
+ if( nColorIndex < ( aColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ else
+ {
+ nEnd = static_cast<SCROW>(aColor.pData[ nColorIndex ].Row);
+ if( nRasterIndex < ( aRaster.Count - 1 ) )
+ nRasterIndex++;
+ if( nColorIndex < ( aColor.Count - 1 ) )
+ nColorIndex++;
+ }
+ if( nStart <= nEnd )
+ pDoc->ApplyPatternAreaTab( Col, nStart, Col, nEnd, Tab, aScPattern );
+
+ nStart = nEnd + 1;
+
+ bEnd = ( nRasterIndex == ( aRaster.Count - 1 ) ) && ( nColorIndex == ( aColor.Count - 1 ) );
+
+ if( nColorIndexOld != nColorIndex || nRasterIndexOld != nRasterIndex )
+ {
+ nColorIndexOld = nColorIndex;
+ nRasterIndexOld = nRasterIndex;
+ nHelpMe = nHelpMeStart;
+ }
+ else
+ nHelpMe--;
+
+ nHelpMe--;
+ }
+
+ // Zahlenformate
+ nStart = 0;
+ nEnd = 0;
+ nLimit = aValue.Count;
+ pColData = aValue.pData;
+ for (i=0; i<nLimit; i++, pColData++)
+ {
+ nEnd = static_cast<SCROW>(pColData->Row);
+ nValue1 = pColData->Value;
+ if ((nStart <= nEnd) && (nValue1))
+ {
+ sal_uLong nKey = 0;
+ sal_uInt16 nFormat = (nValue1 & 0x00FF);
+ sal_uInt16 nInfo = (nValue1 & 0xFF00) >> 8;
+ ChangeFormat(nFormat, nInfo, nKey);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(SfxUInt32Item(ATTR_VALUE_FORMAT, (sal_uInt32)nKey));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // Zellattribute (Schutz, Versteckt...)
+ nStart = 0;
+ nEnd = 0;
+ for (i=0; i<aFlag.Count; i++)
+ {
+ nEnd = static_cast<SCROW>(aFlag.pData[i].Row);
+ if ((nStart <= nEnd) && (aFlag.pData[i].Value != 0))
+ {
+ sal_Bool bProtect = ((aFlag.pData[i].Value & paProtect) == paProtect);
+ sal_Bool bHFormula = ((aFlag.pData[i].Value & paHideFormula) == paHideFormula);
+ sal_Bool bHCell = ((aFlag.pData[i].Value & paHideAll) == paHideAll);
+ sal_Bool bHPrint = ((aFlag.pData[i].Value & paHidePrint) == paHidePrint);
+ ScPatternAttr aScPattern(pDoc->GetPool());
+ aScPattern.GetItemSet().Put(ScProtectionAttr(bProtect, bHFormula, bHCell, bHPrint));
+ pDoc->ApplyPatternAreaTab(Col, nStart, Col, nEnd, Tab, aScPattern);
+ }
+ nStart = nEnd + 1;
+ }
+
+ // ZellVorlagen
+ nStart = 0;
+ nEnd = 0;
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ for (i=0; i<aPattern.Count; i++)
+ {
+ nEnd = static_cast<SCROW>(aPattern.pData[i].Row);
+ if ((nStart <= nEnd) && (aPattern.pData[i].Value != 0))
+ {
+ sal_uInt16 nPatternIndex = (aPattern.pData[i].Value & 0x00FF) - 1;
+ Sc10PatternData* pPattern = pPatternCollection->At(nPatternIndex);
+ if (pPattern != NULL)
+ {
+ ScStyleSheet* pStyle = (ScStyleSheet*) pStylePool->Find(
+ SC10TOSTRING( pPattern->Name ), SFX_STYLE_FAMILY_PARA);
+
+ if (pStyle != NULL)
+ pDoc->ApplyStyleAreaTab(Col, nStart, Col, nEnd, Tab, *pStyle);
+ }
+ }
+ nStart = nEnd + 1;
+ }
+ }
+
+ delete[] aFont.pData;
+ delete[] aAttr.pData;
+ delete[] aJustify.pData;
+ delete[] aFrame.pData;
+ delete[] aRaster.pData;
+ delete[] aValue.pData;
+ delete[] aColor.pData;
+ delete[] aFrameColor.pData;
+ delete[] aFlag.pData;
+ delete[] aPattern.pData;
+}
+
+
+void Sc10Import::LoadAttr(Sc10ColAttr& rAttr)
+{
+ rStream >> rAttr.Count;
+ rAttr.pData = new Sc10ColData[rAttr.Count];
+ if (rAttr.pData != NULL)
+ {
+ for (sal_uInt16 i = 0; i < rAttr.Count; i++)
+ {
+ rStream >> rAttr.pData[i].Row;
+ rStream >> rAttr.pData[i].Value;
+ }
+ nError = rStream.GetError();
+ }
+ else
+ nError = errOutOfMemory;
+}
+
+
+void Sc10Import::ChangeFormat(sal_uInt16 nFormat, sal_uInt16 nInfo, sal_uLong& nKey)
+{
+ // Achtung: Die Formate werden nur auf die StarCalc 3.0 internen Formate gemappt
+ // Korrekterweise muessten zum Teil neue Formate erzeugt werden (sollte Stephan sich ansehen)
+ nKey = 0;
+ switch (nFormat)
+ {
+ case vfStandard :
+ if (nInfo > 0)
+ nKey = 2;
+ break;
+ case vfMoney :
+ if (nInfo > 0)
+ nKey = 21;
+ else
+ nKey = 20;
+ break;
+ case vfThousend :
+ if (nInfo > 0)
+ nKey = 4;
+ else
+ nKey = 5;
+ break;
+ case vfPercent :
+ if (nInfo > 0)
+ nKey = 11;
+ else
+ nKey = 10;
+ break;
+ case vfExponent :
+ nKey = 60;
+ break;
+ case vfZerro :
+ // Achtung kein Aequivalent
+ break;
+ case vfDate :
+ switch (nInfo)
+ {
+ case df_NDMY_Long :
+ nKey = 31;
+ break;
+ case df_DMY_Long :
+ nKey = 30;
+ break;
+ case df_MY_Long :
+ nKey = 32;
+ break;
+ case df_NDM_Long :
+ nKey = 31;
+ break;
+ case df_DM_Long :
+ nKey = 33;
+ break;
+ case df_M_Long :
+ nKey = 34;
+ break;
+ case df_NDMY_Short :
+ nKey = 31;
+ break;
+ case df_DMY_Short :
+ nKey = 30;
+ break;
+ case df_MY_Short :
+ nKey = 32;
+ break;
+ case df_NDM_Short :
+ nKey = 31;
+ break;
+ case df_DM_Short :
+ nKey = 33;
+ break;
+ case df_M_Short :
+ nKey = 34;
+ break;
+ case df_Q_Long :
+ nKey = 35;
+ break;
+ case df_Q_Short :
+ nKey = 35;
+ break;
+ default :
+ nKey = 30;
+ break;
+ }
+ break;
+ case vfTime :
+ switch (nInfo)
+ {
+ case tf_HMS_Long :
+ nKey = 41;
+ break;
+ case tf_HM_Long :
+ nKey = 40;
+ break;
+ case tf_HMS_Short :
+ nKey = 43;
+ break;
+ case tf_HM_Short :
+ nKey = 42;
+ break;
+ default :
+ nKey = 41;
+ break;
+ }
+ break;
+ case vfBoolean :
+ nKey = 99;
+ break;
+ case vfStandardRed :
+ if (nInfo > 0)
+ nKey = 2;
+ break;
+ case vfMoneyRed :
+ if (nInfo > 0)
+ nKey = 23;
+ else
+ nKey = 22;
+ break;
+ case vfThousendRed :
+ if (nInfo > 0)
+ nKey = 4;
+ else
+ nKey = 5;
+ break;
+ case vfPercentRed :
+ if (nInfo > 0)
+ nKey = 11;
+ else
+ nKey = 10;
+ break;
+ case vfExponentRed :
+ nKey = 60;
+ break;
+ case vfFormula :
+ break;
+ case vfString :
+ break;
+ default :
+ break;
+ }
+}
+
+
+void Sc10Import::LoadObjects()
+{
+ sal_uInt16 ID;
+ rStream >> ID;
+ if (rStream.IsEof()) return;
+ if (ID == ObjectID)
+ {
+ sal_uInt16 nAnz;
+ rStream >> nAnz;
+ sal_Char Reserved[32];
+ rStream.Read(Reserved, sizeof(Reserved));
+ nError = rStream.GetError();
+ if ((nAnz > 0) && (nError == 0))
+ {
+ sal_uInt8 ObjectType;
+ Sc10GraphHeader GraphHeader;
+ sal_Bool IsOleObject = false; // Achtung dies ist nur ein Notnagel
+ for (sal_uInt16 i = 0; (i < nAnz) && (nError == 0) && !rStream.IsEof() && !IsOleObject; i++)
+ {
+ rStream >> ObjectType;
+ lcl_ReadGraphHeader(rStream, GraphHeader);
+
+ double nPPTX = ScGlobal::nScreenPPTX;
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ long nStartX = 0;
+ for (SCsCOL nX=0; nX<GraphHeader.CarretX; nX++)
+ nStartX += pDoc->GetColWidth(nX, static_cast<SCTAB>(GraphHeader.CarretZ));
+ nStartX = (long) ( nStartX * HMM_PER_TWIPS );
+ nStartX += (long) ( GraphHeader.x / nPPTX * HMM_PER_TWIPS );
+ long nSizeX = (long) ( GraphHeader.w / nPPTX * HMM_PER_TWIPS );
+ long nStartY = pDoc->GetRowHeight( 0,
+ static_cast<SCsROW>(GraphHeader.CarretY) - 1,
+ static_cast<SCTAB>(GraphHeader.CarretZ));
+ nStartY = (long) ( nStartY * HMM_PER_TWIPS );
+ nStartY += (long) ( GraphHeader.y / nPPTY * HMM_PER_TWIPS );
+ long nSizeY = (long) ( GraphHeader.h / nPPTY * HMM_PER_TWIPS );
+
+ switch (ObjectType)
+ {
+ case otOle :
+ // Achtung hier muss sowas wie OleLoadFromStream passieren
+ IsOleObject = sal_True;
+ break;
+ case otImage :
+ {
+ Sc10ImageHeader ImageHeader;
+ lcl_ReadImageHeaer(rStream, ImageHeader);
+
+ // Achtung nun kommen die Daten (Bitmap oder Metafile)
+ // Typ = 1 Device Dependend Bitmap DIB
+ // Typ = 2 MetaFile
+ rStream.SeekRel(ImageHeader.Size);
+
+ if( ImageHeader.Typ != 1 && ImageHeader.Typ != 2 )
+ nError = errUnknownFormat;
+ break;
+ }
+ case otChart :
+ {
+ Sc10ChartHeader ChartHeader;
+ Sc10ChartSheetData ChartSheetData;
+ Sc10ChartTypeData* pTypeData = new Sc10ChartTypeData;
+ lcl_ReadChartHeader(rStream, ChartHeader);
+
+ //! altes Metafile verwenden ??
+ rStream.SeekRel(ChartHeader.Size);
+
+ lcl_ReadChartSheetData(rStream, ChartSheetData);
+ lcl_ReadChartTypeData(rStream, *pTypeData);
+
+ Rectangle aRect( Point(nStartX,nStartY), Size(nSizeX,nSizeY) );
+ Sc10InsertObject::InsertChart( pDoc, static_cast<SCTAB>(GraphHeader.CarretZ), aRect,
+ static_cast<SCTAB>(GraphHeader.CarretZ),
+ ChartSheetData.DataX1, ChartSheetData.DataY1,
+ ChartSheetData.DataX2, ChartSheetData.DataY2 );
+
+ delete pTypeData;
+ }
+ break;
+ default :
+ nError = errUnknownFormat;
+ break;
+ }
+ nError = rStream.GetError();
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL( "ObjectID" );
+ nError = errUnknownID;
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+
+FltError ScFormatFilterPluginImpl::ScImportStarCalc10( SvStream& rStream, ScDocument* pDocument )
+{
+ rStream.Seek( 0UL );
+ Sc10Import aImport( rStream, pDocument );
+ return ( FltError ) aImport.Import();
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/starcalc/scfobj.cxx b/sc/source/filter/starcalc/scfobj.cxx
new file mode 100644
index 000000000000..e1fc11a68719
--- /dev/null
+++ b/sc/source/filter/starcalc/scfobj.cxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+
+using namespace com::sun::star;
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <unotools/moduleoptions.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/objsh.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/app.hxx>
+#include <sot/clsids.hxx>
+#include "address.hxx"
+
+#include "scfobj.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "chartarr.hxx"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+void Sc10InsertObject::InsertChart( ScDocument* pDoc, SCTAB nDestTab, const Rectangle& rRect,
+ SCTAB nSrcTab, sal_uInt16 nX1, sal_uInt16 nY1, sal_uInt16 nX2, sal_uInt16 nY2 )
+{
+ // wenn Chart nicht installiert ist, darf nicht auf SCH_MOD zugegriffen werden!
+ if ( !SvtModuleOptions().IsChart() )
+ return;
+
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = pDoc->GetDocumentShell()->
+ GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aName );
+ if ( xObj.is() )
+ {
+ SdrOle2Obj* pSdrOle2Obj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aName, rRect );
+
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ {
+ pDoc->InitDrawLayer();
+ pModel = pDoc->GetDrawLayer();
+ DBG_ASSERT(pModel,"Draw Layer ?");
+ }
+
+ SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nDestTab));
+ DBG_ASSERT(pPage,"Page ?");
+ pPage->InsertObject(pSdrOle2Obj);
+
+ pSdrOle2Obj->SetLogicRect(rRect); // erst nach InsertObject !!!
+ awt::Size aSz;
+ aSz.Width = rRect.GetSize().Width();
+ aSz.Height = rRect.GetSize().Height();
+ xObj->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, aSz );
+
+ // hier kann das Chart noch nicht mit Daten gefuettert werden,
+ // weil die Formeln noch nicht berechnet sind.
+ // Deshalb in die ChartCollection, die Daten werden dann im
+ // Sc10Import dtor geholt.
+
+ ScChartCollection* pColl = pDoc->GetChartCollection();
+ pColl->Insert( new ScChartArray( pDoc, nSrcTab, static_cast<SCCOL>(nX1), static_cast<SCROW>(nY1), static_cast<SCCOL>(nX2), static_cast<SCROW>(nY2), aName ) );
+ }
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
new file mode 100644
index 000000000000..cab208e7dc21
--- /dev/null
+++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
@@ -0,0 +1,1706 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//___________________________________________________________________
+
+#include <stdio.h>
+#include <sot/storage.hxx>
+#include "XclExpChangeTrack.hxx"
+#include "xeformula.hxx"
+#include "cell.hxx"
+#include "xcl97rec.hxx"
+
+#include <oox/token/tokens.hxx>
+#include <rtl/strbuf.hxx>
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using namespace oox;
+
+static OString lcl_GuidToOString( sal_uInt8 aGuid[ 16 ] )
+{
+ char sBuf[ 40 ];
+ snprintf( sBuf, sizeof( sBuf ),
+ "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ aGuid[ 0 ], aGuid[ 1 ], aGuid[ 2 ], aGuid[ 3 ], aGuid[ 4 ], aGuid[ 5 ], aGuid[ 6 ], aGuid[ 7 ],
+ aGuid[ 8 ], aGuid[ 9 ], aGuid[ 10 ], aGuid[ 11 ], aGuid[ 12 ], aGuid[ 13 ], aGuid[ 14 ], aGuid[ 15 ] );
+ return OString( sBuf );
+}
+
+static OString lcl_DateTimeToOString( const DateTime& rDateTime )
+{
+ char sBuf[ 200 ];
+ snprintf( sBuf, sizeof( sBuf ),
+ "%d-%02d-%02dT%02d:%02d:%02d.%02dZ",
+ rDateTime.GetYear(), rDateTime.GetMonth(), rDateTime.GetDay(),
+ rDateTime.GetHour(), rDateTime.GetMin(), rDateTime.GetSec(),
+ rDateTime.Get100Sec() );
+ return OString( sBuf );
+}
+
+//___________________________________________________________________
+// local functions
+
+void lcl_WriteDateTime( XclExpStream& rStrm, const DateTime& rDateTime )
+{
+ rStrm.SetSliceSize( 7 );
+ rStrm << (sal_uInt16) rDateTime.GetYear()
+ << (sal_uInt8) rDateTime.GetMonth()
+ << (sal_uInt8) rDateTime.GetDay()
+ << (sal_uInt8) rDateTime.GetHour()
+ << (sal_uInt8) rDateTime.GetMin()
+ << (sal_uInt8) rDateTime.GetSec();
+ rStrm.SetSliceSize( 0 );
+}
+
+// write string and fill rest of <nLength> with zero bytes
+// <nLength> is without string header
+void lcl_WriteFixedString( XclExpStream& rStrm, const XclExpString& rString, sal_Size nLength )
+{
+ sal_Size nStrBytes = rString.GetBufferSize();
+ DBG_ASSERT( nLength >= nStrBytes, "lcl_WriteFixedString - String too long" );
+ if( rString.Len() > 0 )
+ rStrm << rString;
+ if( nLength > nStrBytes )
+ rStrm.WriteZeroBytes( nLength - nStrBytes );
+}
+
+inline void lcl_GenerateGUID( sal_uInt8* pGUID, sal_Bool& rValidGUID )
+{
+ rtl_createUuid( pGUID, rValidGUID ? pGUID : NULL, false );
+ rValidGUID = sal_True;
+}
+
+inline void lcl_WriteGUID( XclExpStream& rStrm, const sal_uInt8* pGUID )
+{
+ rStrm.SetSliceSize( 16 );
+ for( sal_Size nIndex = 0; nIndex < 16; nIndex++ )
+ rStrm << pGUID[ nIndex ];
+ rStrm.SetSliceSize( 0 );
+}
+
+//___________________________________________________________________
+
+XclExpUserBView::XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID ) :
+ sUsername( rUsername )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+void XclExpUserBView::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0xFF078014
+ << (sal_uInt32) 0x00000001;
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm.WriteZeroBytes( 8 );
+ rStrm << (sal_uInt32) 1200
+ << (sal_uInt32) 1000
+ << (sal_uInt16) 1000
+ << (sal_uInt16) 0x0CF7
+ << (sal_uInt16) 0x0000
+ << (sal_uInt16) 0x0001
+ << (sal_uInt16) 0x0000;
+ if( sUsername.Len() > 0 )
+ rStrm << sUsername;
+}
+
+sal_uInt16 XclExpUserBView::GetNum() const
+{
+ return 0x01A9;
+}
+
+sal_Size XclExpUserBView::GetLen() const
+{
+ return 50 + ((sUsername.Len() > 0) ? sUsername.GetSize() : 0);
+}
+
+//___________________________________________________________________
+
+XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack& rChangeTrack )
+{
+ sal_uInt8 aGUID[ 16 ];
+ sal_Bool bValidGUID = false;
+ const ScStrCollection& rStrColl = rChangeTrack.GetUserCollection();
+ for( sal_uInt16 nIndex = 0; nIndex < rStrColl.GetCount(); nIndex++ )
+ {
+ const StrData* pStrData = (const StrData*) rStrColl.At( nIndex );
+ lcl_GenerateGUID( aGUID, bValidGUID );
+ if( pStrData )
+ List::Insert( new XclExpUserBView( pStrData->GetString(), aGUID ), LIST_APPEND );
+ }
+}
+
+XclExpUserBViewList::~XclExpUserBViewList()
+{
+ for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
+ delete pRec;
+}
+
+void XclExpUserBViewList::Save( XclExpStream& rStrm )
+{
+ for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
+ pRec->Save( rStrm );
+}
+
+//___________________________________________________________________
+
+XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab ) :
+ nCurrTab( nTab )
+{
+ memcpy( aGUID, pGUID, 16 );
+}
+
+void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm )
+{
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << nCurrTab
+ << (sal_uInt32) 100
+ << (sal_uInt32) 64
+ << (sal_uInt32) 3
+ << (sal_uInt32) 0x0000003C
+ << (sal_uInt16) 0
+ << (sal_uInt16) 3
+ << (sal_uInt16) 0
+ << (sal_uInt16) 3
+ << (double) 0
+ << (double) 0
+ << (sal_Int16) -1
+ << (sal_Int16) -1;
+}
+
+sal_uInt16 XclExpUsersViewBegin::GetNum() const
+{
+ return 0x01AA;
+}
+
+sal_Size XclExpUsersViewBegin::GetLen() const
+{
+ return 64;
+}
+
+//___________________________________________________________________
+
+void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0001;
+}
+
+sal_uInt16 XclExpUsersViewEnd::GetNum() const
+{
+ return 0x01AB;
+}
+
+sal_Size XclExpUsersViewEnd::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0000;
+}
+
+sal_uInt16 XclExpChTr0x0191::GetNum() const
+{
+ return 0x0191;
+}
+
+sal_Size XclExpChTr0x0191::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0006
+ << (sal_uInt16) 0x0000;
+}
+
+sal_uInt16 XclExpChTr0x0198::GetNum() const
+{
+ return 0x0198;
+}
+
+sal_Size XclExpChTr0x0198::GetLen() const
+{
+ return 4;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( 0x0022 );
+ rStrm.WriteZeroBytes( 510 );
+}
+
+sal_uInt16 XclExpChTr0x0192::GetNum() const
+{
+ return 0x0192;
+}
+
+sal_Size XclExpChTr0x0192::GetLen() const
+{
+ return 512;
+}
+
+//___________________________________________________________________
+
+void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0000;
+}
+
+sal_uInt16 XclExpChTr0x0197::GetNum() const
+{
+ return 0x0197;
+}
+
+sal_Size XclExpChTr0x0197::GetLen() const
+{
+ return 2;
+}
+
+//___________________________________________________________________
+
+XclExpChTrEmpty::~XclExpChTrEmpty()
+{
+}
+
+sal_uInt16 XclExpChTrEmpty::GetNum() const
+{
+ return nRecNum;
+}
+
+sal_Size XclExpChTrEmpty::GetLen() const
+{
+ return 0;
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x0195::~XclExpChTr0x0195()
+{
+}
+
+void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.WriteZeroBytes( 162 );
+}
+
+sal_uInt16 XclExpChTr0x0195::GetNum() const
+{
+ return 0x0195;
+}
+
+sal_Size XclExpChTr0x0195::GetLen() const
+{
+ return 162;
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x0194::~XclExpChTr0x0194()
+{
+}
+
+void XclExpChTr0x0194::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0;
+ lcl_WriteDateTime( rStrm, aDateTime );
+ rStrm << (sal_uInt8) 0;
+ lcl_WriteFixedString( rStrm, sUsername, 147 );
+}
+
+sal_uInt16 XclExpChTr0x0194::GetNum() const
+{
+ return 0x0194;
+}
+
+sal_Size XclExpChTr0x0194::GetLen() const
+{
+ return 162;
+}
+
+//___________________________________________________________________
+
+XclExpChTrHeader::~XclExpChTrHeader()
+{
+}
+
+void XclExpChTrHeader::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) 0x0006
+ << (sal_uInt16) 0x0000
+ << (sal_uInt16) 0x000D;
+ lcl_WriteGUID( rStrm, aGUID );
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << nCount
+ << (sal_uInt16) 0x0001
+ << (sal_uInt32) 0x00000000
+ << (sal_uInt16) 0x001E;
+}
+
+sal_uInt16 XclExpChTrHeader::GetNum() const
+{
+ return 0x0196;
+}
+
+sal_Size XclExpChTrHeader::GetLen() const
+{
+ return 50;
+}
+
+void XclExpChTrHeader::SaveXml( XclExpXmlStream& rRevisionHeadersStrm )
+{
+ sax_fastparser::FSHelperPtr pHeaders = rRevisionHeadersStrm.GetCurrentStream();
+ rRevisionHeadersStrm.WriteAttributes(
+ XML_guid, lcl_GuidToOString( aGUID ).getStr(),
+ XML_lastGuid, NULL, // OOXTODO
+ XML_shared, NULL, // OOXTODO
+ XML_diskRevisions, NULL, // OOXTODO
+ XML_history, NULL, // OOXTODO
+ XML_trackRevisions, NULL, // OOXTODO
+ XML_exclusive, NULL, // OOXTODO
+ XML_revisionId, NULL, // OOXTODO
+ XML_version, NULL, // OOXTODO
+ XML_keepChangeHistory, NULL, // OOXTODO
+ XML_protected, NULL, // OOXTODO
+ XML_preserveHistory, NULL, // OOXTODO
+ FSEND );
+ pHeaders->write( ">" );
+}
+
+//___________________________________________________________________
+
+XclExpChTrInfo::~XclExpChTrInfo()
+{
+}
+
+void XclExpChTrInfo::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt32) 0xFFFFFFFF
+ << (sal_uInt32) 0x00000000
+ << (sal_uInt32) 0x00000020
+ << (sal_uInt16) 0xFFFF;
+ lcl_WriteGUID( rStrm, aGUID );
+ rStrm << (sal_uInt16) 0x04B0;
+ lcl_WriteFixedString( rStrm, sUsername, 113 );
+ lcl_WriteDateTime( rStrm, aDateTime );
+ rStrm << (sal_uInt8) 0x0000
+ << (sal_uInt16) 0x0002;
+}
+
+sal_uInt16 XclExpChTrInfo::GetNum() const
+{
+ return 0x0138;
+}
+
+sal_Size XclExpChTrInfo::GetLen() const
+{
+ return 158;
+}
+
+void XclExpChTrInfo::SaveXml( XclExpXmlStream& rRevisionHeadersStrm )
+{
+ sax_fastparser::FSHelperPtr pHeader = rRevisionHeadersStrm.GetCurrentStream();
+
+ OUString sRelationshipId;
+ sax_fastparser::FSHelperPtr pRevisionLog = rRevisionHeadersStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/revisions/", "revisionLog", mnLogNumber ),
+ XclXmlUtils::GetStreamName( NULL, "revisionLog", mnLogNumber ),
+ rRevisionHeadersStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionLog",
+ &sRelationshipId );
+
+ rRevisionHeadersStrm.WriteAttributes(
+ XML_guid, lcl_GuidToOString( aGUID ).getStr(),
+ XML_dateTime, lcl_DateTimeToOString( aDateTime ).getStr(),
+ XML_maxSheetId, NULL, // OOXTODO
+ XML_userName, XclXmlUtils::ToOString( sUsername ).getStr(),
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sRelationshipId ).getStr(),
+ XML_minRId, NULL, // OOXTODO
+ XML_maxRId, NULL, // OOXTODO
+ FSEND );
+ pHeader->write( ">" );
+
+ rRevisionHeadersStrm.PushStream( pRevisionLog );
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) :
+ nBufSize( nCount ),
+ nLastId( nCount )
+{
+ pBuffer = new sal_uInt16[ nBufSize ];
+ memset( pBuffer, 0, sizeof(sal_uInt16) * nBufSize );
+ pLast = pBuffer + nBufSize - 1;
+}
+
+XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy ) :
+ nBufSize( rCopy.nBufSize ),
+ nLastId( rCopy.nLastId )
+{
+ pBuffer = new sal_uInt16[ nBufSize ];
+ memcpy( pBuffer, rCopy.pBuffer, sizeof(sal_uInt16) * nBufSize );
+ pLast = pBuffer + nBufSize - 1;
+}
+
+XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
+{
+ delete[] pBuffer;
+}
+
+void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex )
+{
+ DBG_ASSERT( nIndex < nLastId, "XclExpChTrTabIdBuffer::Insert - out of range" );
+
+ sal_uInt16 nFreeCount = 0;
+ for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
+ {
+ if( !*pElem )
+ nFreeCount++;
+ if( nFreeCount > nIndex )
+ {
+ *pElem = nLastId--;
+ return;
+ }
+ }
+}
+
+void XclExpChTrTabIdBuffer::InitFillup()
+{
+ sal_uInt16 nFreeCount = 1;
+ for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
+ if( !*pElem )
+ *pElem = nFreeCount++;
+ nLastId = nBufSize;
+}
+
+sal_uInt16 XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex ) const
+{
+ DBG_ASSERT( nIndex < nBufSize, "XclExpChTrTabIdBuffer::GetId - out of range" );
+ return pBuffer[ nIndex ];
+}
+
+void XclExpChTrTabIdBuffer::Remove()
+{
+ DBG_ASSERT( pBuffer <= pLast, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
+ sal_uInt16* pElem = pBuffer;
+ while( (pElem <= pLast) && (*pElem != nLastId) )
+ pElem++;
+ while( pElem < pLast )
+ {
+ *pElem = *(pElem + 1);
+ pElem++;
+ }
+ pLast--;
+ nLastId--;
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabIdBufferList::~XclExpChTrTabIdBufferList()
+{
+ for( XclExpChTrTabIdBuffer* pBuffer = First(); pBuffer; pBuffer = Next() )
+ delete pBuffer;
+}
+
+//___________________________________________________________________
+
+XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer, bool bInRevisionHeaders )
+ : nTabCount( rBuffer.GetBufferCount() )
+ , mbInRevisionHeaders( bInRevisionHeaders )
+{
+ pBuffer = new sal_uInt16[ nTabCount ];
+ rBuffer.GetBufferCopy( pBuffer );
+}
+
+XclExpChTrTabId::~XclExpChTrTabId()
+{
+ Clear();
+}
+
+void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
+{
+ Clear();
+ nTabCount = rBuffer.GetBufferCount();
+ pBuffer = new sal_uInt16[ nTabCount ];
+ rBuffer.GetBufferCopy( pBuffer );
+}
+
+void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.EnableEncryption();
+ if( pBuffer )
+ for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
+ rStrm << *pElem;
+ else
+ for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ )
+ rStrm << nIndex;
+}
+
+sal_uInt16 XclExpChTrTabId::GetNum() const
+{
+ return 0x013D;
+}
+
+sal_Size XclExpChTrTabId::GetLen() const
+{
+ return nTabCount << 1;
+}
+
+void XclExpChTrTabId::SaveXml( XclExpXmlStream& rRevisionLogStrm )
+{
+ if( !mbInRevisionHeaders )
+ return;
+
+ sax_fastparser::FSHelperPtr pRevisionLog = rRevisionLogStrm.GetCurrentStream();
+ rRevisionLogStrm.PopStream();
+
+ sax_fastparser::FSHelperPtr pHeader = rRevisionLogStrm.GetCurrentStream();
+ pHeader->startElement( XML_sheetIdMap,
+ XML_count, OString::valueOf( sal_Int32( nTabCount ) ).getStr(),
+ FSEND );
+ for( int i = 0; i < nTabCount; ++i )
+ {
+ pHeader->singleElement( XML_sheetId,
+ XML_val, OString::valueOf( sal_Int32( pBuffer[ i ] ) ).getStr(),
+ FSEND );
+ }
+ pHeader->endElement( XML_sheetIdMap );
+
+ rRevisionLogStrm.PushStream( pRevisionLog );
+}
+
+//___________________________________________________________________
+
+// ! does not copy additional actions
+XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) :
+ ExcRecord( rCopy ),
+ sUsername( rCopy.sUsername ),
+ aDateTime( rCopy.aDateTime ),
+ nIndex( 0 ),
+ pAddAction( 0 ),
+ bAccepted( rCopy.bAccepted ),
+ rTabInfo( rCopy.rTabInfo ),
+ rIdBuffer( rCopy.rIdBuffer ),
+ nLength( rCopy.nLength ),
+ nOpCode( rCopy.nOpCode ),
+ bForceInfo( rCopy.bForceInfo )
+{
+}
+
+XclExpChTrAction::XclExpChTrAction(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ sal_uInt16 nNewOpCode ) :
+ sUsername( rAction.GetUser() ),
+ aDateTime( rAction.GetDateTime() ),
+ nIndex( 0 ),
+ pAddAction( NULL ),
+ bAccepted( rAction.IsAccepted() ),
+ rTabInfo( rRoot.GetTabInfo() ),
+ rIdBuffer( rTabIdBuffer ),
+ nLength( 0 ),
+ nOpCode( nNewOpCode ),
+ bForceInfo( false )
+{
+ aDateTime.SetSec( 0 );
+ aDateTime.Set100Sec( 0 );
+}
+
+XclExpChTrAction::~XclExpChTrAction()
+{
+ if( pAddAction )
+ delete pAddAction;
+}
+
+void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction )
+{
+ if( pAddAction )
+ pAddAction->SetAddAction( pAction );
+ else
+ pAddAction = pAction;
+}
+
+void XclExpChTrAction::AddDependentContents(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ ScChangeTrack& rChangeTrack )
+{
+ ScChangeActionTable aActionTable;
+ rChangeTrack.GetDependents( (ScChangeAction*)(&rAction), aActionTable );
+ for( const ScChangeAction* pDepAction = aActionTable.First(); pDepAction; pDepAction = aActionTable.Next() )
+ if( pDepAction->GetType() == SC_CAT_CONTENT )
+ SetAddAction( new XclExpChTrCellContent(
+ *((const ScChangeActionContent*) pDepAction), rRoot, rIdBuffer ) );
+}
+
+void XclExpChTrAction::SetIndex( sal_uInt32& rIndex )
+{
+ nIndex = rIndex++;
+}
+
+void XclExpChTrAction::SaveCont( XclExpStream& rStrm )
+{
+ DBG_ASSERT( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" );
+ rStrm << nLength
+ << nIndex
+ << nOpCode
+ << (sal_uInt16)(bAccepted ? EXC_CHTR_ACCEPT : EXC_CHTR_NOTHING);
+ SaveActionData( rStrm );
+}
+
+void XclExpChTrAction::PrepareSaveAction( XclExpStream& /*rStrm*/ ) const
+{
+}
+
+void XclExpChTrAction::CompleteSaveAction( XclExpStream& /*rStrm*/ ) const
+{
+}
+
+void XclExpChTrAction::Save( XclExpStream& rStrm )
+{
+ PrepareSaveAction( rStrm );
+ ExcRecord::Save( rStrm );
+ if( pAddAction )
+ pAddAction->Save( rStrm );
+ CompleteSaveAction( rStrm );
+}
+
+sal_Size XclExpChTrAction::GetLen() const
+{
+ return GetHeaderByteCount() + GetActionByteCount();
+}
+
+//___________________________________________________________________
+
+XclExpChTrData::XclExpChTrData() :
+ pString( NULL ),
+ mpFormulaCell( NULL ),
+ fValue( 0.0 ),
+ nRKValue( 0 ),
+ nType( EXC_CHTR_TYPE_EMPTY ),
+ nSize( 0 )
+{
+}
+
+XclExpChTrData::~XclExpChTrData()
+{
+ Clear();
+}
+
+void XclExpChTrData::Clear()
+{
+ DELETEZ( pString );
+ mpFormulaCell = NULL;
+ mxTokArr.reset();
+ maRefLog.clear();
+ fValue = 0.0;
+ nRKValue = 0;
+ nType = EXC_CHTR_TYPE_EMPTY;
+ nSize = 0;
+}
+
+void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
+{
+ DBG_ASSERT( mxTokArr && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" );
+ rStrm << *mxTokArr;
+
+ for( XclExpRefLog::const_iterator aIt = maRefLog.begin(), aEnd = maRefLog.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mpUrl && aIt->mpFirstTab )
+ {
+ rStrm << *aIt->mpUrl << (sal_uInt8) 0x01 << *aIt->mpFirstTab << (sal_uInt8) 0x02;
+ }
+ else
+ {
+ bool bSingleTab = aIt->mnFirstXclTab == aIt->mnLastXclTab;
+ rStrm.SetSliceSize( bSingleTab ? 6 : 8 );
+ rStrm << (sal_uInt8) 0x01 << (sal_uInt8) 0x02 << (sal_uInt8) 0x00;
+ rStrm << rTabIdBuffer.GetId( aIt->mnFirstXclTab );
+ if( bSingleTab )
+ rStrm << (sal_uInt8) 0x02;
+ else
+ rStrm << (sal_uInt8) 0x00 << rTabIdBuffer.GetId( aIt->mnLastXclTab );
+ }
+ }
+ rStrm.SetSliceSize( 0 );
+ rStrm << (sal_uInt8) 0x00;
+}
+
+void XclExpChTrData::Write( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
+{
+ switch( nType )
+ {
+ case EXC_CHTR_TYPE_RK:
+ rStrm << nRKValue;
+ break;
+ case EXC_CHTR_TYPE_DOUBLE:
+ rStrm << fValue;
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ DBG_ASSERT( pString, "XclExpChTrData::Write - no string" );
+ rStrm << *pString;
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ WriteFormula( rStrm, rTabIdBuffer );
+ break;
+ }
+}
+
+//___________________________________________________________________
+
+XclExpChTrCellContent::XclExpChTrCellContent(
+ const ScChangeActionContent& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ),
+ XclExpRoot( rRoot ),
+ pOldData( 0 ),
+ pNewData( 0 ),
+ aPosition( rAction.GetBigRange().MakeRange().aStart )
+{
+ sal_uInt32 nDummy32;
+ sal_uInt16 nDummy16;
+ GetCellData( rRoot, rAction.GetOldCell(), pOldData, nDummy32, nOldLength );
+ GetCellData( rRoot, rAction.GetNewCell(), pNewData, nLength, nDummy16 );
+}
+
+XclExpChTrCellContent::~XclExpChTrCellContent()
+{
+ if( pOldData )
+ delete pOldData;
+ if( pNewData )
+ delete pNewData;
+}
+
+void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData )
+{
+ if( rpData )
+ rpData->Clear();
+ else
+ rpData = new XclExpChTrData;
+}
+
+void XclExpChTrCellContent::GetCellData(
+ const XclExpRoot& rRoot,
+ const ScBaseCell* pScCell,
+ XclExpChTrData*& rpData,
+ sal_uInt32& rXclLength1,
+ sal_uInt16& rXclLength2 )
+{
+ MakeEmptyChTrData( rpData );
+ rXclLength1 = 0x0000003A;
+ rXclLength2 = 0x0000;
+
+ if( !pScCell )
+ {
+ delete rpData;
+ rpData = NULL;
+ return;
+ }
+
+ switch( pScCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ rpData->fValue = ((const ScValueCell*) pScCell)->GetValue();
+ if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) )
+ {
+ rpData->nType = EXC_CHTR_TYPE_RK;
+ rpData->nSize = 4;
+ rXclLength1 = 0x0000003E;
+ rXclLength2 = 0x0004;
+ }
+ else
+ {
+ rpData->nType = EXC_CHTR_TYPE_DOUBLE;
+ rpData->nSize = 8;
+ rXclLength1 = 0x00000042;
+ rXclLength2 = 0x0008;
+ }
+ }
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ {
+ String sCellStr;
+ if( pScCell->GetCellType() == CELLTYPE_STRING )
+ {
+ const ScStringCell* pStrCell = static_cast< const ScStringCell* >( pScCell );
+ pStrCell->GetString( sCellStr );
+ rpData->mpFormattedString = XclExpStringHelper::CreateCellString( rRoot,
+ *pStrCell, NULL );
+ }
+ else
+ {
+ const ScEditCell* pEditCell = static_cast< const ScEditCell* >( pScCell );
+ pEditCell->GetString( sCellStr );
+ XclExpHyperlinkHelper aLinkHelper( rRoot, aPosition );
+ rpData->mpFormattedString = XclExpStringHelper::CreateCellString( rRoot,
+ *pEditCell, NULL, aLinkHelper );
+ }
+ rpData->pString = new XclExpString( sCellStr, EXC_STR_DEFAULT, 32766 );
+ rpData->nType = EXC_CHTR_TYPE_STRING;
+ rpData->nSize = 3 + rpData->pString->GetSize();
+ rXclLength1 = 64 + (sCellStr.Len() << 1);
+ rXclLength2 = 6 + (sal_uInt16)(sCellStr.Len() << 1);
+ }
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ const ScFormulaCell* pFmlCell = (const ScFormulaCell*) pScCell;
+ rpData->mpFormulaCell = pFmlCell;
+
+ const ScTokenArray* pTokenArray = pFmlCell->GetCode();
+ if( pTokenArray )
+ {
+ XclExpRefLog& rRefLog = rpData->maRefLog;
+ rpData->mxTokArr = GetFormulaCompiler().CreateFormula(
+ EXC_FMLATYPE_CELL, *pTokenArray, &pFmlCell->aPos, &rRefLog );
+ rpData->nType = EXC_CHTR_TYPE_FORMULA;
+ sal_Size nSize = rpData->mxTokArr->GetSize() + 3;
+
+ for( XclExpRefLog::const_iterator aIt = rRefLog.begin(), aEnd = rRefLog.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mpUrl && aIt->mpFirstTab )
+ nSize += aIt->mpUrl->GetSize() + aIt->mpFirstTab->GetSize() + 2;
+ else
+ nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8;
+ }
+ rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF );
+ rXclLength1 = 0x00000052;
+ rXclLength2 = 0x0018;
+ }
+ }
+ break;
+ default:;
+ }
+}
+
+void XclExpChTrCellContent::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aPosition.Tab() );
+ rStrm << (sal_uInt16)((pOldData ? (pOldData->nType << 3) : 0x0000) | (pNewData ? pNewData->nType : 0x0000))
+ << (sal_uInt16) 0x0000;
+ Write2DAddress( rStrm, aPosition );
+ rStrm << nOldLength
+ << (sal_uInt32) 0x00000000;
+ if( pOldData )
+ pOldData->Write( rStrm, rIdBuffer );
+ if( pNewData )
+ pNewData->Write( rStrm, rIdBuffer );
+}
+
+sal_uInt16 XclExpChTrCellContent::GetNum() const
+{
+ return 0x013B;
+}
+
+sal_Size XclExpChTrCellContent::GetActionByteCount() const
+{
+ sal_Size nLen = 16;
+ if( pOldData )
+ nLen += pOldData->nSize;
+ if( pNewData )
+ nLen += pNewData->nSize;
+ return nLen;
+}
+
+static const char* lcl_GetType( XclExpChTrData* pData )
+{
+ switch( pData->nType )
+ {
+ case EXC_CHTR_TYPE_RK:
+ case EXC_CHTR_TYPE_DOUBLE:
+ return "n";
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ {
+ ScFormulaCell* pFormulaCell = const_cast< ScFormulaCell* >( pData->mpFormulaCell );
+ const char* sType;
+ OUString sValue;
+ XclXmlUtils::GetFormulaTypeAndValue( *pFormulaCell, sType, sValue );
+ return sType;
+ }
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ return "inlineStr";
+ break;
+ default:
+ break;
+ }
+ return "*unknown*";
+}
+
+static void lcl_WriteCell( XclExpXmlStream& rStrm, sal_Int32 nElement, const ScAddress& rPosition, XclExpChTrData* pData )
+{
+ sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
+
+ pStream->startElement( nElement,
+ XML_r, XclXmlUtils::ToOString( rPosition ).getStr(),
+ XML_s, NULL, // OOXTODO: not supported
+ XML_t, lcl_GetType( pData ),
+ XML_cm, NULL, // OOXTODO: not supported
+ XML_vm, NULL, // OOXTODO: not supported
+ XML_ph, NULL, // OOXTODO: not supported
+ FSEND );
+ switch( pData->nType )
+ {
+ case EXC_CHTR_TYPE_RK:
+ case EXC_CHTR_TYPE_DOUBLE:
+ pStream->startElement( XML_v, FSEND );
+ pStream->write( pData->fValue );
+ pStream->endElement( XML_v );
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ pStream->startElement( XML_f,
+ // OOXTODO: other attributes? see XclExpFormulaCell::SaveXml()
+ FSEND );
+ pStream->writeEscaped( XclXmlUtils::ToOUString(
+ *pData->mpFormulaCell->GetDocument(),
+ pData->mpFormulaCell->aPos, pData->mpFormulaCell->GetCode() ) );
+ pStream->endElement( XML_f );
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ pStream->startElement( XML_is, FSEND );
+ if( pData->mpFormattedString )
+ pData->mpFormattedString->WriteXml( rStrm );
+ else
+ pData->pString->WriteXml( rStrm );
+ pStream->endElement( XML_is );
+ break;
+ default:
+ // ignore
+ break;
+ }
+ pStream->endElement( nElement );
+}
+
+void XclExpChTrCellContent::SaveXml( XclExpXmlStream& rRevisionLogStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
+ pStream->startElement( XML_rcc,
+ XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
+ XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
+ XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
+ XML_sId, OString::valueOf( (sal_Int32) GetTabId( aPosition.Tab() ) ).getStr(),
+ XML_odxf, NULL, // OOXTODO: not supported
+ XML_xfDxf, NULL, // OOXTODO: not supported
+ XML_s, NULL, // OOXTODO: not supported
+ XML_dxf, NULL, // OOXTODO: not supported
+ XML_numFmtId, NULL, // OOXTODO: not supported
+ XML_quotePrefix, NULL, // OOXTODO: not supported
+ XML_oldQuotePrefix, NULL, // OOXTODO: not supported
+ XML_ph, NULL, // OOXTODO: not supported
+ XML_oldPh, NULL, // OOXTODO: not supported
+ XML_endOfListFormulaUpdate, NULL, // OOXTODO: not supported
+ FSEND );
+ if( pOldData )
+ {
+ lcl_WriteCell( rRevisionLogStrm, XML_oc, aPosition, pOldData );
+ }
+ if( pNewData )
+ {
+ lcl_WriteCell( rRevisionLogStrm, XML_nc, aPosition, pNewData );
+ }
+ // OOXTODO: XML_odxf, XML_ndxf, XML_extLst elements
+ pStream->endElement( XML_rcc );
+}
+
+//___________________________________________________________________
+
+XclExpChTrInsert::XclExpChTrInsert(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer ),
+ aRange( rAction.GetBigRange().MakeRange() )
+{
+ nLength = 0x00000030;
+ switch( rAction.GetType() )
+ {
+ case SC_CAT_INSERT_COLS: nOpCode = EXC_CHTR_OP_INSCOL; break;
+ case SC_CAT_INSERT_ROWS: nOpCode = EXC_CHTR_OP_INSROW; break;
+ case SC_CAT_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break;
+ case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break;
+ default:
+ OSL_FAIL( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
+ }
+
+ if( nOpCode & EXC_CHTR_OP_COLFLAG )
+ {
+ aRange.aStart.SetRow( 0 );
+ aRange.aEnd.SetRow( rRoot.GetXclMaxPos().Row() );
+ }
+ else
+ {
+ aRange.aStart.SetCol( 0 );
+ aRange.aEnd.SetCol( rRoot.GetXclMaxPos().Col() );
+ }
+
+ if( nOpCode & EXC_CHTR_OP_DELFLAG )
+ {
+ SetAddAction( new XclExpChTr0x014A( *this ) );
+ AddDependentContents( rAction, rRoot, rChangeTrack );
+ }
+}
+
+XclExpChTrInsert::~XclExpChTrInsert()
+{
+}
+
+void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aRange.aStart.Tab() );
+ rStrm << (sal_uInt16) 0x0000;
+ Write2DRange( rStrm, aRange );
+ rStrm << (sal_uInt32) 0x00000000;
+}
+
+void XclExpChTrInsert::PrepareSaveAction( XclExpStream& rStrm ) const
+{
+ if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
+ XclExpChTrEmpty( 0x0150 ).Save( rStrm );
+}
+
+void XclExpChTrInsert::CompleteSaveAction( XclExpStream& rStrm ) const
+{
+ if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
+ XclExpChTrEmpty( 0x0151 ).Save( rStrm );
+}
+
+sal_uInt16 XclExpChTrInsert::GetNum() const
+{
+ return 0x0137;
+}
+
+sal_Size XclExpChTrInsert::GetActionByteCount() const
+{
+ return 16;
+}
+
+static const char* lcl_GetAction( sal_uInt16 nOpCode )
+{
+ switch( nOpCode )
+ {
+ case EXC_CHTR_OP_INSCOL: return "insertCol";
+ case EXC_CHTR_OP_INSROW: return "insertRow";
+ case EXC_CHTR_OP_DELCOL: return "deleteCol";
+ case EXC_CHTR_OP_DELROW: return "deleteRow";
+ default: return "*unknown*";
+ }
+}
+
+void XclExpChTrInsert::SaveXml( XclExpXmlStream& rRevisionLogStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
+ pStream->startElement( XML_rrc,
+ XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
+ XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
+ XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
+ XML_sId, OString::valueOf( (sal_Int32) GetTabId( aRange.aStart.Tab() ) ).getStr(),
+ XML_eol, NULL, // OOXTODO: not supported?
+ XML_ref, XclXmlUtils::ToOString( aRange ).getStr(),
+ XML_action, lcl_GetAction( nOpCode ),
+ XML_edge, NULL, // OOXTODO: ???
+ FSEND );
+ // OOXTODO: does this handle XML_rfmt, XML_undo?
+ XclExpChTrAction* pAction = GetAddAction();
+ while( pAction != NULL )
+ {
+ pAction->SaveXml( rRevisionLogStrm );
+ pAction = pAction->GetAddAction();
+ }
+ pStream->endElement( XML_rrc );
+}
+
+//___________________________________________________________________
+
+XclExpChTrInsertTab::XclExpChTrInsertTab(
+ const ScChangeAction& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_INSTAB ),
+ XclExpRoot( rRoot ),
+ nTab( (SCTAB) rAction.GetBigRange().aStart.Tab() )
+{
+ nLength = 0x0000021C;
+ bForceInfo = sal_True;
+}
+
+XclExpChTrInsertTab::~XclExpChTrInsertTab()
+{
+}
+
+void XclExpChTrInsertTab::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, nTab );
+ rStrm << sal_uInt32( 0 );
+ lcl_WriteFixedString( rStrm, XclExpString( GetTabInfo().GetScTabName( nTab ) ), 127 );
+ lcl_WriteDateTime( rStrm, GetDateTime() );
+ rStrm.WriteZeroBytes( 133 );
+}
+
+sal_uInt16 XclExpChTrInsertTab::GetNum() const
+{
+ return 0x014D;
+}
+
+sal_Size XclExpChTrInsertTab::GetActionByteCount() const
+{
+ return 276;
+}
+
+void XclExpChTrInsertTab::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
+ pStream->singleElement( XML_ris,
+ XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
+ XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
+ XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
+ XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( nTab ) ).getStr(),
+ XML_name, XclXmlUtils::ToOString( GetTabInfo().GetScTabName( nTab ) ).getStr(),
+ XML_sheetPosition, OString::valueOf( (sal_Int32) nTab ).getStr(),
+ FSEND );
+}
+
+//___________________________________________________________________
+
+XclExpChTrMoveRange::XclExpChTrMoveRange(
+ const ScChangeActionMove& rAction,
+ const XclExpRoot& rRoot,
+ const XclExpChTrTabIdBuffer& rTabIdBuffer,
+ ScChangeTrack& rChangeTrack ) :
+ XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_MOVE ),
+ aDestRange( rAction.GetBigRange().MakeRange() )
+{
+ nLength = 0x00000042;
+ aSourceRange = aDestRange;
+ sal_Int32 nDCols, nDRows, nDTabs;
+ rAction.GetDelta( nDCols, nDRows, nDTabs );
+ aSourceRange.aStart.IncRow( (SCROW) -nDRows );
+ aSourceRange.aStart.IncCol( (SCCOL) -nDCols );
+ aSourceRange.aStart.IncTab( (SCTAB) -nDTabs );
+ aSourceRange.aEnd.IncRow( (SCROW) -nDRows );
+ aSourceRange.aEnd.IncCol( (SCCOL) -nDCols );
+ aSourceRange.aEnd.IncTab( (SCTAB) -nDTabs );
+ AddDependentContents( rAction, rRoot, rChangeTrack );
+}
+
+XclExpChTrMoveRange::~XclExpChTrMoveRange()
+{
+}
+
+void XclExpChTrMoveRange::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aDestRange.aStart.Tab() );
+ Write2DRange( rStrm, aSourceRange );
+ Write2DRange( rStrm, aDestRange );
+ WriteTabId( rStrm, aSourceRange.aStart.Tab() );
+ rStrm << (sal_uInt32) 0x00000000;
+}
+
+void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream& rStrm ) const
+{
+ XclExpChTrEmpty( 0x014E ).Save( rStrm );
+}
+
+void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream& rStrm ) const
+{
+ XclExpChTrEmpty( 0x014F ).Save( rStrm );
+}
+
+sal_uInt16 XclExpChTrMoveRange::GetNum() const
+{
+ return 0x0140;
+}
+
+sal_Size XclExpChTrMoveRange::GetActionByteCount() const
+{
+ return 24;
+}
+
+void XclExpChTrMoveRange::SaveXml( XclExpXmlStream& rRevisionLogStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
+
+ pStream->startElement( XML_rm,
+ XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
+ XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
+ XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
+ XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( aDestRange.aStart.Tab() ) ).getStr(),
+ XML_source, XclXmlUtils::ToOString( aSourceRange ).getStr(),
+ XML_destination, XclXmlUtils::ToOString( aDestRange ).getStr(),
+ XML_sourceSheetId, OString::valueOf( (sal_Int32) GetTabId( aSourceRange.aStart.Tab() ) ).getStr(),
+ FSEND );
+ // OOXTODO: does this handle XML_rfmt, XML_undo?
+ XclExpChTrAction* pAction = GetAddAction();
+ while( pAction != NULL )
+ {
+ pAction->SaveXml( rRevisionLogStrm );
+ pAction = pAction->GetAddAction();
+ }
+ pStream->endElement( XML_rm );
+}
+
+//___________________________________________________________________
+
+XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert& rAction ) :
+ XclExpChTrInsert( rAction )
+{
+ nLength = 0x00000026;
+ nOpCode = EXC_CHTR_OP_FORMAT;
+}
+
+XclExpChTr0x014A::~XclExpChTr0x014A()
+{
+}
+
+void XclExpChTr0x014A::SaveActionData( XclExpStream& rStrm ) const
+{
+ WriteTabId( rStrm, aRange.aStart.Tab() );
+ rStrm << (sal_uInt16) 0x0003
+ << (sal_uInt16) 0x0001;
+ Write2DRange( rStrm, aRange );
+}
+
+sal_uInt16 XclExpChTr0x014A::GetNum() const
+{
+ return 0x014A;
+}
+
+sal_Size XclExpChTr0x014A::GetActionByteCount() const
+{
+ return 14;
+}
+
+void XclExpChTr0x014A::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
+
+ pStream->startElement( XML_rfmt,
+ XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( aRange.aStart.Tab() ) ).getStr(),
+ XML_xfDxf, NULL, // OOXTODO: not supported
+ XML_s, NULL, // OOXTODO: style
+ XML_sqref, XclXmlUtils::ToOString( aRange ).getStr(),
+ XML_start, NULL, // OOXTODO: for string changes
+ XML_length, NULL, // OOXTODO: for string changes
+ FSEND );
+ // OOXTODO: XML_dxf, XML_extLst
+
+ pStream->endElement( XML_rfmt );
+}
+
+//___________________________________________________________________
+
+XclExpChTrActionStack::~XclExpChTrActionStack()
+{
+ while( XclExpChTrAction* pRec = Pop() )
+ delete pRec;
+}
+
+void XclExpChTrActionStack::Push( XclExpChTrAction* pNewRec )
+{
+ DBG_ASSERT( pNewRec, "XclExpChTrActionStack::Push - NULL pointer" );
+ if( pNewRec )
+ Stack::Push( pNewRec );
+}
+
+//___________________________________________________________________
+
+XclExpChTrRecordList::~XclExpChTrRecordList()
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ delete pRec;
+}
+
+void XclExpChTrRecordList::Append( ExcRecord* pNewRec )
+{
+ DBG_ASSERT( pNewRec, "XclExpChTrRecordList::Append - NULL pointer" );
+ if( pNewRec )
+ List::Insert( pNewRec, LIST_APPEND );
+}
+
+void XclExpChTrRecordList::Save( XclExpStream& rStrm )
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ pRec->Save( rStrm );
+}
+
+void XclExpChTrRecordList::SaveXml( XclExpXmlStream& rStrm )
+{
+ for( ExcRecord* pRec = First(); pRec; pRec = Next() )
+ pRec->SaveXml( rStrm );
+}
+
+//___________________________________________________________________
+
+class ExcXmlRecord : public ExcRecord
+{
+public:
+ virtual sal_Size GetLen() const;
+ virtual sal_uInt16 GetNum() const;
+ virtual void Save( XclExpStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm ) = 0;
+};
+
+sal_Size ExcXmlRecord::GetLen() const
+{
+ return 0;
+}
+
+sal_uInt16 ExcXmlRecord::GetNum() const
+{
+ return 0;
+}
+
+void ExcXmlRecord::Save( XclExpStream& )
+{
+ // Do nothing; ignored for BIFF output.
+}
+
+class StartXmlElement : public ExcXmlRecord
+{
+public:
+ enum Behavior {
+ CLOSE_ELEMENT = 0x1,
+ WRITE_NAMESPACES = 0x2,
+ };
+ StartXmlElement( sal_Int32 nElement, sal_Int32 eBehavior )
+ : mnElement( nElement ), meBehavior( (Behavior) eBehavior ) {}
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+private:
+ sal_Int32 mnElement;
+ Behavior meBehavior;
+};
+
+void StartXmlElement::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
+ pStream->write( "<" )
+ ->writeId( mnElement );
+ if( meBehavior & WRITE_NAMESPACES )
+ {
+ rStrm.WriteAttributes(
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+ }
+ if( meBehavior & CLOSE_ELEMENT )
+ {
+ pStream->write( ">" );
+ }
+}
+
+class EndXmlElement : public ExcXmlRecord
+{
+ sal_Int32 mnElement;
+public:
+ EndXmlElement( sal_Int32 nElement ) : mnElement( nElement) {}
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+void EndXmlElement::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->endElement( mnElement );
+}
+
+class EndHeaderElement : public EndXmlElement
+{
+public:
+ EndHeaderElement() : EndXmlElement( XML_header ) {}
+ virtual void SaveXml( XclExpXmlStream& rStrm );
+};
+
+void EndHeaderElement::SaveXml( XclExpXmlStream& rStrm )
+{
+ // Remove the `xl/revisions/revisionLogX.xml' file from the stack
+ rStrm.PopStream();
+
+ EndXmlElement::SaveXml( rStrm );
+}
+
+XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot ),
+ aRecList(),
+ aActionStack(),
+ aTabIdBufferList(),
+ pTabIdBuffer( NULL ),
+ pTempDoc( NULL ),
+ nNewAction( 1 ),
+ pHeader( NULL ),
+ bValidGUID( false )
+{
+ DBG_ASSERT( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
+ if( !GetOldRoot().pTabId )
+ return;
+
+ ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack();
+ if (!pTempChangeTrack)
+ return;
+
+ pTabIdBuffer = new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
+ aTabIdBufferList.Append( pTabIdBuffer );
+
+ // calculate final table order (tab id list)
+ const ScChangeAction* pScAction;
+ for( pScAction = pTempChangeTrack->GetLast(); pScAction; pScAction = pScAction->GetPrev() )
+ {
+ if( pScAction->GetType() == SC_CAT_INSERT_TABS )
+ {
+ SCTAB nScTab = static_cast< SCTAB >( pScAction->GetBigRange().aStart.Tab() );
+ pTabIdBuffer->InitFill( GetTabInfo().GetXclTab( nScTab ) );
+ }
+ }
+ pTabIdBuffer->InitFillup();
+ GetOldRoot().pTabId->Copy( *pTabIdBuffer );
+
+ // get actions in reverse order
+ pScAction = pTempChangeTrack->GetLast();
+ while( pScAction )
+ {
+ PushActionRecord( *pScAction );
+ const ScChangeAction* pPrevAction = pScAction->GetPrev();
+ pTempChangeTrack->Undo( pScAction->GetActionNumber(), pScAction->GetActionNumber() );
+ pScAction = pPrevAction;
+ }
+
+ // build record list
+ pHeader = new XclExpChTrHeader;
+ aRecList.Append( new StartXmlElement( XML_headers, StartXmlElement::WRITE_NAMESPACES ) );
+ aRecList.Append( pHeader );
+ aRecList.Append( new XclExpChTr0x0195 );
+ aRecList.Append( new XclExpChTr0x0194( *pTempChangeTrack ) );
+
+ String sLastUsername;
+ DateTime aLastDateTime;
+ sal_uInt32 nIndex = 1;
+ sal_Int32 nLogNumber = 1;
+ while( XclExpChTrAction* pAction = aActionStack.Pop() )
+ {
+ if( (nIndex == 1) || pAction->ForceInfoRecord() ||
+ (pAction->GetUsername() != sLastUsername) ||
+ (pAction->GetDateTime() != aLastDateTime) )
+ {
+ if( nIndex != 1 )
+ {
+ aRecList.Append( new EndXmlElement( XML_revisions ) );
+ aRecList.Append( new EndHeaderElement() );
+ }
+
+ lcl_GenerateGUID( aGUID, bValidGUID );
+ sLastUsername = pAction->GetUsername();
+ aLastDateTime = pAction->GetDateTime();
+
+ aRecList.Append( new StartXmlElement( XML_header, 0 ) );
+ aRecList.Append( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID, nLogNumber++ ) );
+ aRecList.Append( new XclExpChTrTabId( pAction->GetTabIdBuffer(), true ) );
+ aRecList.Append( new StartXmlElement( XML_revisions, StartXmlElement::WRITE_NAMESPACES | StartXmlElement::CLOSE_ELEMENT ) );
+ pHeader->SetGUID( aGUID );
+ }
+ pAction->SetIndex( nIndex );
+ aRecList.Append( pAction );
+ }
+
+ pHeader->SetGUID( aGUID );
+ pHeader->SetCount( nIndex - 1 );
+ if( nLogNumber > 1 )
+ {
+ aRecList.Append( new EndXmlElement( XML_revisions ) );
+ aRecList.Append( new EndHeaderElement() );
+ }
+ aRecList.Append( new EndXmlElement( XML_headers ) );
+ aRecList.Append( new ExcEof );
+}
+
+XclExpChangeTrack::~XclExpChangeTrack()
+{
+ if( pTempDoc )
+ delete pTempDoc;
+}
+
+ScChangeTrack* XclExpChangeTrack::CreateTempChangeTrack()
+{
+ // get original change track
+ ScChangeTrack* pOrigChangeTrack = GetDoc().GetChangeTrack();
+ DBG_ASSERT( pOrigChangeTrack, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
+ if( !pOrigChangeTrack )
+ return NULL;
+
+ // create empty document
+ pTempDoc = new ScDocument;
+ DBG_ASSERT( pTempDoc, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" );
+ if( !pTempDoc )
+ return NULL;
+
+ // adjust table count
+ SCTAB nOrigCount = GetDoc().GetTableCount();
+ String sTabName;
+ for( sal_Int32 nIndex = 0; nIndex < nOrigCount; nIndex++ )
+ {
+ pTempDoc->CreateValidTabName( sTabName );
+ pTempDoc->InsertTab( SC_TAB_APPEND, sTabName );
+ }
+ DBG_ASSERT( nOrigCount == pTempDoc->GetTableCount(),
+ "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
+ if( nOrigCount != pTempDoc->GetTableCount() )
+ return false;
+
+ return pOrigChangeTrack->Clone(pTempDoc);
+}
+
+void XclExpChangeTrack::PushActionRecord( const ScChangeAction& rAction )
+{
+ XclExpChTrAction* pXclAction = NULL;
+ ScChangeTrack* pTempChangeTrack = pTempDoc->GetChangeTrack();
+ switch( rAction.GetType() )
+ {
+ case SC_CAT_CONTENT:
+ pXclAction = new XclExpChTrCellContent( (const ScChangeActionContent&) rAction, GetRoot(), *pTabIdBuffer );
+ break;
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_COLS:
+ if (pTempChangeTrack)
+ pXclAction = new XclExpChTrInsert( rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
+ break;
+ case SC_CAT_INSERT_TABS:
+ {
+ pXclAction = new XclExpChTrInsertTab( rAction, GetRoot(), *pTabIdBuffer );
+ XclExpChTrTabIdBuffer* pNewBuffer = new XclExpChTrTabIdBuffer( *pTabIdBuffer );
+ pNewBuffer->Remove();
+ aTabIdBufferList.Append( pNewBuffer );
+ pTabIdBuffer = pNewBuffer;
+ }
+ break;
+ case SC_CAT_MOVE:
+ if (pTempChangeTrack)
+ pXclAction = new XclExpChTrMoveRange( (const ScChangeActionMove&) rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
+ break;
+ default:;
+ }
+ if( pXclAction )
+ aActionStack.Push( pXclAction );
+}
+
+sal_Bool XclExpChangeTrack::WriteUserNamesStream()
+{
+ sal_Bool bRet = false;
+ SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_USERNAMES );
+ DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aXclStrm( *xSvStrm, GetRoot() );
+ XclExpChTr0x0191().Save( aXclStrm );
+ XclExpChTr0x0198().Save( aXclStrm );
+ XclExpChTr0x0192().Save( aXclStrm );
+ XclExpChTr0x0197().Save( aXclStrm );
+ xSvStrm->Commit();
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+void XclExpChangeTrack::Write()
+{
+ if( !aRecList.Count() )
+ return;
+
+ if( WriteUserNamesStream() )
+ {
+ SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_REVLOG );
+ DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" );
+ if( xSvStrm.Is() )
+ {
+ XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 );
+ aRecList.Save( aXclStrm );
+ xSvStrm->Commit();
+ }
+ }
+}
+
+static void lcl_WriteUserNamesXml( XclExpXmlStream& rWorkbookStrm )
+{
+ sax_fastparser::FSHelperPtr pUserNames = rWorkbookStrm.CreateOutputStream(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/revisions/userNames.xml" )),
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "revisions/userNames.xml" )),
+ rWorkbookStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/usernames" );
+ pUserNames->startElement( XML_users,
+ XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ XML_count, "0",
+ FSEND );
+ // OOXTODO: XML_userinfo elements for each user editing the file
+ // Doesn't seem to be supported by .xls output either (based on
+ // contents of XclExpChangeTrack::WriteUserNamesStream()).
+ pUserNames->endElement( XML_users );
+}
+
+void XclExpChangeTrack::WriteXml( XclExpXmlStream& rWorkbookStrm )
+{
+ if( !aRecList.Count() )
+ return;
+
+ lcl_WriteUserNamesXml( rWorkbookStrm );
+
+ sax_fastparser::FSHelperPtr pRevisionHeaders = rWorkbookStrm.CreateOutputStream(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/revisions/revisionHeaders.xml" )),
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "revisions/revisionHeaders.xml" )),
+ rWorkbookStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionHeaders" );
+ // OOXTODO: XML_userinfo elements for each user editing the file
+ // Doesn't seem to be supported by .xls output either (based on
+ // contents of XclExpChangeTrack::WriteUserNamesStream()).
+ rWorkbookStrm.PushStream( pRevisionHeaders );
+
+ aRecList.SaveXml( rWorkbookStrm );
+
+ rWorkbookStrm.PopStream();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/XclImpChangeTrack.cxx b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
new file mode 100644
index 000000000000..7cf584f317b0
--- /dev/null
+++ b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
@@ -0,0 +1,504 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XclImpChangeTrack.hxx"
+#include <tools/debug.hxx>
+#include <sot/storage.hxx>
+#include <svl/zforlist.hxx>
+#include "chgviset.hxx"
+#include "cell.hxx"
+#include "chgtrack.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "externalrefmgr.hxx"
+
+//___________________________________________________________________
+// class XclImpChangeTrack
+
+XclImpChangeTrack::XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm ) :
+ XclImpRoot( rRoot ),
+ aRecHeader(),
+ sOldUsername(),
+ pChangeTrack( NULL ),
+ pStrm( NULL ),
+ nTabIdCount( 0 ),
+ bGlobExit( false ),
+ eNestedMode( nmBase )
+{
+ // Verify that the User Names stream exists before going any further. Excel adds both
+ // "Revision Log" and "User Names" streams when Change Tracking is active but the Revision log
+ // remains if Change Tracking is turned off.
+ SotStorageStreamRef xUserStrm = OpenStream( EXC_STREAM_USERNAMES );
+ if( !xUserStrm.Is() )
+ return;
+
+ xInStrm = OpenStream( EXC_STREAM_REVLOG );
+ if( xInStrm.Is() )
+ {
+ xInStrm->Seek( STREAM_SEEK_TO_END );
+ sal_uLong nStreamLen = xInStrm->Tell();
+ if( (xInStrm->GetErrorCode() == ERRCODE_NONE) && (nStreamLen != STREAM_SEEK_TO_END) )
+ {
+ xInStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ pStrm = new XclImpStream( *xInStrm, GetRoot() );
+ pStrm->CopyDecrypterFrom( rBookStrm );
+ pChangeTrack = new ScChangeTrack( GetDocPtr() );
+
+ sOldUsername = pChangeTrack->GetUser();
+ pChangeTrack->SetUseFixDateTime( sal_True );
+
+ ReadRecords();
+ }
+ }
+}
+
+XclImpChangeTrack::~XclImpChangeTrack()
+{
+ delete pChangeTrack;
+ delete pStrm;
+}
+
+void XclImpChangeTrack::DoAcceptRejectAction( ScChangeAction* pAction )
+{
+ if( !pAction ) return;
+ switch( aRecHeader.nAccept )
+ {
+ case EXC_CHTR_ACCEPT:
+ pChangeTrack->Accept( pAction );
+ break;
+ case EXC_CHTR_REJECT:
+ break;
+ }
+}
+
+void XclImpChangeTrack::DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast )
+{
+ for( sal_uInt32 nIndex = nFirst; nIndex <= nLast; nIndex++ )
+ DoAcceptRejectAction( pChangeTrack->GetAction( nIndex ) );
+}
+
+void XclImpChangeTrack::DoInsertRange( const ScRange& rRange )
+{
+ sal_uInt32 nFirst = pChangeTrack->GetActionMax() + 1;
+ pChangeTrack->AppendInsert( rRange );
+ sal_uInt32 nLast = pChangeTrack->GetActionMax();
+ DoAcceptRejectAction( nFirst, nLast );
+}
+
+void XclImpChangeTrack::DoDeleteRange( const ScRange& rRange )
+{
+ sal_uLong nFirst, nLast;
+ pChangeTrack->AppendDeleteRange( rRange, NULL, nFirst, nLast );
+ DoAcceptRejectAction( nFirst, nLast );
+}
+
+SCTAB XclImpChangeTrack::ReadTabNum()
+{
+ return static_cast<SCTAB>(GetTabInfo().GetCurrentIndex(
+ pStrm->ReaduInt16(), nTabIdCount ));
+}
+
+void XclImpChangeTrack::ReadDateTime( DateTime& rDateTime )
+{
+ sal_uInt16 nYear;
+ sal_uInt8 nMonth, nDay, nHour, nMin, nSec;
+
+ *pStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+
+ rDateTime.SetYear( nYear );
+ rDateTime.SetMonth( nMonth );
+ rDateTime.SetDay( nDay );
+ rDateTime.SetHour( nHour );
+ rDateTime.SetMin( nMin );
+ rDateTime.SetSec( nSec );
+ rDateTime.Set100Sec( 0 );
+}
+
+sal_Bool XclImpChangeTrack::CheckRecord( sal_uInt16 nOpCode )
+{
+ if( (nOpCode != EXC_CHTR_OP_UNKNOWN) && (aRecHeader.nOpCode != nOpCode) )
+ {
+ OSL_FAIL( "XclImpChangeTrack::CheckRecord - unknown action" );
+ return false;
+ }
+ return aRecHeader.nIndex != 0;
+}
+
+sal_Bool XclImpChangeTrack::Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo )
+{
+ if( LookAtuInt8() == 0x01 )
+ {
+ rExtInfo.mbExternal = false;
+ // internal ref - read tab num and return sc tab num (position in TABID list)
+ pStrm->Ignore( 3 );
+ rFirstTab = static_cast< SCTAB >( GetTabInfo().GetCurrentIndex( pStrm->ReaduInt16(), nTabIdCount ) );
+ sal_uInt8 nFillByte = pStrm->ReaduInt8();
+ rLastTab = (nFillByte == 0x00) ?
+ static_cast< SCTAB >( GetTabInfo().GetCurrentIndex( pStrm->ReaduInt16(), nTabIdCount ) ) : rFirstTab;
+ }
+ else
+ {
+ // external ref - read doc and tab name and find sc tab num
+ // - URL
+ String aEncUrl( pStrm->ReadUniString() );
+ String aUrl;
+ bool bSelf;
+ XclImpUrlHelper::DecodeUrl( aUrl, bSelf, GetRoot(), aEncUrl );
+ pStrm->Ignore( 1 );
+ // - sheet name, always separated from URL
+ String aTabName( pStrm->ReadUniString() );
+ pStrm->Ignore( 1 );
+
+ rExtInfo.mbExternal = true;
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ pRefMgr->convertToAbsName(aUrl);
+ rExtInfo.mnFileId = pRefMgr->getExternalFileId(aUrl);
+ rExtInfo.maTabName = aTabName;
+ rFirstTab = rLastTab = 0;
+ }
+ return sal_True;
+}
+
+void XclImpChangeTrack::ReadFormula( ScTokenArray*& rpTokenArray, const ScAddress& rPosition )
+{
+ sal_uInt16 nFmlSize;
+ *pStrm >> nFmlSize;
+
+ // create a memory stream and copy the formula to be able to read simultaneously
+ // the formula and the additional 3D tab ref data following the formula
+ // here we have to simulate an Excel record to be able to use an XclImpStream...
+ // 2do: remove the stream member from formula converter and add it as a parameter
+ // to the Convert() routine (to prevent the construction/destruction of the
+ // converter in each formula)
+ SvMemoryStream aMemStrm;
+ aMemStrm << (sal_uInt16) 0x0001 << nFmlSize;
+ pStrm->CopyToStream( aMemStrm, nFmlSize );
+ XclImpStream aFmlaStrm( aMemStrm, GetRoot() );
+ aFmlaStrm.StartNextRecord();
+ XclImpChTrFmlConverter aFmlConv( GetRoot(), *this );
+
+ // read the formula, 3D tab refs from extended data
+ const ScTokenArray* pArray = NULL;
+ aFmlConv.Reset( rPosition );
+ sal_Bool bOK = (aFmlConv.Convert( pArray, aFmlaStrm, nFmlSize, false, FT_CellFormula) == ConvOK); // JEG : Check This
+ rpTokenArray = (bOK && pArray) ? new ScTokenArray( *pArray ) : NULL;
+ pStrm->Ignore( 1 );
+}
+
+void XclImpChangeTrack::ReadCell(
+ ScBaseCell*& rpCell,
+ sal_uInt32& rFormat,
+ sal_uInt16 nFlags,
+ const ScAddress& rPosition )
+{
+ rpCell = NULL;
+ rFormat = 0;
+ switch( nFlags & EXC_CHTR_TYPE_MASK )
+ {
+ case EXC_CHTR_TYPE_EMPTY:
+ break;
+ case EXC_CHTR_TYPE_RK:
+ {
+ double fValue = ReadRK();
+ if( pStrm->IsValid() )
+ rpCell = new ScValueCell( fValue );
+ }
+ break;
+ case EXC_CHTR_TYPE_DOUBLE:
+ {
+ double fValue;
+ *pStrm >> fValue;
+ if( pStrm->IsValid() )
+ rpCell = new ScValueCell( fValue );
+ }
+ break;
+ case EXC_CHTR_TYPE_STRING:
+ {
+ String sString( pStrm->ReadUniString() );
+ if( pStrm->IsValid() )
+ rpCell = new ScStringCell( sString );
+ }
+ break;
+ case EXC_CHTR_TYPE_BOOL:
+ {
+ double fValue = (double) ReadBool();
+ if( pStrm->IsValid() )
+ {
+ rpCell = new ScValueCell( fValue );
+ rFormat = GetFormatter().GetStandardFormat( NUMBERFORMAT_LOGICAL, ScGlobal::eLnge );
+ }
+ }
+ break;
+ case EXC_CHTR_TYPE_FORMULA:
+ {
+ ScTokenArray* pTokenArray = NULL;
+ ReadFormula( pTokenArray, rPosition );
+ if( pStrm->IsValid() && pTokenArray )
+ rpCell = new ScFormulaCell( GetDocPtr(), rPosition, pTokenArray );
+ }
+ break;
+ default:
+ OSL_FAIL( "XclImpChangeTrack::ReadCell - unknown data type" );
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInsert()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_UNKNOWN ) )
+ {
+ if( (aRecHeader.nOpCode != EXC_CHTR_OP_INSROW) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_INSCOL) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_DELROW) &&
+ (aRecHeader.nOpCode != EXC_CHTR_OP_DELCOL) )
+ {
+ OSL_FAIL( "XclImpChangeTrack::ReadChTrInsert - unknown action" );
+ return;
+ }
+
+ ScRange aRange;
+ aRange.aStart.SetTab( ReadTabNum() );
+ aRange.aEnd.SetTab( aRange.aStart.Tab() );
+ pStrm->Ignore( 2 );
+ Read2DRange( aRange );
+
+ if( aRecHeader.nOpCode & EXC_CHTR_OP_COLFLAG )
+ aRange.aEnd.SetRow( MAXROW );
+ else
+ aRange.aEnd.SetCol( MAXCOL );
+
+ sal_Bool bValid = pStrm->IsValid();
+ if( FoundNestedMode() )
+ ReadNestedRecords();
+
+ if( bValid )
+ {
+ if( aRecHeader.nOpCode & EXC_CHTR_OP_DELFLAG )
+ DoDeleteRange( aRange );
+ else
+ DoInsertRange( aRange );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInfo()
+{
+ pStrm->DisableDecryption();
+ pStrm->Ignore( 32 );
+ String sUsername( pStrm->ReadUniString() );
+ if( !pStrm->IsValid() ) return;
+
+ if( sUsername.Len() )
+ pChangeTrack->SetUser( sUsername );
+ pStrm->Seek( 148 );
+ if( !pStrm->IsValid() ) return;
+
+ DateTime aDateTime;
+ ReadDateTime( aDateTime );
+ if( pStrm->IsValid() )
+ pChangeTrack->SetFixDateTimeLocal( aDateTime );
+}
+
+void XclImpChangeTrack::ReadChTrCellContent()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_CELL ) )
+ {
+ ScAddress aPosition;
+ SCTAB nTab = ReadTabNum();
+ aPosition.SetTab( nTab );
+ sal_uInt16 nValueType;
+ *pStrm >> nValueType;
+ sal_uInt16 nOldValueType = (nValueType >> 3) & EXC_CHTR_TYPE_MASK;
+ sal_uInt16 nNewValueType = nValueType & EXC_CHTR_TYPE_MASK;
+ pStrm->Ignore( 2 );
+ Read2DAddress( aPosition );
+ sal_uInt16 nOldSize;
+ *pStrm >> nOldSize;
+ DBG_ASSERT( (nOldSize == 0) == (nOldValueType == EXC_CHTR_TYPE_EMPTY),
+ "XclImpChangeTrack::ReadChTrCellContent - old value mismatch" );
+ pStrm->Ignore( 4 );
+ switch( nValueType & EXC_CHTR_TYPE_FORMATMASK )
+ {
+ case 0x0000: break;
+ case 0x1100: pStrm->Ignore( 16 ); break;
+ case 0x1300: pStrm->Ignore( 8 ); break;
+ default: OSL_FAIL( "XclImpChangeTrack::ReadChTrCellContent - unknown format info" );
+ }
+
+ ScBaseCell* pOldCell;
+ ScBaseCell* pNewCell;
+ sal_uInt32 nOldFormat;
+ sal_uInt32 nNewFormat;
+ ReadCell( pOldCell, nOldFormat, nOldValueType, aPosition );
+ ReadCell( pNewCell, nNewFormat, nNewValueType, aPosition );
+ if( !pStrm->IsValid() || (pStrm->GetRecLeft() > 0) )
+ {
+ OSL_FAIL( "XclImpChangeTrack::ReadChTrCellContent - bytes left, action ignored" );
+ if( pOldCell )
+ pOldCell->Delete();
+ if( pNewCell )
+ pNewCell->Delete();
+ }
+ else
+ {
+ ScChangeActionContent* pNewAction =
+ pChangeTrack->AppendContentOnTheFly( aPosition, pOldCell, pNewCell, nOldFormat, nNewFormat );
+ DoAcceptRejectAction( pNewAction );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrTabId()
+{
+ if( nTabIdCount == 0 ) // read only 1st time, otherwise calculated by <ReadChTrInsertTab()>
+ nTabIdCount = static_cast< sal_uInt16 >( pStrm->GetRecLeft() >> 1 );
+}
+
+void XclImpChangeTrack::ReadChTrMoveRange()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_MOVE ) )
+ {
+ ScRange aSourceRange;
+ ScRange aDestRange;
+ aDestRange.aStart.SetTab( ReadTabNum() );
+ aDestRange.aEnd.SetTab( aDestRange.aStart.Tab() );
+ Read2DRange( aSourceRange );
+ Read2DRange( aDestRange );
+ aSourceRange.aStart.SetTab( ReadTabNum() );
+ aSourceRange.aEnd.SetTab( aSourceRange.aStart.Tab() );
+
+ sal_Bool bValid = pStrm->IsValid();
+ if( FoundNestedMode() )
+ ReadNestedRecords();
+
+ if( bValid )
+ {
+ pChangeTrack->AppendMove( aSourceRange, aDestRange, NULL );
+ DoAcceptRejectAction( pChangeTrack->GetLast() );
+ }
+ }
+}
+
+void XclImpChangeTrack::ReadChTrInsertTab()
+{
+ *pStrm >> aRecHeader;
+ if( CheckRecord( EXC_CHTR_OP_INSTAB ) )
+ {
+ SCTAB nTab = ReadTabNum();
+ if( pStrm->IsValid() )
+ {
+ nTabIdCount++;
+ DoInsertRange( ScRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ) );
+ }
+ }
+}
+
+void XclImpChangeTrack::InitNestedMode()
+{
+ DBG_ASSERT( eNestedMode == nmBase, "XclImpChangeTrack::InitNestedMode - unexpected nested mode" );
+ if( eNestedMode == nmBase )
+ eNestedMode = nmFound;
+}
+
+void XclImpChangeTrack::ReadNestedRecords()
+{
+ DBG_ASSERT( eNestedMode == nmFound, "XclImpChangeTrack::StartNestedMode - missing nested mode" );
+ if( eNestedMode == nmFound )
+ {
+ eNestedMode = nmNested;
+ ReadRecords();
+ }
+}
+
+sal_Bool XclImpChangeTrack::EndNestedMode()
+{
+ DBG_ASSERT( eNestedMode != nmBase, "XclImpChangeTrack::EndNestedMode - missing nested mode" );
+ sal_Bool bReturn = (eNestedMode == nmNested);
+ eNestedMode = nmBase;
+ return bReturn;
+}
+
+void XclImpChangeTrack::ReadRecords()
+{
+ sal_Bool bExitLoop = false;
+
+ while( !bExitLoop && !bGlobExit && pStrm->StartNextRecord() )
+ {
+ switch( pStrm->GetRecId() )
+ {
+ case 0x000A: bGlobExit = sal_True; break;
+ case 0x0137: ReadChTrInsert(); break;
+ case 0x0138: ReadChTrInfo(); break;
+ case 0x013B: ReadChTrCellContent(); break;
+ case 0x013D: ReadChTrTabId(); break;
+ case 0x0140: ReadChTrMoveRange(); break;
+ case 0x014D: ReadChTrInsertTab(); break;
+ case 0x014E:
+ case 0x0150: InitNestedMode(); break;
+ case 0x014F:
+ case 0x0151: bExitLoop = EndNestedMode(); break;
+ }
+ }
+}
+
+void XclImpChangeTrack::Apply()
+{
+ if( pChangeTrack )
+ {
+ pChangeTrack->SetUser( sOldUsername );
+ pChangeTrack->SetUseFixDateTime( false );
+
+ GetDoc().SetChangeTrack( pChangeTrack );
+ pChangeTrack = NULL;
+
+ ScChangeViewSettings aSettings;
+ aSettings.SetShowChanges( sal_True );
+ GetDoc().SetChangeViewSettings( aSettings );
+ }
+}
+
+//___________________________________________________________________
+// class XclImpChTrFmlConverter
+
+XclImpChTrFmlConverter::~XclImpChTrFmlConverter()
+{
+}
+
+// virtual, called from ExcToSc8::Convert()
+bool XclImpChTrFmlConverter::Read3DTabReference( sal_uInt16 /*nIxti*/, SCTAB& rFirstTab, SCTAB& rLastTab,
+ ExternalTabInfo& rExtInfo )
+{
+ return rChangeTrack.Read3DTabRefInfo( rFirstTab, rLastTab, rExtInfo );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/xcl97dum.cxx b/sc/source/filter/xcl97/xcl97dum.cxx
new file mode 100644
index 000000000000..1eafabf2fb73
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97dum.cxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+#include "xcl97dum.hxx"
+
+
+// --- ExcDummy8_xx Data ---------------------------------------------
+
+// ... (8+) := neu in Biff8, ... (8*) := anders in Biff8
+
+const sal_uInt8 ExcDummy8_00a::pMyData[] = {
+ 0xe1, 0x00, 0x02, 0x00, 0xb0, 0x04, // INTERFACEHDR
+ 0xc1, 0x00, 0x02, 0x00, 0x00, 0x00, // MMS
+ 0xe2, 0x00, 0x00, 0x00, // INTERFACEEND
+ 0x5c, 0x00, 0x70, 0x00, // WRITEACCESS (8*)
+ 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20, // "Calc"
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x42, 0x00, 0x02, 0x00, 0xb0, 0x04, // CODEPAGE
+ 0x61, 0x01, 0x02, 0x00, 0x00, 0x00 // DSF (8+)
+};
+const sal_Size ExcDummy8_00a::nMyLen = sizeof(ExcDummy8_00a::pMyData);
+
+ // TABID (8+): ExcTabid
+
+const sal_uInt8 ExcDummy8_00b::pMyData[] = {
+ 0x9c, 0x00, 0x02, 0x00, 0x0e, 0x00 // FNGROUPCOUNT
+};
+const sal_Size ExcDummy8_00b::nMyLen = sizeof(ExcDummy8_00b::pMyData);
+
+
+const sal_uInt8 ExcDummy8_040::pMyData[] = {
+ 0xaf, 0x01, 0x02, 0x00, 0x00, 0x00, // PROT4REV (8+)
+ 0xbc, 0x01, 0x02, 0x00, 0x00, 0x00, // PROT4REVPASS (8+)
+// 0x3d, 0x00, 0x12, 0x00, 0xe0, 0x01, 0x5a, 0x00, 0xcf, // WINDOW1
+// 0x3f, 0x4e, 0x2a, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+// 0x01, 0x00, 0x58, 0x02,
+ 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, // BACKUP
+ 0x8d, 0x00, 0x02, 0x00, 0x00, 0x00 // HIDEOBJ
+};
+const sal_Size ExcDummy8_040::nMyLen = sizeof(ExcDummy8_040::pMyData);
+
+
+const sal_uInt8 ExcDummy8_041::pMyData[] = {
+ 0xb7, 0x01, 0x02, 0x00, 0x00, 0x00, // REFRESHALL (8+)
+ 0xda, 0x00, 0x02, 0x00, 0x00, 0x00 // BOOKBOOL
+};
+const sal_Size ExcDummy8_041::nMyLen = sizeof(ExcDummy8_041::pMyData);
+
+
+
+const sal_uInt8 ExcDummy8_02::pMyData[] = {
+ 0x5f, 0x00, 0x02, 0x00, 0x01, 0x00 // SAVERECALC
+ };
+const sal_Size ExcDummy8_02::nMyLen = sizeof(ExcDummy8_02::pMyData);
+
+
+// --- class ExcDummy8_xx --------------------------------------------
+
+sal_Size ExcDummy8_00a::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy8_00a::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_00b::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy8_00b::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_040::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy8_040::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_041::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy8_041::GetData() const
+{
+ return pMyData;
+}
+
+
+
+sal_Size ExcDummy8_02::GetLen() const
+{
+ return nMyLen;
+}
+
+
+const sal_uInt8* ExcDummy8_02::GetData() const
+{
+ return pMyData;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx
new file mode 100644
index 000000000000..75bb0335f9d6
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97esc.cxx
@@ -0,0 +1,554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+
+#include <svx/svdpage.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/fmglob.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <vcl/outdev.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/debug.hxx>
+#include <svx/sdasitm.hxx>
+
+#include <sot/exchange.hxx>
+#include "xeescher.hxx"
+
+#include "global.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include "xecontent.hxx"
+#include <editeng/flditem.hxx>
+#include "userdat.hxx"
+#include "xcl97rec.hxx"
+#include "xehelper.hxx"
+#include "xechart.hxx"
+#include "xcl97esc.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::embed::XClassifiedObject;
+using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::form::XFormsSupplier;
+using ::com::sun::star::script::ScriptEventDescriptor;
+using ::com::sun::star::script::XEventAttacherManager;
+
+// ============================================================================
+
+XclEscherExGlobal::XclEscherExGlobal( const XclExpRoot& rRoot ) :
+ XclExpRoot( rRoot )
+{
+}
+
+SvStream* XclEscherExGlobal::ImplQueryPictureStream()
+{
+ mxPicTempFile.reset( new ::utl::TempFile );
+ if( mxPicTempFile->IsValid() )
+ {
+ mxPicTempFile->EnableKillingFile();
+ mxPicStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxPicTempFile->GetURL(), STREAM_STD_READWRITE ) );
+ mxPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ }
+ return mxPicStrm.get();
+}
+
+// ============================================================================
+
+XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, XclExpObjectManager& rObjMgr, SvStream& rStrm, const XclEscherEx* pParent ) :
+ EscherEx( pParent ? pParent->mxGlobal : EscherExGlobalRef( new XclEscherExGlobal( rRoot ) ), rStrm ),
+ XclExpRoot( rRoot ),
+ mrObjMgr( rObjMgr ),
+ pCurrXclObj( NULL ),
+ pCurrAppData( NULL ),
+ pTheClientData( new XclEscherClientData ),
+ pAdditionalText( NULL ),
+ nAdditionalText( 0 ),
+ mnNextKey( 0 ),
+ mbIsRootDff( pParent == 0 )
+{
+ InsertPersistOffset( mnNextKey, 0 );
+}
+
+
+XclEscherEx::~XclEscherEx()
+{
+ DBG_ASSERT( !aStack.Count(), "~XclEscherEx: stack not empty" );
+ DeleteCurrAppData();
+ delete pTheClientData;
+}
+
+
+sal_uInt32 XclEscherEx::InitNextDffFragment()
+{
+ /* Current value of mnNextKey will be used by caller to refer to the
+ starting point of the DFF fragment. The key exists already in the
+ PersistTable (has been inserted by c'tor of previous call of
+ InitNextDffFragment(), has been updated by UpdateDffFragmentEnd(). */
+ sal_uInt32 nPersistKey = mnNextKey;
+
+ /* Prepare the next key that is used by caller as end point of the DFF
+ fragment. Will be updated by caller when writing to the DFF stream,
+ using the UpdateDffFragmentEnd() function. This is needed to find DFF
+ data written by the SVX base class implementation without interaction,
+ e.g. the solver container that will be written after the last shape. */
+ ++mnNextKey;
+ InsertPersistOffset( mnNextKey, mpOutStrm->Tell() );
+
+ return nPersistKey;
+}
+
+void XclEscherEx::UpdateDffFragmentEnd()
+{
+ // update existing fragment key with new stream position
+ ReplacePersistOffset( mnNextKey, mpOutStrm->Tell() );
+}
+
+sal_uInt32 XclEscherEx::GetDffFragmentPos( sal_uInt32 nFragmentKey )
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetPersistOffset( nFragmentKey );
+}
+
+sal_uInt32 XclEscherEx::GetDffFragmentSize( sal_uInt32 nFragmentKey )
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetDffFragmentPos( nFragmentKey + 1 ) - GetDffFragmentPos( nFragmentKey );
+}
+
+bool XclEscherEx::HasPendingDffData()
+{
+ /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
+ is non-const due to tools/List usage. */
+ return GetDffFragmentPos( mnNextKey ) < GetStreamPos();
+}
+
+XclExpDffAnchorBase* XclEscherEx::CreateDffAnchor( const SdrObject& rSdrObj ) const
+{
+ // the object manager creates the correct anchor type according to context
+ XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
+ // pass the drawing object, that will calculate the anchor position
+ pAnchor->SetSdrObject( rSdrObj );
+ return pAnchor;
+}
+
+namespace {
+
+bool lcl_IsFontwork( const SdrObject* pObj )
+{
+ bool bIsFontwork = false;
+ if( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE )
+ {
+ const OUString aTextPath = CREATE_OUSTRING( "TextPath" );
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)
+ pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ if( Any* pAny = rGeometryItem.GetPropertyValueByName( aTextPath, aTextPath ) )
+ *pAny >>= bIsFontwork;
+ }
+ return bIsFontwork;
+}
+
+} // namespace
+
+EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape, const Rectangle* pChildAnchor )
+{
+ if ( nAdditionalText )
+ nAdditionalText++;
+ sal_Bool bInGroup = ( pCurrXclObj != NULL );
+ if ( bInGroup )
+ { // stacked recursive group object
+ if ( !pCurrAppData->IsStackedGroup() )
+ { //! UpdateDffFragmentEnd only once
+ pCurrAppData->SetStackedGroup( sal_True );
+ UpdateDffFragmentEnd();
+ }
+ }
+ aStack.Push( pCurrXclObj );
+ aStack.Push( pCurrAppData );
+ pCurrAppData = new XclEscherHostAppData;
+ SdrObject* pObj = GetSdrObjectFromXShape( rxShape );
+ if ( !pObj )
+ pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just what is it?!?
+ else
+ {
+ pCurrXclObj = NULL;
+ sal_uInt16 nObjType = pObj->GetObjIdentifier();
+
+ if( nObjType == OBJ_OLE2 )
+ {
+ // no OLE objects in embedded drawings (chart shapes)
+ if( mbIsRootDff )
+ {
+ //! not-const because GetObjRef may load the OLE object
+ Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY );
+ if ( xObj.is() )
+ {
+ SvGlobalName aObjClsId( xObj->getClassID() );
+ if ( SotExchange::IsChart( aObjClsId ) )
+ { // yes, it's a chart diagram
+ mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) );
+ pCurrXclObj = NULL; // no metafile or whatsoever
+ }
+ else // metafile and OLE object
+ pCurrXclObj = new XclObjOle( mrObjMgr, *pObj );
+ }
+ else // just a metafile
+ pCurrXclObj = new XclObjAny( mrObjMgr, rxShape );
+ }
+ else
+ pCurrXclObj = new XclObjAny( mrObjMgr, rxShape );
+ }
+ else if( nObjType == OBJ_UNO )
+ {
+#if EXC_EXP_OCX_CTRL
+ // no ActiveX controls in embedded drawings (chart shapes)
+ if( mbIsRootDff )
+ pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor );
+#else
+ pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor );
+#endif
+ if( !pCurrXclObj )
+ pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just a metafile
+ }
+ else if( !ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ // ignore permanent note shapes
+ // #i12190# do not ignore callouts (do not filter by object type ID)
+ pCurrXclObj = ShapeInteractionHelper::CreateShapeObj( mrObjMgr, rxShape );
+ ShapeInteractionHelper::PopulateShapeInteractionInfo( mrObjMgr, rxShape, *pCurrAppData );
+ }
+ }
+ if ( pCurrXclObj )
+ {
+ if ( !mrObjMgr.AddObj( pCurrXclObj ) )
+ { // maximum count reached, object got deleted
+ pCurrXclObj = NULL;
+ }
+ else
+ {
+ pCurrAppData->SetClientData( pTheClientData );
+ if ( nAdditionalText == 0 )
+ {
+ if ( pObj )
+ {
+ if ( !bInGroup )
+ {
+ /* Create a dummy anchor carrying the flags. Real
+ coordinates are calculated later in virtual call of
+ WriteData(EscherEx&,const Rectangle&). */
+ XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
+ pAnchor->SetFlags( *pObj );
+ pCurrAppData->SetClientAnchor( pAnchor );
+ }
+ const SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pObj );
+ if( pTextObj && !lcl_IsFontwork( pTextObj ) && (pObj->GetObjIdentifier() != OBJ_CAPTION) )
+ {
+ const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
+ if( pParaObj )
+ pCurrAppData->SetClientTextbox(
+ new XclEscherClientTextbox( GetRoot(), *pTextObj, pCurrXclObj ) );
+ }
+ }
+ else
+ {
+ if ( !bInGroup )
+ pCurrAppData->SetClientAnchor( mrObjMgr.CreateDffAnchor() );
+ }
+ }
+ else if ( nAdditionalText == 3 )
+ {
+ if ( pAdditionalText )
+ {
+ pAdditionalText->SetXclObj( pCurrXclObj );
+ pCurrAppData->SetClientTextbox( pAdditionalText );
+ }
+ }
+ }
+ }
+ if ( !pCurrXclObj )
+ pCurrAppData->SetDontWriteShape( sal_True );
+ return pCurrAppData;
+}
+
+
+void XclEscherEx::EndShape( sal_uInt16 nShapeType, sal_uInt32 nShapeID )
+{
+ // own escher data created? -> never delete such objects
+ bool bOwnEscher = pCurrXclObj && pCurrXclObj->IsOwnEscher();
+
+ // post process the current object - not for objects with own escher data
+ if( pCurrXclObj && !bOwnEscher )
+ {
+ // escher data of last shape not written? -> delete it from object list
+ if( nShapeID == 0 )
+ {
+ XclObj* pLastObj = mrObjMgr.RemoveLastObj();
+ DBG_ASSERT( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" );
+ DELETEZ( pLastObj );
+ pCurrXclObj = 0;
+ }
+
+ if( pCurrXclObj )
+ {
+ // set shape type
+ if ( pCurrAppData->IsStackedGroup() )
+ pCurrXclObj->SetEscherShapeTypeGroup();
+ else
+ {
+ pCurrXclObj->SetEscherShapeType( nShapeType );
+ UpdateDffFragmentEnd();
+ }
+ }
+ }
+
+ // get next object from stack
+ DeleteCurrAppData();
+ pCurrAppData = static_cast< XclEscherHostAppData* >( aStack.Pop() );
+ pCurrXclObj = static_cast< XclObj* >( aStack.Pop() );
+ if( nAdditionalText == 3 )
+ nAdditionalText = 0;
+}
+
+
+EscherExHostAppData* XclEscherEx::EnterAdditionalTextGroup()
+{
+ nAdditionalText = 1;
+ pAdditionalText = (XclEscherClientTextbox*) pCurrAppData->GetClientTextbox();
+ pCurrAppData->SetClientTextbox( NULL );
+ return pCurrAppData;
+}
+
+void XclEscherEx::EndDocument()
+{
+ if( mbIsRootDff )
+ Flush( static_cast< XclEscherExGlobal& >( *mxGlobal ).GetPictureStream() );
+
+ // seek back DFF stream to prepare saving the MSODRAWING[GROUP] records
+ mpOutStrm->Seek( 0 );
+}
+
+#if EXC_EXP_OCX_CTRL
+
+XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
+{
+ ::std::auto_ptr< XclExpOcxControlObj > xOcxCtrl;
+
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ if( xCtrlModel.is() )
+ {
+ // output stream
+ if( !mxCtlsStrm.Is() )
+ mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
+ if( mxCtlsStrm.Is() )
+ {
+ String aClassName;
+ sal_uInt32 nStrmStart = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() );
+
+ // writes from xCtrlModel into mxCtlsStrm, raw class name returned in aClassName
+ if( SvxMSConvertOCXControls::WriteOCXExcelKludgeStream( mxCtlsStrm, xCtrlModel, xShape->getSize(), aClassName ) )
+ {
+ sal_uInt32 nStrmSize = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() - nStrmStart );
+ // adjust the class name to "Forms.***.1"
+ aClassName.InsertAscii( "Forms.", 0 ).AppendAscii( ".1" );
+ xOcxCtrl.reset( new XclExpOcxControlObj( mrObjMgr, xShape, pChildAnchor, aClassName, nStrmStart, nStrmSize ) );
+ }
+ }
+ }
+ return xOcxCtrl.release();
+}
+
+#else
+
+XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
+{
+ ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( mrObjMgr, xShape, pChildAnchor ) );
+ if( xTbxCtrl->GetObjType() == EXC_OBJTYPE_UNKNOWN )
+ xTbxCtrl.reset();
+
+ if( xTbxCtrl.get() )
+ {
+ // find attached macro
+ Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
+ ConvertTbxMacro( *xTbxCtrl, xCtrlModel );
+ }
+ return xTbxCtrl.release();
+}
+
+void XclEscherEx::ConvertTbxMacro( XclExpTbxControlObj& rTbxCtrlObj, Reference< XControlModel > xCtrlModel )
+{
+ SdrPage* pSdrPage = GetSdrPage( GetCurrScTab() );
+ if( xCtrlModel.is() && GetDocShell() && pSdrPage ) try
+ {
+ Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xFormsIA( xFormsSupplier->getForms(), UNO_QUERY_THROW );
+
+ // 1) try to find the index of the processed control in the form
+
+ Reference< XIndexAccess > xFormIA; // needed in step 2) below
+ sal_Int32 nFoundIdx = -1;
+
+ // search all existing forms in the draw page
+ for( sal_Int32 nFormIdx = 0, nFormCount = xFormsIA->getCount();
+ (nFoundIdx < 0) && (nFormIdx < nFormCount); ++nFormIdx )
+ {
+ // get the XIndexAccess interface of the form with index nFormIdx
+ if( xFormIA.set( xFormsIA->getByIndex( nFormIdx ), UNO_QUERY ) )
+ {
+ // search all elements (controls) of the current form by index
+ for( sal_Int32 nCtrlIdx = 0, nCtrlCount = xFormIA->getCount();
+ (nFoundIdx < 0) && (nCtrlIdx < nCtrlCount); ++nCtrlIdx )
+ {
+ // compare implementation pointers of the control models
+ Reference< XControlModel > xCurrModel( xFormIA->getByIndex( nCtrlIdx ), UNO_QUERY );
+ if( xCtrlModel.get() == xCurrModel.get() )
+ nFoundIdx = nCtrlIdx;
+ }
+ }
+ }
+
+ // 2) try to find an attached macro
+
+ if( xFormIA.is() && (nFoundIdx >= 0) )
+ {
+ Reference< XEventAttacherManager > xEventMgr( xFormIA, UNO_QUERY_THROW );
+ // loop over all events attached to the found control
+ const Sequence< ScriptEventDescriptor > aEventSeq( xEventMgr->getScriptEvents( nFoundIdx ) );
+ bool bFound = false;
+ for( sal_Int32 nEventIdx = 0, nEventCount = aEventSeq.getLength();
+ !bFound && (nEventIdx < nEventCount); ++nEventIdx )
+ {
+ // try to set the event data at the Excel control object, returns true on success
+ bFound = rTbxCtrlObj.SetMacroLink( aEventSeq[ nEventIdx ] );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+#endif
+
+void XclEscherEx::DeleteCurrAppData()
+{
+ if ( pCurrAppData )
+ {
+ delete pCurrAppData->GetClientAnchor();
+// delete pCurrAppData->GetClientData();
+ delete pCurrAppData->GetClientTextbox();
+ delete pCurrAppData->GetInteractionInfo();
+ delete pCurrAppData;
+ }
+}
+
+// ============================================================================
+
+// --- class XclEscherClientData -------------------------------------
+
+void XclEscherClientData::WriteData( EscherEx& rEx ) const
+{ // actual data is in the following OBJ record
+ rEx.AddAtom( 0, ESCHER_ClientData );
+}
+
+
+// --- class XclEscherClientTextbox -------------------------------------
+
+XclEscherClientTextbox::XclEscherClientTextbox( const XclExpRoot& rRoot,
+ const SdrTextObj& rObj, XclObj* pObj )
+ :
+ XclExpRoot( rRoot ),
+ rTextObj( rObj ),
+ pXclObj( pObj )
+{
+}
+
+
+void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const
+{
+ pXclObj->SetText( GetRoot(), rTextObj );
+}
+
+XclExpShapeObj*
+ShapeInteractionHelper::CreateShapeObj( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape )
+{
+ return new XclExpShapeObj( rObjMgr, xShape );
+}
+
+void
+ShapeInteractionHelper::PopulateShapeInteractionInfo( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape, EscherExHostAppData& rHostAppData )
+{
+ try
+ {
+ SvMemoryStream* pMemStrm = NULL;
+ rtl::OUString sHyperLink;
+ rtl::OUString sMacro;
+ if ( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( ::GetSdrObjectFromXShape( xShape ) ) )
+ {
+ sHyperLink = pInfo->GetHlink();
+ sMacro = pInfo->GetMacro();
+ }
+ if ( sHyperLink.getLength() > 0 )
+ {
+ pMemStrm = new SvMemoryStream();
+ XclExpStream tmpStream( *pMemStrm, rObjMgr.GetRoot() );
+ ScAddress dummyAddress;
+ SvxURLField aUrlField;
+ aUrlField.SetURL( sHyperLink );
+ XclExpHyperlink hExpHlink( rObjMgr.GetRoot(), aUrlField, dummyAddress );
+ hExpHlink.WriteEmbeddedData( tmpStream );
+ }
+ if ( ( sHyperLink.getLength() > 0 ) || ( sMacro.getLength() > 0 ) )
+ rHostAppData.SetInteractionInfo( new InteractionInfo( pMemStrm, true ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
new file mode 100644
index 000000000000..d26cc995b1d0
--- /dev/null
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -0,0 +1,1752 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdpool.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/editobj.hxx>
+#include <svx/svdoole2.hxx>
+#include <sot/storage.hxx>
+#include <svl/itemset.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/unoapi.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/math.hxx>
+#include <svl/zformat.hxx>
+#include "cell.hxx"
+#include "drwlayer.hxx"
+
+#include "xcl97rec.hxx"
+#include "xcl97esc.hxx"
+#include "editutil.hxx"
+#include "xecontent.hxx"
+#include "xeescher.hxx"
+#include "xestyle.hxx"
+#include "xelink.hxx"
+
+#include "scitems.hxx"
+
+#include <unotools/fltrcfg.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <filter/msfilter/msoleexp.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+
+#include <stdio.h>
+
+#include "document.hxx"
+#include "conditio.hxx"
+#include "rangelst.hxx"
+#include "stlpool.hxx"
+#include "viewopti.hxx"
+#include "scextopt.hxx"
+#include "docoptio.hxx"
+#include "patattr.hxx"
+#include "tabprotection.hxx"
+
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <oox/token/tokens.hxx>
+#include <oox/export/shapes.hxx>
+#include <oox/export/utils.hxx>
+#include <oox/export/vmlexport.hxx>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::oox::drawingml::DrawingML;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+using ::oox::drawingml::ShapeExport;
+using ::oox::vml::VMLExport;
+using namespace oox;
+
+// ============================================================================
+
+sal_Int32 XclExpObjList::mnDrawingMLCount;
+sal_Int32 XclExpObjList::mnVmlCount;
+
+XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
+ XclExpRoot( rRoot ),
+ mnScTab( rRoot.GetCurrScTab() ),
+ mrEscherEx( rEscherEx ),
+ pSolverContainer( 0 )
+{
+ pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
+ // open the DGCONTAINER and the patriarch group shape
+ mrEscherEx.OpenContainer( ESCHER_DgContainer );
+ Rectangle aRect( 0, 0, 0, 0 );
+ mrEscherEx.EnterGroup( &aRect );
+ mrEscherEx.UpdateDffFragmentEnd();
+}
+
+XclExpObjList::~XclExpObjList()
+{
+ for ( XclObj* p = First(); p; p = Next() )
+ delete p;
+ delete pMsodrawingPerSheet;
+ delete pSolverContainer;
+}
+
+sal_uInt16 XclExpObjList::Add( XclObj* pObj )
+{
+ DBG_ASSERT( Count() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
+ if ( Count() < 0xFFFF )
+ {
+ Insert( pObj, LIST_APPEND );
+ sal_uInt16 nCnt = (sal_uInt16) Count();
+ pObj->SetId( nCnt );
+ pObj->SetTab( mnScTab );
+ return nCnt;
+ }
+ else
+ {
+ delete pObj;
+ return 0;
+ }
+}
+
+void XclExpObjList::EndSheet()
+{
+ // Is there still something in the stream? -> The solver container
+ if( mrEscherEx.HasPendingDffData() )
+ pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
+
+ // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
+ mrEscherEx.CloseContainer();
+}
+
+void XclExpObjList::Save( XclExpStream& rStrm )
+{
+ //! Escher must be written, even if there are no objects
+ pMsodrawingPerSheet->Save( rStrm );
+
+ for ( XclObj* p = First(); p; p = Next() )
+ p->Save( rStrm );
+
+ if( pSolverContainer )
+ pSolverContainer->Save( rStrm );
+}
+
+static bool IsVmlObject( const XclObj& rObj )
+{
+ switch( rObj.GetObjType() )
+ {
+ case EXC_OBJTYPE_NOTE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+static sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
+{
+ sal_Int32 nNumVml = 0;
+
+ for ( XclObj* p = rList.First(); p; p = rList.Next() )
+ if( IsVmlObject( *p ) )
+ ++nNumVml;
+
+ return nNumVml;
+}
+
+
+static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nDrawingMLCount )
+{
+ sal_Int32 nVmlObjects = GetVmlObjectCount( rList );
+ if( (rList.Count() - nVmlObjects) == 0 )
+ return;
+
+ sal_Int32 nDrawing = ++nDrawingMLCount;
+ OUString sId;
+ sax_fastparser::FSHelperPtr pDrawing = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "drawings/drawing", nDrawing ),
+ XclXmlUtils::GetStreamName( "../", "drawings/drawing", nDrawing ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.drawing+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
+ &sId );
+
+ rStrm.GetCurrentStream()->singleElement( XML_drawing,
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+
+ rStrm.PushStream( pDrawing );
+ pDrawing->startElement( FSNS( XML_xdr, XML_wsDr ),
+ FSNS( XML_xmlns, XML_xdr ), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
+ FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
+ FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+ FSEND );
+
+ for ( XclObj* p = rList.First(); p; p = rList.Next() )
+ {
+ if( IsVmlObject( *p ) )
+ continue;
+ p->SaveXml( rStrm );
+ }
+
+ pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
+
+ rStrm.PopStream();
+}
+
+
+static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nVmlCount )
+{
+ if( GetVmlObjectCount( rList ) == 0 )
+ return;
+
+ sal_Int32 nDrawing = ++nVmlCount;
+ OUString sId;
+ sax_fastparser::FSHelperPtr pVmlDrawing = rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "drawings/vmlDrawing", nDrawing ),
+ XclXmlUtils::GetStreamName( "../", "drawings/vmlDrawing", nDrawing ),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.vmlDrawing",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
+ &sId );
+
+ rStrm.GetCurrentStream()->singleElement( XML_legacyDrawing,
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+
+ rStrm.PushStream( pVmlDrawing );
+ pVmlDrawing->startElement( XML_xml,
+ FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml",
+ FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office",
+ FSNS( XML_xmlns, XML_x ), "urn:schemas-microsoft-com:office:excel",
+ FSEND );
+
+ for ( XclObj* p = rList.First(); p; p = rList.Next() )
+ {
+ if( !IsVmlObject( *p ) )
+ continue;
+ p->SaveXml( rStrm );
+ }
+
+ pVmlDrawing->endElement( XML_xml );
+
+ rStrm.PopStream();
+}
+
+
+void XclExpObjList::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( pSolverContainer )
+ pSolverContainer->SaveXml( rStrm );
+
+ if( Count() == 0 )
+ return;
+
+ SaveDrawingMLObjects( *this, rStrm, mnDrawingMLCount );
+ SaveVmlObjects( *this, rStrm, mnVmlCount );
+}
+
+
+void XclExpObjList::ResetCounters()
+{
+ mnDrawingMLCount = 0;
+ mnVmlCount = 0;
+}
+
+// --- class XclObj --------------------------------------------------
+
+XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) :
+ XclExpRecord( EXC_ID_OBJ, 26 ),
+ mrEscherEx( rObjMgr.GetEscherEx() ),
+ pClientTextbox( NULL ),
+ pTxo( NULL ),
+ mnObjType( nObjType ),
+ nObjId(0),
+ nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
+ bFirstOnSheet( !rObjMgr.HasObj() ),
+ mbOwnEscher( bOwnEscher )
+{
+ //! first object continues the first MSODRAWING record
+ if ( bFirstOnSheet )
+ pMsodrawing = rObjMgr.GetMsodrawingPerSheet();
+ else
+ pMsodrawing = new XclExpMsoDrawing( mrEscherEx );
+}
+
+XclObj::~XclObj()
+{
+ if ( !bFirstOnSheet )
+ delete pMsodrawing;
+ delete pClientTextbox;
+ delete pTxo;
+}
+
+void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor )
+{
+ if( pChildAnchor )
+ {
+ mrEscherEx.AddChildAnchor( *pChildAnchor );
+ }
+ else if( pSdrObj )
+ {
+ ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) );
+ xDffAnchor->WriteDffData( mrEscherEx );
+ }
+}
+
+void XclObj::SetEscherShapeType( sal_uInt16 nType )
+{
+//2do: what about the other defined ot... types?
+ switch ( nType )
+ {
+ case ESCHER_ShpInst_Line :
+ mnObjType = EXC_OBJTYPE_LINE;
+ break;
+ case ESCHER_ShpInst_Rectangle :
+ case ESCHER_ShpInst_RoundRectangle :
+ mnObjType = EXC_OBJTYPE_RECTANGLE;
+ break;
+ case ESCHER_ShpInst_Ellipse :
+ mnObjType = EXC_OBJTYPE_OVAL;
+ break;
+ case ESCHER_ShpInst_Arc :
+ mnObjType = EXC_OBJTYPE_ARC;
+ break;
+ case ESCHER_ShpInst_TextBox :
+ mnObjType = EXC_OBJTYPE_TEXT;
+ break;
+ case ESCHER_ShpInst_PictureFrame :
+ mnObjType = EXC_OBJTYPE_PICTURE;
+ break;
+ default:
+ mnObjType = EXC_OBJTYPE_DRAWING;
+ }
+}
+
+void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
+{
+ DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" );
+ if ( !pClientTextbox )
+ {
+ mrEscherEx.UpdateDffFragmentEnd();
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+ pTxo = new XclTxo( rRoot, rObj );
+ }
+}
+
+void XclObj::WriteBody( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
+
+ // create a substream to be able to create subrecords
+ SvMemoryStream aMemStrm;
+ ::std::auto_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
+
+ // write the ftCmo subrecord
+ pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
+ *pXclStrm << mnObjType << nObjId << nGrbit;
+ pXclStrm->WriteZeroBytes( 12 );
+ pXclStrm->EndRecord();
+
+ // write other subrecords
+ WriteSubRecs( *pXclStrm );
+
+ // write the ftEnd subrecord
+ pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
+ pXclStrm->EndRecord();
+
+ // copy the data to the OBJ record
+ pXclStrm.reset();
+ aMemStrm.Seek( 0 );
+ rStrm.CopyFromStream( aMemStrm );
+}
+
+void XclObj::Save( XclExpStream& rStrm )
+{
+ // MSODRAWING record (msofbtSpContainer)
+ if ( !bFirstOnSheet )
+ pMsodrawing->Save( rStrm );
+
+ // OBJ
+ XclExpRecord::Save( rStrm );
+
+ // second MSODRAWING record and TXO and CONTINUE records
+ SaveTextRecs( rStrm );
+}
+
+void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
+{
+}
+
+void XclObj::SaveTextRecs( XclExpStream& rStrm )
+{
+ // MSODRAWING record (msofbtClientTextbox)
+ if ( pClientTextbox )
+ pClientTextbox->Save( rStrm );
+ // TXO and CONTINUE records
+ if ( pTxo )
+ pTxo->Save( rStrm );
+}
+
+ // --- class XclObjComment ------------------------------------------
+
+XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrCaptionObj* pCaption, bool bVisible, const ScAddress& rAddress, Rectangle &rFrom, Rectangle &rTo ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true )
+ , maScPos( rAddress )
+ , mpCaption( static_cast< SdrCaptionObj* >( pCaption->Clone() ) )
+ , mbVisible( bVisible )
+ , maFrom ( rFrom )
+ , maTo ( rTo )
+{
+ ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible);
+ // TXO
+ pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption );
+}
+
+static void lcl_FillProps( EscherPropertyContainer& rPropOpt, SdrObject* pCaption, bool bVisible )
+{
+ if( pCaption )
+ {
+ Reference< XShape > aXShape = GetXShapeForSdrObject( pCaption );
+ Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
+ if( aXPropSet.is() )
+ {
+ rPropOpt.CreateFillProperties( aXPropSet, sal_True);
+
+ rPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
+ rPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
+
+ sal_uInt32 nValue = 0;
+ if( !rPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ) )
+ rPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+
+ if( rPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ) )
+ {
+ // If the Colour is the same as the 'ToolTip' System colour then
+ // use the default rather than the explicit colour value. This will
+ // be incorrect where user has chosen to use this colour explicity.
+ Color aColor = Color( (sal_uInt8)nValue, (sal_uInt8)( nValue >> 8 ), (sal_uInt8)( nValue >> 16 ) );
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+ if( aColor == rSett.GetHelpColor().GetColor() )
+ {
+ rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
+ rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
+ }
+ }
+ else
+ rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
+
+ if( !rPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
+ rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
+ if( !rPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) )
+ rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
+ if( !rPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ) )
+ rPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
+ if( !rPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue ) ) // bool field
+ rPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
+ }
+ }
+
+ sal_uInt32 nFlags = 0x000A0000;
+ ::set_flag( nFlags, sal_uInt32(2), !bVisible );
+ rPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
+}
+
+void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
+{
+ EscherPropertyContainer aPropOpt;
+
+
+ lcl_FillProps( aPropOpt, pCaption, bVisible );
+
+ nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+
+ //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
+ //! base OBJ's MSODRAWING record Escher data is completed.
+ pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
+ mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
+ mrEscherEx.UpdateDffFragmentEnd();
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+}
+
+XclObjComment::~XclObjComment()
+{
+}
+
+void XclObjComment::Save( XclExpStream& rStrm )
+{
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+class VmlCommentExporter : public VMLExport
+{
+ ScAddress maScPos;
+ SdrCaptionObj* mpCaption;
+ bool mbVisible;
+ Rectangle maFrom;
+ Rectangle maTo;
+
+public:
+ VmlCommentExporter ( sax_fastparser::FSHelperPtr p, ScAddress aScPos, SdrCaptionObj* pCaption, bool bVisible, Rectangle &aFrom, Rectangle &aTo );
+protected:
+ virtual void Commit( EscherPropertyContainer& rProps, const Rectangle& rRect );
+ using VMLExport::StartShape;
+ virtual sal_Int32 StartShape();
+ using VMLExport::EndShape;
+ virtual void EndShape( sal_Int32 nShapeElement );
+};
+
+
+VmlCommentExporter::VmlCommentExporter( sax_fastparser::FSHelperPtr p, ScAddress aScPos, SdrCaptionObj* pCaption,
+ bool bVisible, Rectangle &aFrom, Rectangle &aTo )
+ : VMLExport( p )
+ , maScPos( aScPos )
+ , mpCaption( pCaption )
+ , mbVisible( bVisible )
+ , maFrom ( aFrom )
+ , maTo ( aTo )
+{
+}
+
+void VmlCommentExporter::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
+{
+ lcl_FillProps( rProps, mpCaption, mbVisible );
+ rProps.AddOpt( ESCHER_Prop_fHidden, 1 ); // bool field
+
+ VMLExport::Commit( rProps, rRect );
+}
+
+sal_Int32 VmlCommentExporter::StartShape()
+{
+ AddShapeAttribute( XML_type, OString( "#_x0000_t202") );
+
+ sal_Int32 nId = VMLExport::StartShape();
+
+ return nId;
+}
+
+void VmlCommentExporter::EndShape( sal_Int32 nShapeElement )
+{
+ char pAnchor[100];
+ sax_fastparser::FSHelperPtr pVmlDrawing = GetFS();
+ snprintf( pAnchor, 100, "%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld",
+ maFrom.Left(), maFrom.Top(), maFrom.Right(), maFrom.Bottom(),
+ maTo.Left(), maTo.Top(), maTo.Right(), maTo.Bottom() );
+
+ pVmlDrawing->startElement( FSNS( XML_x, XML_ClientData ),
+ XML_ObjectType, "Note",
+ FSEND );
+ pVmlDrawing->singleElement( FSNS( XML_x, XML_MoveWithCells ),
+ FSEND );
+ pVmlDrawing->singleElement( FSNS( XML_x, XML_SizeWithCells ),
+ FSEND );
+ XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Anchor ), pAnchor );
+ XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_AutoFill ), "False" );
+ XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Row ), maScPos.Row() );
+ XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Column ), sal_Int32( maScPos.Col() ) );
+ pVmlDrawing->endElement( FSNS( XML_x, XML_ClientData ) );
+
+ VMLExport::EndShape( nShapeElement );
+}
+
+void XclObjComment::SaveXml( XclExpXmlStream& rStrm )
+{
+ VmlCommentExporter aCommentExporter( rStrm.GetCurrentStream(), maScPos, mpCaption.get(), mbVisible, maFrom, maTo );
+ aCommentExporter.AddSdrObject( *mpCaption );
+}
+
+
+// --- class XclObjDropDown ------------------------------------------
+
+XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, sal_Bool bFilt ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ),
+ bIsFiltered( bFilt )
+{
+ SetLocked( sal_True );
+ SetPrintable( false );
+ SetAutoFill( sal_True );
+ SetAutoLine( false );
+ nGrbit |= 0x0100; // undocumented
+ mrEscherEx.OpenContainer( ESCHER_SpContainer );
+ mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
+ EscherPropertyContainer aPropOpt;
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
+ aPropOpt.Commit( mrEscherEx.GetStream() );
+
+ XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx );
+
+ mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
+ mrEscherEx.UpdateDffFragmentEnd();
+ mrEscherEx.CloseContainer(); // ESCHER_SpContainer
+
+ // old size + ftSbs + ftLbsData
+ AddRecSize( 24 + 20 );
+}
+
+XclObjDropDown::~XclObjDropDown()
+{
+}
+
+void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
+{
+ // ftSbs subrecord - Scroll bars (dummy)
+ rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
+ rStrm.WriteZeroBytes( 20 );
+ rStrm.EndRecord();
+
+ // ftLbsData subrecord - Listbox data
+ sal_uInt16 nDropDownFlags = 0;
+ ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
+ ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
+ rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
+ rStrm << (sal_uInt32)0 << (sal_uInt16)0 << (sal_uInt16)0x0301 << (sal_uInt16)0
+ << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
+ rStrm.EndRecord();
+}
+
+// --- class XclTxo --------------------------------------------------
+
+sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
+{
+ sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
+
+ switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
+ {
+ case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
+ case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
+ case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
+ case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
+ default:;
+ }
+ return nHorAlign;
+}
+
+sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
+{
+ sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
+
+ switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
+ {
+ case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
+ case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
+ case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
+ case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
+ }
+ return nVerAlign;
+}
+
+XclTxo::XclTxo( const String& rString, sal_uInt16 nFontIx ) :
+ mpString( new XclExpString( rString ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ if( mpString->Len() )
+ {
+ // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
+ mpString->AppendFormat( 0, nFontIx );
+ mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
+ }
+}
+
+XclTxo::XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rTextObj ) :
+ mpString( XclExpStringHelper::CreateString( rRoot, rTextObj ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ // additional alignment and orientation items
+ const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
+
+ // horizontal alignment
+ SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
+
+ // vertical alignment
+ SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
+
+ // rotation
+ long nAngle = rTextObj.GetRotateAngle();
+ if( (4500 < nAngle) && (nAngle < 13500) )
+ mnRotation = EXC_OBJ_ORIENT_90CCW;
+ else if( (22500 < nAngle) && (nAngle < 31500) )
+ mnRotation = EXC_OBJ_ORIENT_90CW;
+ else
+ mnRotation = EXC_OBJ_ORIENT_NONE;
+}
+
+XclTxo::XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption ) :
+ mpString( XclExpStringHelper::CreateString( rRoot, rEditObj ) ),
+ mnRotation( EXC_OBJ_ORIENT_NONE ),
+ mnHorAlign( EXC_OBJ_HOR_LEFT ),
+ mnVerAlign( EXC_OBJ_VER_TOP )
+{
+ if(pCaption)
+ {
+ // Excel has one alignment per NoteObject while Calc supports
+ // one alignment per paragraph - use the first paragraph
+ // alignment (if set) as our overall alignment.
+ String aParaText( rEditObj.GetText( 0 ) );
+ if( aParaText.Len() )
+ {
+ SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
+ const SfxPoolItem* pItem = NULL;
+ if( aSet.GetItemState( EE_PARA_JUST, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
+ pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
+ }
+ }
+ const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
+
+ // horizontal alignment
+ SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
+
+ // vertical alignment
+ SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
+
+ // orientation alignment
+ const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
+ if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
+ mnRotation = EXC_OBJ_ORIENT_90CW;
+ }
+}
+
+void XclTxo::SaveCont( XclExpStream& rStrm )
+{
+ DBG_ASSERT( mpString.get(), "XclTxo::SaveCont - missing string" );
+
+ // #i96858# do not save existing string formatting if text is empty
+ sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
+ // alignment
+ sal_uInt16 nFlags = 0;
+ ::insert_value( nFlags, mnHorAlign, 1, 3 );
+ ::insert_value( nFlags, mnVerAlign, 4, 3 );
+
+ rStrm << nFlags << mnRotation;
+ rStrm.WriteZeroBytes( 6 );
+ rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
+}
+
+void XclTxo::Save( XclExpStream& rStrm )
+{
+ // Write the TXO part
+ ExcRecord::Save( rStrm );
+
+ // CONTINUE records are only written if there is some text
+ if( !mpString->IsEmpty() )
+ {
+ // CONTINUE for character array
+ rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
+ rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
+ mpString->WriteBuffer( rStrm );
+ rStrm.EndRecord();
+
+ // CONTINUE for formatting runs
+ rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
+ const XclFormatRunVec& rFormats = mpString->GetFormats();
+ for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
+ rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
+ rStrm.EndRecord();
+ }
+}
+
+sal_uInt16 XclTxo::GetNum() const
+{
+ return EXC_ID_TXO;
+}
+
+sal_Size XclTxo::GetLen() const
+{
+ return 18;
+}
+
+// --- class XclObjOle -------------------------------------------
+
+XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) :
+ XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ),
+ rOleObj( rObj ),
+ pRootStorage( rObjMgr.GetRoot().GetRootStorage() )
+{
+}
+
+XclObjOle::~XclObjOle()
+{
+}
+
+void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
+{
+ // write only as embedded, not linked
+ String aStorageName( RTL_CONSTASCII_USTRINGPARAM( "MBD" ) );
+ sal_Char aBuf[ sizeof(sal_uInt32) * 2 + 1 ];
+ // FIXME Eeek! Is this just a way to get a unique id?
+ sal_uInt32 nPictureId = sal_uInt32(sal_uIntPtr(this) >> 2);
+ sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) );
+ aStorageName.AppendAscii( aBuf );
+ SotStorageRef xOleStg = pRootStorage->OpenSotStorage( aStorageName,
+ STREAM_READWRITE| STREAM_SHARE_DENYALL );
+ if( xOleStg.Is() )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj&)rOleObj).GetObjRef() );
+ if ( xObj.is() )
+ {
+ // set version to "old" version, because it must be
+ // saved in MS notation.
+ sal_uInt32 nFl = 0;
+ SvtFilterOptions* pFltOpts = SvtFilterOptions::Get();
+ if( pFltOpts )
+ {
+ if( pFltOpts->IsMath2MathType() )
+ nFl |= OLE_STARMATH_2_MATHTYPE;
+
+ if( pFltOpts->IsWriter2WinWord() )
+ nFl |= OLE_STARWRITER_2_WINWORD;
+
+ if( pFltOpts->IsCalc2Excel() )
+ nFl |= OLE_STARCALC_2_EXCEL;
+
+ if( pFltOpts->IsImpress2PowerPoint() )
+ nFl |= OLE_STARIMPRESS_2_POWERPOINT;
+ }
+
+ SvxMSExportOLEObjects aOLEExpFilt( nFl );
+ aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
+
+ // OBJCF subrecord, undocumented as usual
+ rStrm.StartRecord( EXC_ID_OBJCF, 2 );
+ rStrm << sal_uInt16(0x0002);
+ rStrm.EndRecord();
+
+ // OBJFLAGS subrecord, undocumented as usual
+ rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
+ sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
+ ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, ((SdrOle2Obj&)rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
+ rStrm << nFlags;
+ rStrm.EndRecord();
+
+ // OBJPICTFMLA subrecord, undocumented as usual
+ XclExpString aName( xOleStg->GetUserName() );
+ sal_uInt16 nPadLen = (sal_uInt16)(aName.GetSize() & 0x01);
+ sal_uInt16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
+ sal_uInt16 nSubRecLen = nFmlaLen + 6;
+
+ rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
+ rStrm << nFmlaLen
+ << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
+ << sal_uInt32( 0 ) << sal_uInt8( 3 )
+ << aName;
+ if( nPadLen )
+ rStrm << sal_uInt8( 0 ); // pad byte
+ rStrm << nPictureId;
+ rStrm.EndRecord();
+ }
+ }
+}
+
+void XclObjOle::Save( XclExpStream& rStrm )
+{
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+// --- class XclObjAny -------------------------------------------
+
+XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr, const Reference< XShape >& rShape )
+ : XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
+ , mxShape( rShape )
+{
+}
+
+XclObjAny::~XclObjAny()
+{
+}
+
+void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
+{
+ if( mnObjType == EXC_OBJTYPE_GROUP )
+ // ftGmo subrecord
+ rStrm << EXC_ID_OBJGMO << sal_uInt16(2) << sal_uInt16(0);
+}
+
+void XclObjAny::Save( XclExpStream& rStrm )
+{
+ if( mnObjType == EXC_OBJTYPE_GROUP )
+ // old size + ftGmo
+ AddRecSize( 6 );
+
+ // content of this record
+ XclObj::Save( rStrm );
+}
+
+// --- class ExcBof8_Base --------------------------------------------
+
+ExcBof8_Base::ExcBof8_Base()
+{
+ nVers = 0x0600;
+ nRupBuild = 0x0dbb;
+ nRupYear = 0x07cc;
+// nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
+ nFileHistory = 0x00000000;
+ nLowestBiffVer = 0x00000006; // Biff8
+}
+void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const Reference< XShape >& rShape, SCTAB nTab )
+{
+ sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
+
+ awt::Point aTopLeft = rShape->getPosition();
+ awt::Size aSize = rShape->getSize();
+ Rectangle aLocation( aTopLeft.X, aTopLeft.Y, aTopLeft.X + aSize.Width, aTopLeft.Y + aSize.Height );
+ ScRange aRange = rStrm.GetRoot().GetDoc().GetRange( nTab, aLocation );
+ Rectangle aRangeRect = rStrm.GetRoot().GetDoc().GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col()-1, aRange.aEnd.Row()-1,
+ nTab );
+
+
+ pDrawing->startElement( FSNS( XML_xdr, XML_from ),
+ FSEND );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aStart.Col() );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
+ MM100toEMU( aLocation.Left() - aRangeRect.Left() ) );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aStart.Row() );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
+ MM100toEMU( aLocation.Top() - aRangeRect.Top() ) );
+ pDrawing->endElement( FSNS( XML_xdr, XML_from ) );
+
+ pDrawing->startElement( FSNS( XML_xdr, XML_to ),
+ FSEND );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aEnd.Col() );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
+ MM100toEMU( aLocation.Right() - aRangeRect.Right() ) );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aEnd.Row() );
+ XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
+ MM100toEMU( aLocation.Bottom() - aRangeRect.Bottom() ) );
+ pDrawing->endElement( FSNS( XML_xdr, XML_to ) );
+}
+
+void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
+{
+ WriteFromTo( rStrm, rObj.GetShape(), rObj.GetTab() );
+}
+
+static const char*
+GetEditAs( XclObjAny& rObj )
+{
+ if( const SdrObject* pShape = EscherEx::GetSdrObject( rObj.GetShape() ) )
+ {
+ // OOXTODO: returning "twoCell"
+ switch( ScDrawLayer::GetAnchorType( *pShape ) )
+ {
+ case SCA_CELL: return "oneCell";
+ default: break;
+ }
+ }
+ return "absolute";
+}
+
+
+void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( !mxShape.is() )
+ return;
+
+ sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
+
+ ShapeExport aDML( XML_xdr, pDrawing, NULL, &rStrm, DrawingML::DOCUMENT_XLSX );
+
+ pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
+ XML_editAs, GetEditAs( *this ),
+ FSEND );
+ Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
+ if (xPropSet.is())
+ {
+ WriteFromTo( rStrm, *this );
+ aDML.WriteShape( mxShape );
+ }
+
+ pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
+ // OOXTODO: XML_fLocksWithSheet
+ // OOXTODO: XML_fPrintsWithSheet
+ FSEND );
+ pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
+}
+
+
+
+void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
+{
+ rStrm.DisableEncryption();
+ rStrm << nVers << nDocType << nRupBuild << nRupYear
+ << nFileHistory << nLowestBiffVer;
+}
+
+
+sal_uInt16 ExcBof8_Base::GetNum() const
+{
+ return 0x0809;
+}
+
+
+sal_Size ExcBof8_Base::GetLen() const
+{
+ return 16;
+}
+
+
+// --- class ExcBof8 -------------------------------------------------
+
+ExcBof8::ExcBof8()
+{
+ nDocType = 0x0010;
+}
+
+
+// --- class ExcBofW8 ------------------------------------------------
+
+ExcBofW8::ExcBofW8()
+{
+ nDocType = 0x0005;
+}
+
+
+// --- class ExcBundlesheet8 -----------------------------------------
+
+ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
+ ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
+ sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
+{
+}
+
+
+ExcBundlesheet8::ExcBundlesheet8( const String& rString ) :
+ ExcBundlesheetBase(),
+ sUnicodeName( rString )
+{
+}
+
+
+XclExpString ExcBundlesheet8::GetName() const
+{
+ return XclExpString( sUnicodeName, EXC_STR_8BITLENGTH );
+}
+
+
+void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
+{
+ nOwnPos = rStrm.GetSvStreamPos();
+ // write dummy position, real position comes later
+ rStrm.DisableEncryption();
+ rStrm << sal_uInt32(0);
+ rStrm.EnableEncryption();
+ rStrm << nGrbit << GetName();
+}
+
+
+sal_Size ExcBundlesheet8::GetLen() const
+{ // Text max 255 chars
+ return 8 + GetName().GetBufferSize();
+}
+
+
+void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
+{
+ OUString sId;
+ rStrm.CreateOutputStream(
+ XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
+ XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
+ rStrm.GetCurrentStream()->getOutputStream(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
+ &sId );
+
+ rStrm.GetCurrentStream()->singleElement( XML_sheet,
+ XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
+ XML_sheetId, rtl::OString::valueOf( (sal_Int32)( nTab+1 ) ).getStr(),
+ XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
+ FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
+ FSEND );
+}
+
+
+
+// --- class XclObproj -----------------------------------------------
+
+sal_uInt16 XclObproj::GetNum() const
+{
+ return 0x00D3;
+}
+
+
+sal_Size XclObproj::GetLen() const
+{
+ return 0;
+}
+
+
+// ---- class XclCodename --------------------------------------------
+
+XclCodename::XclCodename( const String& r ) : aName( r )
+{
+}
+
+
+void XclCodename::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << aName;
+}
+
+
+sal_uInt16 XclCodename::GetNum() const
+{
+ return 0x01BA;
+}
+
+
+sal_Size XclCodename::GetLen() const
+{
+ return aName.GetSize();
+}
+
+
+
+// ---- Scenarios ----------------------------------------------------
+
+ExcEScenarioCell::ExcEScenarioCell( sal_uInt16 nC, sal_uInt16 nR, const String& rTxt ) :
+ nCol( nC ),
+ nRow( nR ),
+ sText( rTxt, EXC_STR_DEFAULT, 255 )
+{
+}
+
+void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm )
+{
+ rStrm << nRow << nCol;
+}
+
+void ExcEScenarioCell::WriteText( XclExpStream& rStrm )
+{
+ rStrm << sText;
+}
+
+void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.GetCurrentStream()->singleElement( XML_inputCells,
+ // OOXTODO: XML_deleted,
+ // OOXTODO: XML_numFmtId,
+ XML_r, XclXmlUtils::ToOString( ScAddress( nCol, nRow, 0 ) ).getStr(),
+ // OOXTODO: XML_undone,
+ XML_val, XclXmlUtils::ToOString( sText ).getStr(),
+ FSEND );
+}
+
+
+
+
+ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab )
+{
+ String sTmpName;
+ String sTmpComm;
+ Color aDummyCol;
+ sal_uInt16 nFlags;
+
+ ScDocument& rDoc = rRoot.GetDoc();
+ rDoc.GetName( nTab, sTmpName );
+ sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
+ nRecLen = 8 + sName.GetBufferSize();
+
+ rDoc.GetScenarioData( nTab, sTmpComm, aDummyCol, nFlags );
+ sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
+ if( sComment.Len() )
+ nRecLen += sComment.GetSize();
+ nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0;
+
+ sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 );
+ nRecLen += sUserName.GetSize();
+
+ const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
+ if( !pRList )
+ return;
+
+ sal_Bool bContLoop = sal_True;
+ SCROW nRow;
+ SCCOL nCol;
+ String sText;
+ double fVal;
+
+ for( size_t nRange = 0; (nRange < pRList->size()) && bContLoop; nRange++ )
+ {
+ const ScRange* pRange = (*pRList)[nRange];
+ for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
+ for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
+ {
+ if( rDoc.HasValueData( nCol, nRow, nTab ) )
+ {
+ rDoc.GetValue( nCol, nRow, nTab, fVal );
+ sText = ::rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0),
+ sal_True );
+ }
+ else
+ rDoc.GetString( nCol, nRow, nTab, sText );
+ bContLoop = Append( static_cast<sal_uInt16>(nCol),
+ static_cast<sal_uInt16>(nRow), sText );
+ }
+ }
+}
+
+ExcEScenario::~ExcEScenario()
+{
+ for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
+ delete pCell;
+}
+
+sal_Bool ExcEScenario::Append( sal_uInt16 nCol, sal_uInt16 nRow, const String& rTxt )
+{
+ if( List::Count() == EXC_SCEN_MAXCELL )
+ return false;
+
+ ExcEScenarioCell* pCell = new ExcEScenarioCell( nCol, nRow, rTxt );
+ List::Insert( pCell, LIST_APPEND );
+ nRecLen += 6 + pCell->GetStringBytes(); // 4 bytes address, 2 bytes ifmt
+ return sal_True;
+}
+
+void ExcEScenario::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) List::Count() // number of cells
+ << nProtected // fProtection
+ << (sal_uInt8) 0 // fHidden
+ << (sal_uInt8) sName.Len() // length of scen name
+ << (sal_uInt8) sComment.Len() // length of comment
+ << (sal_uInt8) sUserName.Len(); // length of user name
+ sName.WriteFlagField( rStrm );
+ sName.WriteBuffer( rStrm );
+
+ rStrm << sUserName;
+
+ if( sComment.Len() )
+ rStrm << sComment;
+
+ ExcEScenarioCell* pCell;
+ for( pCell = _First(); pCell; pCell = _Next() )
+ pCell->WriteAddress( rStrm ); // pos of cell
+ for( pCell = _First(); pCell; pCell = _Next() )
+ pCell->WriteText( rStrm ); // string content
+ rStrm.SetSliceSize( 2 );
+ rStrm.WriteZeroBytes( 2 * List::Count() ); // date format
+}
+
+sal_uInt16 ExcEScenario::GetNum() const
+{
+ return 0x00AF;
+}
+
+sal_Size ExcEScenario::GetLen() const
+{
+ return nRecLen;
+}
+
+void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
+{
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_scenario,
+ XML_name, XclXmlUtils::ToOString( sName ).getStr(),
+ XML_locked, XclXmlUtils::ToPsz( nProtected ),
+ // OOXTODO: XML_hidden,
+ XML_count, OString::valueOf( (sal_Int32) List::Count() ).getStr(),
+ XML_user, XESTRING_TO_PSZ( sUserName ),
+ XML_comment, XESTRING_TO_PSZ( sComment ),
+ FSEND );
+
+ for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
+ pCell->SaveXml( rStrm );
+
+ rWorkbook->endElement( XML_scenario );
+}
+
+
+
+
+ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) :
+ nActive( 0 )
+{
+ ScDocument& rDoc = rRoot.GetDoc();
+ if( rDoc.IsScenario( nTab ) )
+ return;
+
+ SCTAB nFirstTab = nTab + 1;
+ SCTAB nNewTab = nFirstTab;
+
+ while( rDoc.IsScenario( nNewTab ) )
+ {
+ Append( new ExcEScenario( rRoot, nNewTab ) );
+
+ if( rDoc.IsActiveScenario( nNewTab ) )
+ nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
+ nNewTab++;
+ }
+}
+
+ExcEScenarioManager::~ExcEScenarioManager()
+{
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ delete pScen;
+}
+
+void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << (sal_uInt16) List::Count() // number of scenarios
+ << nActive // active scen
+ << nActive // last displayed
+ << (sal_uInt16) 0; // reference areas
+}
+
+void ExcEScenarioManager::Save( XclExpStream& rStrm )
+{
+ if( List::Count() )
+ ExcRecord::Save( rStrm );
+
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ pScen->Save( rStrm );
+}
+
+void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
+{
+ if( ! List::Count() )
+ return;
+
+ sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
+ rWorkbook->startElement( XML_scenarios,
+ XML_current, OString::valueOf( (sal_Int32)nActive ).getStr(),
+ XML_show, OString::valueOf( (sal_Int32)nActive ).getStr(),
+ // OOXTODO: XML_sqref,
+ FSEND );
+
+ for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
+ pScen->SaveXml( rStrm );
+
+ rWorkbook->endElement( XML_scenarios );
+}
+
+sal_uInt16 ExcEScenarioManager::GetNum() const
+{
+ return 0x00AE;
+}
+
+sal_Size ExcEScenarioManager::GetLen() const
+{
+ return 8;
+}
+
+// ============================================================================
+
+struct XclExpTabProtectOption
+{
+ ScTableProtection::Option eOption;
+ sal_uInt16 nMask;
+};
+
+XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRecord( 0x0867, 23 )
+{
+ static const XclExpTabProtectOption aTable[] =
+ {
+ { ScTableProtection::OBJECTS, 0x0001 },
+ { ScTableProtection::SCENARIOS, 0x0002 },
+ { ScTableProtection::FORMAT_CELLS, 0x0004 },
+ { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
+ { ScTableProtection::FORMAT_ROWS, 0x0010 },
+ { ScTableProtection::INSERT_COLUMNS, 0x0020 },
+ { ScTableProtection::INSERT_ROWS, 0x0040 },
+ { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
+
+ { ScTableProtection::DELETE_COLUMNS, 0x0100 },
+ { ScTableProtection::DELETE_ROWS, 0x0200 },
+ { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
+ { ScTableProtection::SORT, 0x0800 },
+ { ScTableProtection::AUTOFILTER, 0x1000 },
+ { ScTableProtection::PIVOT_TABLES, 0x2000 },
+ { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
+
+ { ScTableProtection::NONE, 0x0000 }
+ };
+
+ mnOptions = 0x0000;
+ ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
+ if (!pProtect)
+ return;
+
+ for (int i = 0; aTable[i].nMask != 0x0000; ++i)
+ {
+ if ( pProtect->isOptionEnabled(aTable[i].eOption) )
+ mnOptions |= aTable[i].nMask;
+ }
+}
+
+void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nBytes = 0x0867;
+ rStrm << nBytes;
+
+ sal_uChar nZero = 0x00;
+ for (int i = 0; i < 9; ++i)
+ rStrm << nZero;
+
+ nBytes = 0x0200;
+ rStrm << nBytes;
+ nBytes = 0x0100;
+ rStrm << nBytes;
+ nBytes = 0xFFFF;
+ rStrm << nBytes << nBytes;
+
+ rStrm << mnOptions;
+ nBytes = 0;
+ rStrm << nBytes;
+}
+
+// ============================================================================
+
+
+
+
+void XclCalccount::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nCount;
+}
+
+
+XclCalccount::XclCalccount( const ScDocument& rDoc )
+{
+ nCount = rDoc.GetDocOptions().GetIterCount();
+}
+
+
+sal_uInt16 XclCalccount::GetNum() const
+{
+ return 0x000C;
+}
+
+
+sal_Size XclCalccount::GetLen() const
+{
+ return 2;
+}
+
+
+void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterateCount, OString::valueOf( (sal_Int32)nCount ).getStr(),
+ FSEND );
+}
+
+
+
+
+void XclIteration::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << nIter;
+}
+
+
+XclIteration::XclIteration( const ScDocument& rDoc )
+{
+ nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
+}
+
+
+sal_uInt16 XclIteration::GetNum() const
+{
+ return 0x0011;
+}
+
+
+sal_Size XclIteration::GetLen() const
+{
+ return 2;
+}
+
+
+void XclIteration::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
+ FSEND );
+}
+
+
+
+
+void XclDelta::SaveCont( XclExpStream& rStrm )
+{
+ rStrm << fDelta;
+}
+
+
+
+XclDelta::XclDelta( const ScDocument& rDoc )
+{
+ fDelta = rDoc.GetDocOptions().GetIterEps();
+}
+
+
+sal_uInt16 XclDelta::GetNum() const
+{
+ return 0x0010;
+}
+
+
+sal_Size XclDelta::GetLen() const
+{
+ return 8;
+}
+
+
+void XclDelta::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_iterateDelta, OString::valueOf( fDelta ).getStr(),
+ FSEND );
+}
+
+// ============================================================================
+
+XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot& rRoot ) :
+ XclExpRecord(0x002F, 54),
+ mrRoot(rRoot)
+{
+}
+
+XclExpFileEncryption::~XclExpFileEncryption()
+{
+}
+
+void XclExpFileEncryption::WriteBody( XclExpStream& rStrm )
+{
+ // 0x0000 - neither standard nor strong encryption
+ // 0x0001 - standard or strong encryption
+ rStrm << static_cast<sal_uInt16>(0x0001);
+
+ // 0x0000 - non standard encryption
+ // 0x0001 - standard encryption
+ sal_uInt16 nStdEnc = 0x0001;
+ rStrm << nStdEnc << nStdEnc;
+
+ sal_uInt8 pnDocId[16];
+ sal_uInt8 pnSalt[16];
+ sal_uInt8 pnSaltHash[16];
+ XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot) );
+ xEnc->GetDocId(pnDocId);
+ xEnc->GetSalt(pnSalt);
+ xEnc->GetSaltDigest(pnSaltHash);
+
+ rStrm.Write(pnDocId, 16);
+ rStrm.Write(pnSalt, 16);
+ rStrm.Write(pnSaltHash, 16);
+
+ rStrm.SetEncrypter(xEnc);
+}
+
+// ============================================================================
+
+XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) :
+ XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage )
+{
+}
+
+void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
+{
+ rStrm.DisableEncryption();
+ rStrm << GetValue();
+}
+
+// ============================================================================
+
+XclExpInterfaceEnd::XclExpInterfaceEnd() :
+ XclExpRecord(0x00E2, 0) {}
+
+XclExpInterfaceEnd::~XclExpInterfaceEnd() {}
+
+void XclExpInterfaceEnd::WriteBody( XclExpStream& rStrm )
+{
+ // Don't forget to re-enable encryption.
+ rStrm.EnableEncryption();
+}
+
+// ============================================================================
+
+XclExpWriteAccess::XclExpWriteAccess() :
+ XclExpRecord(0x005C, 112)
+{
+}
+
+XclExpWriteAccess::~XclExpWriteAccess()
+{
+}
+
+void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
+{
+ static const sal_uInt8 aData[] = {
+ 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
+
+ sal_Size nDataSize = sizeof(aData);
+ for (sal_Size i = 0; i < nDataSize; ++i)
+ rStrm << aData[i];
+}
+
+// ============================================================================
+
+XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) :
+ XclExpRecord( EXC_ID_FILESHARING ),
+ mnPasswordHash( nPasswordHash ),
+ mbRecommendReadOnly( bRecommendReadOnly )
+{
+ if( rRoot.GetBiff() <= EXC_BIFF5 )
+ maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH );
+ else
+ maUserName.Assign( rRoot.GetUserName() );
+}
+
+void XclExpFileSharing::Save( XclExpStream& rStrm )
+{
+ if( (mnPasswordHash != 0) || mbRecommendReadOnly )
+ XclExpRecord::Save( rStrm );
+}
+
+void XclExpFileSharing::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName;
+}
+
+// ============================================================================
+
+XclExpProt4Rev::XclExpProt4Rev() :
+ XclExpRecord(0x01AF, 2)
+{
+}
+
+XclExpProt4Rev::~XclExpProt4Rev()
+{
+}
+
+void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpProt4RevPass::XclExpProt4RevPass() :
+ XclExpRecord(0x01BC, 2)
+{
+}
+
+XclExpProt4RevPass::~XclExpProt4RevPass()
+{
+}
+
+void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataRecalcId[] = {
+ 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
+};
+
+XclExpRecalcId::XclExpRecalcId() :
+ XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
+{
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataBookExt[] = {
+ 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02
+};
+
+XclExpBookExt::XclExpBookExt() :
+ XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
+{
+}
+
+// ============================================================================
+
+XclRefmode::XclRefmode( const ScDocument& rDoc ) :
+ XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
+{
+}
+
+void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
+{
+ rStrm.WriteAttributes(
+ XML_refMode, GetBool() ? "A1" : "R1C1",
+ FSEND );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
new file mode 100644
index 000000000000..ac636249cf68
--- /dev/null
+++ b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
@@ -0,0 +1,275 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLCalculationSettingsContext.hxx"
+#include "xmlimprt.hxx"
+#include "unonames.hxx"
+#include "docoptio.hxx"
+#include "document.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <comphelper/extract.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLCalculationSettingsContext::ScXMLCalculationSettingsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ fIterationEpsilon(0.001),
+ nIterationCount(100),
+ nYear2000(1930),
+ bIsIterationEnabled(false),
+ bCalcAsShown(false),
+ bIgnoreCase(false),
+ bLookUpLabels(sal_True),
+ bMatchWholeCell(sal_True),
+ bUseRegularExpressions(sal_True)
+{
+ aNullDate.Day = 30;
+ aNullDate.Month = 12;
+ aNullDate.Year = 1899;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_CASE_SENSITIVE))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bIgnoreCase = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_PRECISION_AS_SHOWN))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ bCalcAsShown = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bMatchWholeCell = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_AUTOMATIC_FIND_LABELS))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bLookUpLabels = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_NULL_YEAR))
+ {
+ sal_Int32 nTemp;
+ GetScImport().GetMM100UnitConverter().convertNumber(nTemp, sValue);
+ nYear2000 = static_cast<sal_uInt16>(nTemp);
+ }
+ else if (IsXMLToken(aLocalName, XML_USE_REGULAR_EXPRESSIONS))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bUseRegularExpressions = false;
+ }
+ }
+ }
+}
+
+ScXMLCalculationSettingsContext::~ScXMLCalculationSettingsContext()
+{
+}
+
+SvXMLImportContext *ScXMLCalculationSettingsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_NULL_DATE))
+ pContext = new ScXMLNullDateContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ else if (IsXMLToken(rLName, XML_ITERATION))
+ pContext = new ScXMLIterationContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLCalculationSettingsContext::EndElement()
+{
+ if (GetScImport().GetModel().is())
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (GetScImport().GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN)), uno::makeAny(bCalcAsShown) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE)), uno::makeAny(bIgnoreCase) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS)), uno::makeAny(bLookUpLabels) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE)), uno::makeAny(bMatchWholeCell) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED)), uno::makeAny(bUseRegularExpressions) );
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED)), uno::makeAny(bIsIterationEnabled) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT)), uno::makeAny(nIterationCount) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON)), uno::makeAny(fIterationEpsilon) );
+ xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE)), uno::makeAny(aNullDate) );
+ if (GetScImport().GetDocument())
+ {
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ ScDocOptions aDocOptions (GetScImport().GetDocument()->GetDocOptions());
+ aDocOptions.SetYear2000(nYear2000);
+ GetScImport().GetDocument()->SetDocOptions(aDocOptions);
+ }
+ }
+ }
+}
+
+ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLCalculationSettingsContext* pCalcSet) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DATE_VALUE))
+ {
+ util::DateTime aDateTime;
+ GetScImport().GetMM100UnitConverter().convertDateTime(aDateTime, sValue);
+ util::Date aDate;
+ aDate.Day = aDateTime.Day;
+ aDate.Month = aDateTime.Month;
+ aDate.Year = aDateTime.Year;
+ pCalcSet->SetNullDate(aDate);
+ }
+ }
+}
+
+ScXMLNullDateContext::~ScXMLNullDateContext()
+{
+}
+
+SvXMLImportContext *ScXMLNullDateContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLNullDateContext::EndElement()
+{
+}
+
+ScXMLIterationContext::ScXMLIterationContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLCalculationSettingsContext* pCalcSet) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_STATUS))
+ {
+ if (IsXMLToken(sValue, XML_ENABLE))
+ pCalcSet->SetIterationStatus(sal_True);
+ }
+ else if (IsXMLToken(aLocalName, XML_STEPS))
+ {
+ sal_Int32 nSteps;
+ GetScImport().GetMM100UnitConverter().convertNumber(nSteps, sValue);
+ pCalcSet->SetIterationCount(nSteps);
+ }
+ else if (IsXMLToken(aLocalName, XML_MAXIMUM_DIFFERENCE))
+ {
+ double fDif;
+ GetScImport().GetMM100UnitConverter().convertDouble(fDif, sValue);
+ pCalcSet->SetIterationEpsilon(fDif);
+ }
+ }
+ }
+}
+
+ScXMLIterationContext::~ScXMLIterationContext()
+{
+}
+
+SvXMLImportContext *ScXMLIterationContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLIterationContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.hxx b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx
new file mode 100644
index 000000000000..fb023bc0c740
--- /dev/null
+++ b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
+#define SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/util/Date.hpp>
+
+class ScXMLImport;
+
+class ScXMLCalculationSettingsContext : public SvXMLImportContext
+{
+ com::sun::star::util::Date aNullDate;
+ double fIterationEpsilon;
+ sal_Int32 nIterationCount;
+ sal_uInt16 nYear2000;
+ sal_Bool bIsIterationEnabled;
+ sal_Bool bCalcAsShown;
+ sal_Bool bIgnoreCase;
+ sal_Bool bLookUpLabels;
+ sal_Bool bMatchWholeCell;
+ sal_Bool bUseRegularExpressions;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLCalculationSettingsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLCalculationSettingsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void SetNullDate(const com::sun::star::util::Date& aDate) { aNullDate = aDate; }
+ void SetIterationStatus(const sal_Bool bValue) { bIsIterationEnabled = bValue; }
+ void SetIterationCount(const sal_Int32 nValue) { nIterationCount = nValue; }
+ void SetIterationEpsilon(const double fValue) { fIterationEpsilon = fValue; }
+ virtual void EndElement();
+};
+
+class ScXMLNullDateContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLNullDateContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet);
+
+ virtual ~ScXMLNullDateContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLIterationContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLIterationContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet);
+
+ virtual ~ScXMLIterationContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.cxx b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx
new file mode 100644
index 000000000000..b7a05b59053e
--- /dev/null
+++ b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLCellRangeSourceContext.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "xmlimprt.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+
+//___________________________________________________________________
+
+ScMyImpCellRangeSource::ScMyImpCellRangeSource() :
+ nColumns( 0 ),
+ nRows( 0 ),
+ nRefresh( 0 )
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLCellRangeSourceContext::ScXMLCellRangeSourceContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ ScMyImpCellRangeSource* pCellRangeSource ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableCellRangeSourceAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( nIndex ));
+ const OUString& sValue(xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME:
+ pCellRangeSource->sSourceStr = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME:
+ pCellRangeSource->sFilterName = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS:
+ pCellRangeSource->sFilterOptions = sValue;
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF:
+ pCellRangeSource->sURL = GetScImport().GetAbsoluteReference(sValue);
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) )
+ pCellRangeSource->nColumns = nValue;
+ else
+ pCellRangeSource->nColumns = 1;
+ }
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) )
+ pCellRangeSource->nRows = nValue;
+ else
+ pCellRangeSource->nRows = 1;
+ }
+ break;
+ case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY:
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ pCellRangeSource->nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ break;
+ }
+ }
+}
+
+ScXMLCellRangeSourceContext::~ScXMLCellRangeSourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLCellRangeSourceContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLCellRangeSourceContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.hxx b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx
new file mode 100644
index 000000000000..58b9c7d10e95
--- /dev/null
+++ b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCELLRANGESOURCECONTEXT_HXX
+#define SC_XMLCELLRANGESOURCECONTEXT_HXX
+
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+struct ScMyImpCellRangeSource
+{
+ ::rtl::OUString sSourceStr;
+ ::rtl::OUString sFilterName;
+ ::rtl::OUString sFilterOptions;
+ ::rtl::OUString sURL;
+ sal_Int32 nColumns;
+ sal_Int32 nRows;
+ sal_Int32 nRefresh;
+
+ ScMyImpCellRangeSource();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLCellRangeSourceContext : public SvXMLImportContext
+{
+private:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCellRangeSourceContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ ScMyImpCellRangeSource* pCellRangeSource
+ );
+ virtual ~ScXMLCellRangeSourceContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx
new file mode 100644
index 000000000000..7db33e2c51fa
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx
@@ -0,0 +1,765 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLChangeTrackingExportHelper.hxx"
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "document.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "cell.hxx"
+#include "textuno.hxx"
+#include "rangeutl.hxx"
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <svl/zforlist.hxx>
+
+#define SC_CHANGE_ID_PREFIX "ct"
+
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+ScChangeTrackingExportHelper::ScChangeTrackingExportHelper(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pChangeTrack(NULL),
+ pEditTextObj(NULL),
+ pDependings(NULL),
+ sChangeIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX))
+{
+ pChangeTrack = rExport.GetDocument() ? rExport.GetDocument()->GetChangeTrack() : NULL;
+ pDependings = new ScChangeActionTable();
+}
+
+ScChangeTrackingExportHelper::~ScChangeTrackingExportHelper()
+{
+ if (pDependings)
+ delete pDependings;
+}
+
+rtl::OUString ScChangeTrackingExportHelper::GetChangeID(const sal_uInt32 nActionNumber)
+{
+ rtl::OUStringBuffer sBuffer(sChangeIDPrefix);
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nActionNumber));
+ return sBuffer.makeStringAndClear();
+}
+
+void ScChangeTrackingExportHelper::GetAcceptanceState(const ScChangeAction* pAction)
+{
+ if (pAction->IsRejected())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_REJECTED);
+ else if (pAction->IsAccepted())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_ACCEPTED);
+}
+
+void ScChangeTrackingExportHelper::WriteBigRange(const ScBigRange& rBigRange, XMLTokenEnum aName)
+{
+ sal_Int32 nStartColumn;
+ sal_Int32 nEndColumn;
+ sal_Int32 nStartRow;
+ sal_Int32 nEndRow;
+ sal_Int32 nStartSheet;
+ sal_Int32 nEndSheet;
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ if ((nStartColumn == nEndColumn) && (nStartRow == nEndRow) && (nStartSheet == nEndSheet))
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ }
+ else
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_TABLE, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndColumn);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_COLUMN, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndRow);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_ROW, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, nEndSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_TABLE, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aBigRangeElem(rExport, XML_NAMESPACE_TABLE, aName, sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::WriteChangeInfo(const ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemInfo (rExport, XML_NAMESPACE_OFFICE, XML_CHANGE_INFO, sal_True, sal_True);
+
+ {
+ SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC,
+ XML_CREATOR, sal_True,
+ false );
+ rtl::OUString sAuthor(pAction->GetUser());
+ rExport.Characters(sAuthor);
+ }
+
+ {
+ rtl::OUStringBuffer sDate;
+ ScXMLConverter::ConvertDateTimeToString(pAction->GetDateTimeUTC(), sDate);
+ SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC,
+ XML_DATE, sal_True,
+ false );
+ rExport.Characters(sDate.makeStringAndClear());
+ }
+
+ rtl::OUString sComment(pAction->GetComment());
+ if (sComment.getLength())
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sComment, bPrevCharWasSpace);
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteGenerated(const ScChangeAction* pGeneratedAction)
+{
+#ifdef DBG_UTIL
+ sal_uInt32 nActionNumber(pGeneratedAction->GetActionNumber());
+ DBG_ASSERT(pChangeTrack->IsGenerated(nActionNumber), "a not generated action found");
+#endif
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
+ WriteBigRange(pGeneratedAction->GetBigRange(), XML_CELL_ADDRESS);
+ String sValue;
+ static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewString(sValue);
+ WriteCell(static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewCell(), sValue);
+}
+
+void ScChangeTrackingExportHelper::WriteDeleted(const ScChangeAction* pDeletedAction)
+{
+ sal_uInt32 nActionNumber(pDeletedAction->GetActionNumber());
+ if (pDeletedAction->GetType() == SC_CAT_CONTENT)
+ {
+ const ScChangeActionContent* pContentAction = static_cast<const ScChangeActionContent*>(pDeletedAction);
+ if (pContentAction)
+ {
+ if (!pChangeTrack->IsGenerated(nActionNumber))
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
+ if (static_cast<const ScChangeActionContent*>(pDeletedAction)->IsTopContent() && pDeletedAction->IsDeletedIn())
+ {
+ String sValue;
+ pContentAction->GetNewString(sValue);
+ WriteCell(pContentAction->GetNewCell(), sValue);
+ }
+ }
+ else
+ WriteGenerated(pContentAction);
+ }
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_DELETION, sal_True, sal_True);
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteDepending(const ScChangeAction* pDependAction)
+{
+ sal_uInt32 nActionNumber(pDependAction->GetActionNumber());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
+
+ // #i80033# save old "dependence" element if backward compatibility is requested,
+ // correct "dependency" element otherwise
+ const bool bSaveBackwardsCompatible = ( rExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );
+ SvXMLElementExport aDependElem(rExport, XML_NAMESPACE_TABLE,
+ bSaveBackwardsCompatible ? XML_DEPENDENCE : XML_DEPENDENCY,
+ sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction)
+{
+ if (pAction->HasDependent())
+ {
+ SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True);
+ const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDependentEntry();
+ while (pEntry)
+ {
+ WriteDepending(pEntry->GetAction());
+ pEntry = pEntry->GetNext();
+ }
+ }
+ if (pAction->HasDeleted())
+ {
+ SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DELETIONS, sal_True, sal_True);
+ const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDeletedEntry();
+ while (pEntry)
+ {
+ WriteDeleted(pEntry->GetAction());
+ pEntry = pEntry->GetNext();
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteEmptyCell()
+{
+ SvXMLElementExport aElemEmptyCell(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+}
+
+void ScChangeTrackingExportHelper::SetValueAttributes(const double& fValue, const String& sValue)
+{
+ sal_Bool bSetAttributes(false);
+ if (sValue.Len())
+ {
+ sal_uInt32 nIndex;
+ double fTempValue;
+ if (rExport.GetDocument() && rExport.GetDocument()->GetFormatTable()->IsNumberFormat(sValue, nIndex, fTempValue))
+ {
+ sal_uInt16 nType = rExport.GetDocument()->GetFormatTable()->GetType(nIndex);
+ if ((nType & NUMBERFORMAT_DEFINED) == NUMBERFORMAT_DEFINED)
+ nType -= NUMBERFORMAT_DEFINED;
+ switch(nType)
+ {
+ case NUMBERFORMAT_DATE:
+ {
+ if ( rExport.GetMM100UnitConverter().setNullDate(rExport.GetModel()) )
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertDateTime(sBuffer, fTempValue);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
+ bSetAttributes = sal_True;
+ }
+ }
+ break;
+ case NUMBERFORMAT_TIME:
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertTime(sBuffer, fTempValue);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
+ bSetAttributes = sal_True;
+ }
+ break;
+ }
+ }
+ }
+ if (!bSetAttributes)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertDouble(sBuffer, fValue);
+ rtl::OUString sNumValue(sBuffer.makeStringAndClear());
+ if (sNumValue.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sNumValue);
+ }
+}
+
+
+void ScChangeTrackingExportHelper::WriteValueCell(const ScBaseCell* pCell, const String& sValue)
+{
+ const ScValueCell* pValueCell = static_cast<const ScValueCell*>(pCell);
+ if (pValueCell)
+ {
+ SetValueAttributes(pValueCell->GetValue(), sValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteStringCell(const ScBaseCell* pCell)
+{
+ const ScStringCell* pStringCell = static_cast<const ScStringCell*>(pCell);
+ if (pStringCell)
+ {
+ String sString;
+ pStringCell->GetString(sString);
+ rtl::OUString sOUString(sString);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sOUString.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sOUString, bPrevCharWasSpace);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteEditCell(const ScBaseCell* pCell)
+{
+ const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pCell);
+ if (pEditCell)
+ {
+ String sString;
+ pEditCell->GetString(sString);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sString.Len())
+ {
+ if (!pEditTextObj)
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ xText.set(pEditTextObj);
+ }
+ pEditTextObj->SetText(*(pEditCell->GetData()));
+ if (xText.is())
+ rExport.GetTextParagraphExport()->exportText(xText, false, false);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteFormulaCell(const ScBaseCell* pCell, const String& sValue)
+{
+ ScBaseCell* pBaseCell = const_cast<ScBaseCell*>(pCell);
+ ScFormulaCell* pFormulaCell = static_cast<ScFormulaCell*>(pBaseCell);
+ if (pFormulaCell)
+ {
+ rtl::OUString sAddress;
+ const ScDocument* pDoc = rExport.GetDocument();
+ ScRangeStringConverter::GetStringFromAddress(sAddress, pFormulaCell->aPos, pDoc, ::formula::FormulaGrammar::CONV_OOO);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_ADDRESS, sAddress);
+ const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ String sFormula;
+ pFormulaCell->GetFormula(sFormula, eGrammar);
+ rtl::OUString sOUFormula(sFormula);
+ sal_uInt8 nMatrixFlag(pFormulaCell->GetMatrixFlag());
+ if (nMatrixFlag)
+ {
+ if (nMatrixFlag == MM_FORMULA)
+ {
+ SCCOL nColumns;
+ SCROW nRows;
+ pFormulaCell->GetMatColsRows(nColumns, nRows);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, static_cast<sal_Int32>(nColumns));
+ SvXMLUnitConverter::convertNumber(sRows, static_cast<sal_Int32>(nRows));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MATRIX_COVERED, XML_TRUE);
+ }
+ rtl::OUString sMatrixFormula = sOUFormula.copy(1, sOUFormula.getLength() - 2);
+ rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sMatrixFormula, false );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
+ }
+ else
+ {
+ rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sFormula, false );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
+ }
+ if (pFormulaCell->IsValue())
+ {
+ SetValueAttributes(pFormulaCell->GetValue(), sValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ String sCellValue;
+ pFormulaCell->GetString(sCellValue);
+ rtl::OUString sOUValue(sCellValue);
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
+ if (sOUValue.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ rExport.GetTextParagraphExport()->exportText(sOUValue, bPrevCharWasSpace);
+ }
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteCell(const ScBaseCell* pCell, const String& sValue)
+{
+ if (pCell)
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_NONE:
+ WriteEmptyCell();
+ break;
+ case CELLTYPE_VALUE:
+ WriteValueCell(pCell, sValue);
+ break;
+ case CELLTYPE_STRING:
+ WriteStringCell(pCell);
+ break;
+ case CELLTYPE_EDIT:
+ WriteEditCell(pCell);
+ break;
+ case CELLTYPE_FORMULA:
+ WriteFormulaCell(pCell, sValue);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ WriteEmptyCell();
+}
+
+void ScChangeTrackingExportHelper::WriteContentChange(ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_CHANGE, sal_True, sal_True);
+ const ScChangeAction* pConstAction = pAction;
+ WriteBigRange(pConstAction->GetBigRange(), XML_CELL_ADDRESS);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+ {
+ ScChangeActionContent* pPrevAction = static_cast<ScChangeActionContent*>(pAction)->GetPrevContent();
+ if (pPrevAction)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pPrevAction->GetActionNumber()));
+ SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_PREVIOUS, sal_True, sal_True);
+ String sValue;
+ static_cast<ScChangeActionContent*>(pAction)->GetOldString(sValue);
+ WriteCell(static_cast<ScChangeActionContent*>(pAction)->GetOldCell(), sValue);
+ }
+}
+
+void ScChangeTrackingExportHelper::AddInsertionAttributes(const ScChangeAction* pConstAction)
+{
+ sal_Int32 nPosition(0);
+ sal_Int32 nCount(0);
+ sal_Int32 nStartPosition(0);
+ sal_Int32 nEndPosition(0);
+ sal_Int32 nStartColumn;
+ sal_Int32 nEndColumn;
+ sal_Int32 nStartRow;
+ sal_Int32 nEndRow;
+ sal_Int32 nStartSheet;
+ sal_Int32 nEndSheet;
+ const ScBigRange& rBigRange = pConstAction->GetBigRange();
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ switch (pConstAction->GetType())
+ {
+ case SC_CAT_INSERT_COLS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
+ nStartPosition = nStartColumn;
+ nEndPosition = nEndColumn;
+ }
+ break;
+ case SC_CAT_INSERT_ROWS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
+ nStartPosition = nStartRow;
+ nEndPosition = nEndRow;
+ }
+ break;
+ case SC_CAT_INSERT_TABS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
+ nStartPosition = nStartSheet;
+ nEndPosition = nEndSheet;
+ }
+ break;
+ default :
+ {
+ OSL_FAIL("wrong insertion type");
+ }
+ break;
+ }
+ nPosition = nStartPosition;
+ nCount = nEndPosition - nStartPosition + 1;
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ DBG_ASSERT(nCount > 0, "wrong insertion count");
+ if (nCount > 1)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNT, sBuffer.makeStringAndClear());
+ }
+ if (pConstAction->GetType() != SC_CAT_INSERT_TABS)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteInsertion(ScChangeAction* pAction)
+{
+ AddInsertionAttributes(pAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_INSERTION, sal_True, sal_True);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::AddDeletionAttributes(const ScChangeActionDel* pDelAction, const ScChangeActionDel* /* pLastAction */)
+{
+ sal_Int32 nPosition(0);
+ const ScBigRange& rBigRange = pDelAction->GetBigRange();
+ sal_Int32 nStartColumn(0);
+ sal_Int32 nEndColumn(0);
+ sal_Int32 nStartRow(0);
+ sal_Int32 nEndRow(0);
+ sal_Int32 nStartSheet(0);
+ sal_Int32 nEndSheet(0);
+ rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
+ nEndColumn, nEndRow, nEndSheet);
+ switch (pDelAction->GetType())
+ {
+ case SC_CAT_DELETE_COLS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
+ nPosition = nStartColumn;
+ }
+ break;
+ case SC_CAT_DELETE_ROWS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
+ nPosition = nStartRow;
+ }
+ break;
+ case SC_CAT_DELETE_TABS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
+ nPosition = nStartSheet;
+ }
+ break;
+ default :
+ {
+ OSL_FAIL("wrong deletion type");
+ }
+ break;
+ }
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ if (pDelAction->GetType() != SC_CAT_DELETE_TABS)
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
+ if (pDelAction->IsMultiDelete() && !pDelAction->GetDx() && !pDelAction->GetDy())
+ {
+ const ScChangeAction* p = pDelAction->GetNext();
+ sal_Bool bAll(false);
+ sal_Int32 nSlavesCount (1);
+ while (!bAll && p)
+ {
+ if ( !p || p->GetType() != pDelAction->GetType() )
+ bAll = sal_True;
+ else
+ {
+ const ScChangeActionDel* pDel = (const ScChangeActionDel*) p;
+ if ( (pDel->GetDx() > pDelAction->GetDx() || pDel->GetDy() > pDelAction->GetDy()) &&
+ pDel->GetBigRange() == pDelAction->GetBigRange() )
+ {
+ ++nSlavesCount;
+ p = p->GetNext();
+ }
+ else
+ bAll = sal_True;
+ }
+ }
+
+ SvXMLUnitConverter::convertNumber(sBuffer, nSlavesCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MULTI_DELETION_SPANNED, sBuffer.makeStringAndClear());
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteCutOffs(const ScChangeActionDel* pAction)
+{
+ const ScChangeActionIns* pCutOffIns = pAction->GetCutOffInsert();
+ const ScChangeActionDelMoveEntry* pLinkMove = pAction->GetFirstMoveEntry();
+ if (pCutOffIns || pLinkMove)
+ {
+ SvXMLElementExport aCutOffsElem (rExport, XML_NAMESPACE_TABLE, XML_CUT_OFFS, sal_True, sal_True);
+ rtl::OUStringBuffer sBuffer;
+ if (pCutOffIns)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pCutOffIns->GetActionNumber()));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pAction->GetCutOffCount()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ SvXMLElementExport aInsertCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_INSERTION_CUT_OFF, sal_True, sal_True);
+ }
+ while (pLinkMove)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pLinkMove->GetAction()->GetActionNumber()));
+ if (pLinkMove->GetCutOffFrom() == pLinkMove->GetCutOffTo())
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
+ }
+ else
+ {
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_POSITION, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffTo()));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_POSITION, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aMoveCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT_CUT_OFF, sal_True, sal_True);
+ pLinkMove = pLinkMove->GetNext();
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WriteDeletion(ScChangeAction* pAction)
+{
+ ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
+ AddDeletionAttributes(pDelAction, pDelAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_DELETION, sal_True, sal_True);
+ WriteChangeInfo(pDelAction);
+ WriteDependings(pDelAction);
+ WriteCutOffs(pDelAction);
+}
+
+void ScChangeTrackingExportHelper::WriteMovement(ScChangeAction* pAction)
+{
+ const ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT, sal_True, sal_True);
+ WriteBigRange(pMoveAction->GetFromRange(), XML_SOURCE_RANGE_ADDRESS);
+ WriteBigRange(pMoveAction->GetBigRange(), XML_TARGET_RANGE_ADDRESS);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::WriteRejection(ScChangeAction* pAction)
+{
+ SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_REJECTION, sal_True, sal_True);
+ WriteChangeInfo(pAction);
+ WriteDependings(pAction);
+}
+
+void ScChangeTrackingExportHelper::CollectCellAutoStyles(const ScBaseCell* pBaseCell)
+{
+ if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_EDIT))
+ {
+ const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pBaseCell);
+ if (pEditCell)
+ {
+ if (!pEditTextObj)
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ xText.set(pEditTextObj);
+ }
+ pEditTextObj->SetText(*(pEditCell->GetData()));
+ if (xText.is())
+ rExport.GetTextParagraphExport()->collectTextAutoStyles(xText, false, false);
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::CollectActionAutoStyles(ScChangeAction* pAction)
+{
+ if (pAction->GetType() == SC_CAT_CONTENT)
+ {
+ if (pChangeTrack->IsGenerated(pAction->GetActionNumber()))
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
+ else
+ {
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetOldCell());
+ if (static_cast<ScChangeActionContent*>(pAction)->IsTopContent() && pAction->IsDeletedIn())
+ CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::WorkWithChangeAction(ScChangeAction* pAction)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pAction->GetActionNumber()));
+ GetAcceptanceState(pAction);
+ if (pAction->IsRejecting())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REJECTING_CHANGE_ID, GetChangeID(pAction->GetRejectAction()));
+ if (pAction->GetType() == SC_CAT_CONTENT)
+ WriteContentChange(pAction);
+ else if (pAction->IsInsertType())
+ WriteInsertion(pAction);
+ else if (pAction->IsDeleteType())
+ WriteDeletion(pAction);
+ else if (pAction->GetType() == SC_CAT_MOVE)
+ WriteMovement(pAction);
+ else if (pAction->GetType() == SC_CAT_REJECT)
+ WriteRejection(pAction);
+ else
+ {
+ OSL_FAIL("not a writeable type");
+ }
+ rExport.CheckAttrList();
+}
+
+void ScChangeTrackingExportHelper::CollectAutoStyles()
+{
+ if (pChangeTrack)
+ {
+ sal_uInt32 nCount (pChangeTrack->GetActionMax());
+ if (nCount)
+ {
+ ScChangeAction* pAction = pChangeTrack->GetFirst();
+ CollectActionAutoStyles(pAction);
+ ScChangeAction* pLastAction = pChangeTrack->GetLast();
+ while (pAction != pLastAction)
+ {
+ pAction = pAction->GetNext();
+ CollectActionAutoStyles(pAction);
+ }
+ pAction = pChangeTrack->GetFirstGenerated();
+ while (pAction)
+ {
+ CollectActionAutoStyles(pAction);
+ pAction = pAction->GetNext();
+ }
+ }
+ }
+}
+
+void ScChangeTrackingExportHelper::CollectAndWriteChanges()
+{
+ if (pChangeTrack)
+ {
+ SvXMLElementExport aCangeListElem(rExport, XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, sal_True, sal_True);
+ {
+ ScChangeAction* pAction = pChangeTrack->GetFirst();
+ if (pAction)
+ {
+ WorkWithChangeAction(pAction);
+ ScChangeAction* pLastAction = pChangeTrack->GetLast();
+ while (pAction != pLastAction)
+ {
+ pAction = pAction->GetNext();
+ WorkWithChangeAction(pAction);
+ }
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx
new file mode 100644
index 000000000000..cfb518e58b29
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCHANGETRACKINGEXPORTHELPER_HXX
+#define SC_XMLCHANGETRACKINGEXPORTHELPER_HXX
+
+#include <xmloff/xmltoken.hxx>
+#include <list>
+#include <com/sun/star/text/XText.hpp>
+#include <rtl/ustrbuf.hxx>
+
+class ScChangeAction;
+class ScChangeTrack;
+class ScXMLExport;
+class ScBaseCell;
+class ScChangeActionDel;
+class ScBigRange;
+class ScEditEngineTextObj;
+class ScChangeActionTable;
+class String;
+class DateTime;
+
+typedef std::list<ScChangeActionDel*> ScMyDeletionsList;
+
+class ScChangeTrackingExportHelper
+{
+ ScXMLExport& rExport;
+
+ ScChangeTrack* pChangeTrack;
+ ScEditEngineTextObj* pEditTextObj;
+ ScChangeActionTable* pDependings;
+ rtl::OUString sChangeIDPrefix;
+ com::sun::star::uno::Reference<com::sun::star::text::XText> xText;
+
+ rtl::OUString GetChangeID(const sal_uInt32 nActionNumber);
+ void GetAcceptanceState(const ScChangeAction* pAction);
+
+ void WriteBigRange(const ScBigRange& rBigRange, xmloff::token::XMLTokenEnum aName);
+ void WriteChangeInfo(const ScChangeAction* pAction);
+ void WriteGenerated(const ScChangeAction* pDependAction);
+ void WriteDeleted(const ScChangeAction* pDependAction);
+ void WriteDepending(const ScChangeAction* pDependAction);
+ void WriteDependings(ScChangeAction* pAction);
+
+ void WriteEmptyCell();
+ void SetValueAttributes(const double& fValue, const String& sValue);
+ void WriteValueCell(const ScBaseCell* pCell, const String& sValue);
+ void WriteStringCell(const ScBaseCell* pCell);
+ void WriteEditCell(const ScBaseCell* pCell);
+ void WriteFormulaCell(const ScBaseCell* pCell, const String& sValue);
+ void WriteCell(const ScBaseCell* pCell, const String& sValue);
+
+ void WriteContentChange(ScChangeAction* pAction);
+ void AddInsertionAttributes(const ScChangeAction* pAction);
+ void WriteInsertion(ScChangeAction* pAction);
+ void AddDeletionAttributes(const ScChangeActionDel* pAction, const ScChangeActionDel* pLastAction);
+ void WriteDeletionCells(ScChangeActionDel* pAction);
+ void WriteCutOffs(const ScChangeActionDel* pAction);
+ void WriteDeletion(ScChangeAction* pAction);
+ void WriteMovement(ScChangeAction* pAction);
+ void WriteRejection(ScChangeAction* pAction);
+
+ void CollectCellAutoStyles(const ScBaseCell* pBaseCell);
+ void CollectActionAutoStyles(ScChangeAction* pAction);
+ void WorkWithChangeAction(ScChangeAction* pAction);
+public:
+ ScChangeTrackingExportHelper(ScXMLExport& rExport);
+ ~ScChangeTrackingExportHelper();
+
+ void CollectAutoStyles();
+ void CollectAndWriteChanges();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx
new file mode 100644
index 000000000000..246e3eed3f20
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx
@@ -0,0 +1,938 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "XMLConverter.hxx"
+#include "cell.hxx"
+#include "document.hxx"
+#include "chgviset.hxx"
+#include "rangeutl.hxx"
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <svl/zforlist.hxx>
+#include <xmloff/xmluconv.hxx>
+
+#define SC_CHANGE_ID_PREFIX "ct"
+
+ScMyCellInfo::ScMyCellInfo()
+ : pCell(NULL),
+ sFormulaAddress(),
+ sFormula(),
+ sInputString(),
+ fValue(0.0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE)
+{
+}
+
+ScMyCellInfo::ScMyCellInfo(ScBaseCell* pTempCell, const rtl::OUString& rFormulaAddress, const rtl::OUString& rFormula,
+ const formula::FormulaGrammar::Grammar eTempGrammar, const rtl::OUString& rInputString,
+ const double& rValue, const sal_uInt16 nTempType, const sal_uInt8 nTempMatrixFlag, const sal_Int32 nTempMatrixCols,
+ const sal_Int32 nTempMatrixRows)
+ : pCell(pTempCell),
+ sFormulaAddress(rFormulaAddress),
+ sFormula(rFormula),
+ sInputString(rInputString),
+ fValue(rValue),
+ nMatrixCols(nTempMatrixCols),
+ nMatrixRows(nTempMatrixRows),
+ eGrammar( eTempGrammar),
+ nType(nTempType),
+ nMatrixFlag(nTempMatrixFlag)
+{
+}
+
+ScMyCellInfo::~ScMyCellInfo()
+{
+ if (pCell)
+ pCell->Delete();
+}
+
+ScBaseCell* ScMyCellInfo::CreateCell(ScDocument* pDoc)
+{
+ if (pDoc)
+ {
+ if (!pCell && sFormula.getLength() && sFormulaAddress.getLength())
+ {
+ ScAddress aPos;
+ sal_Int32 nOffset(0);
+ ScRangeStringConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset);
+ pCell = new ScFormulaCell(pDoc, aPos, sFormula, eGrammar, nMatrixFlag);
+ static_cast<ScFormulaCell*>(pCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows));
+ }
+
+ if ((nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME) && sInputString.Len() == 0)
+ {
+ sal_uInt32 nFormat(0);
+ if (nType == NUMBERFORMAT_DATE)
+ nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge );
+ else if (nType == NUMBERFORMAT_TIME)
+ nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_TIME, ScGlobal::eLnge );
+ pDoc->GetFormatTable()->GetInputLineString(fValue, nFormat, sInputString);
+ }
+ }
+
+ return pCell ? pCell->CloneWithoutNote( *pDoc ) : 0;
+}
+
+ScMyDeleted::ScMyDeleted()
+ : pCellInfo(NULL)
+{
+}
+
+ScMyDeleted::~ScMyDeleted()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyGenerated::ScMyGenerated(ScMyCellInfo* pTempCellInfo, const ScBigRange& aTempBigRange)
+ : aBigRange(aTempBigRange),
+ nID(0),
+ pCellInfo(pTempCellInfo)
+{
+}
+
+ScMyGenerated::~ScMyGenerated()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyBaseAction::ScMyBaseAction(const ScChangeActionType nTempActionType)
+ : aDependencies(),
+ aDeletedList(),
+ nActionNumber(0),
+ nRejectingNumber(0),
+ nPreviousAction(0),
+ nActionType(nTempActionType),
+ nActionState(SC_CAS_VIRGIN)
+{
+}
+
+ScMyBaseAction::~ScMyBaseAction()
+{
+}
+
+ScMyInsAction::ScMyInsAction(const ScChangeActionType nActionTypeP)
+ : ScMyBaseAction(nActionTypeP)
+{
+}
+
+ScMyInsAction::~ScMyInsAction()
+{
+}
+
+ScMyDelAction::ScMyDelAction(const ScChangeActionType nActionTypeP)
+ : ScMyBaseAction(nActionTypeP),
+ aGeneratedList(),
+ pInsCutOff(NULL),
+ aMoveCutOffs(),
+ nD(0)
+{
+}
+
+ScMyDelAction::~ScMyDelAction()
+{
+ if (pInsCutOff)
+ delete pInsCutOff;
+}
+
+ScMyMoveAction::ScMyMoveAction()
+ : ScMyBaseAction(SC_CAT_MOVE),
+ aGeneratedList(),
+ pMoveRanges(NULL)
+{
+}
+
+ScMyMoveAction::~ScMyMoveAction()
+{
+ if (pMoveRanges)
+ delete pMoveRanges;
+}
+
+
+ScMyContentAction::ScMyContentAction()
+ : ScMyBaseAction(SC_CAT_CONTENT),
+ pCellInfo(NULL)
+{
+}
+
+ScMyContentAction::~ScMyContentAction()
+{
+ if (pCellInfo)
+ delete pCellInfo;
+}
+
+ScMyRejAction::ScMyRejAction()
+ : ScMyBaseAction(SC_CAT_REJECT)
+{
+}
+
+ScMyRejAction::~ScMyRejAction()
+{
+}
+
+ScXMLChangeTrackingImportHelper::ScXMLChangeTrackingImportHelper()
+ : aUsers(),
+ aActions(),
+ pDoc(NULL),
+ pTrack(NULL),
+ pCurrentAction(NULL),
+ sIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX)),
+ nMultiSpanned(0),
+ nMultiSpannedSlaveCount(0),
+ bChangeTrack(false)
+{
+ nPrefixLength = sIDPrefix.getLength();
+}
+
+ScXMLChangeTrackingImportHelper::~ScXMLChangeTrackingImportHelper()
+{
+}
+
+void ScXMLChangeTrackingImportHelper::StartChangeAction(const ScChangeActionType nActionType)
+{
+ DBG_ASSERT(!pCurrentAction, "a not inserted action");
+ switch (nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ {
+ pCurrentAction = new ScMyInsAction(nActionType);
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ pCurrentAction = new ScMyDelAction(nActionType);
+ }
+ break;
+ case SC_CAT_MOVE:
+ {
+ pCurrentAction = new ScMyMoveAction();
+ }
+ break;
+ case SC_CAT_CONTENT:
+ {
+ pCurrentAction = new ScMyContentAction();
+ }
+ break;
+ case SC_CAT_REJECT:
+ {
+ pCurrentAction = new ScMyRejAction();
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+sal_uInt32 ScXMLChangeTrackingImportHelper::GetIDFromString(const rtl::OUString& sID)
+{
+ sal_uInt32 nResult(0);
+ sal_uInt32 nLength(sID.getLength());
+ if (nLength)
+ {
+ if (sID.compareTo(sIDPrefix, nPrefixLength) == 0)
+ {
+ rtl::OUString sValue(sID.copy(nPrefixLength, nLength - nPrefixLength));
+ sal_Int32 nValue;
+ SvXMLUnitConverter::convertNumber(nValue, sValue);
+ DBG_ASSERT(nValue > 0, "wrong change action ID");
+ nResult = nValue;
+ }
+ else
+ {
+ OSL_FAIL("wrong change action ID");
+ }
+ }
+ return nResult;
+}
+
+void ScXMLChangeTrackingImportHelper::SetActionInfo(const ScMyActionInfo& aInfo)
+{
+ pCurrentAction->aInfo = aInfo;
+ String aUser(aInfo.sUser);
+ StrData* pStrData = new StrData( aUser );
+ if ( !aUsers.Insert( pStrData ) )
+ delete pStrData;
+}
+
+void ScXMLChangeTrackingImportHelper::SetPreviousChange(const sal_uInt32 nPreviousAction,
+ ScMyCellInfo* pCellInfo)
+{
+ DBG_ASSERT(pCurrentAction->nActionType == SC_CAT_CONTENT, "wrong action type");
+ ScMyContentAction* pAction = static_cast<ScMyContentAction*>(pCurrentAction);
+ pAction->nPreviousAction = nPreviousAction;
+ pAction->pCellInfo = pCellInfo;
+}
+
+void ScXMLChangeTrackingImportHelper::SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable)
+{
+ DBG_ASSERT(((pCurrentAction->nActionType != SC_CAT_MOVE) &&
+ (pCurrentAction->nActionType != SC_CAT_CONTENT) &&
+ (pCurrentAction->nActionType != SC_CAT_REJECT)), "wrong action type");
+ DBG_ASSERT(nCount > 0, "wrong count");
+ switch(pCurrentAction->nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_DELETE_COLS:
+ {
+ pCurrentAction->aBigRange.Set(nPosition, nInt32Min, nTable,
+ nPosition + nCount - 1, nInt32Max, nTable);
+ }
+ break;
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_DELETE_ROWS:
+ {
+ pCurrentAction->aBigRange.Set(nInt32Min, nPosition, nTable,
+ nInt32Max, nPosition + nCount - 1, nTable);
+ }
+ break;
+ case SC_CAT_INSERT_TABS:
+ case SC_CAT_DELETE_TABS:
+ {
+ pCurrentAction->aBigRange.Set(nInt32Min, nInt32Min, nPosition,
+ nInt32Max, nInt32Max, nPosition + nCount - 1);
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID)
+{
+ ScMyDeleted* pDeleted = new ScMyDeleted();
+ pDeleted->nID = nID;
+ pCurrentAction->aDeletedList.push_front(pDeleted);
+}
+
+void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo)
+{
+ ScMyDeleted* pDeleted = new ScMyDeleted();
+ pDeleted->nID = nID;
+ pDeleted->pCellInfo = pCellInfo;
+ pCurrentAction->aDeletedList.push_front(pDeleted);
+}
+
+void ScXMLChangeTrackingImportHelper::SetMultiSpanned(const sal_Int16 nTempMultiSpanned)
+{
+ if (nTempMultiSpanned)
+ {
+ DBG_ASSERT(((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)), "wrong action type");
+ nMultiSpanned = nTempMultiSpanned;
+ nMultiSpannedSlaveCount = 0;
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition)
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->pInsCutOff = new ScMyInsertionCutOff(nID, nPosition);
+ }
+ else
+ {
+ OSL_FAIL("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition)
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->aMoveCutOffs.push_front(ScMyMoveCutOff(nID, nStartPosition, nEndPosition));
+ }
+ else
+ {
+ OSL_FAIL("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange)
+{
+ if (pCurrentAction->nActionType == SC_CAT_MOVE)
+ {
+ static_cast<ScMyMoveAction*>(pCurrentAction)->pMoveRanges = new ScMyMoveRanges(aSourceRange, aTargetRange);
+ }
+ else
+ {
+ OSL_FAIL("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::GetMultiSpannedRange()
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ if (nMultiSpannedSlaveCount)
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->nD = nMultiSpannedSlaveCount;
+ }
+ ++nMultiSpannedSlaveCount;
+ if (nMultiSpannedSlaveCount >= nMultiSpanned)
+ {
+ nMultiSpanned = 0;
+ nMultiSpannedSlaveCount = 0;
+ }
+ }
+ else
+ {
+ OSL_FAIL("wrong action type");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange)
+{
+ ScMyGenerated* pGenerated = new ScMyGenerated(pCellInfo, aBigRange);
+ if (pCurrentAction->nActionType == SC_CAT_MOVE)
+ {
+ static_cast<ScMyMoveAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
+ }
+ else if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ {
+ static_cast<ScMyDelAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
+ }
+ else
+ {
+ OSL_FAIL("try to insert a generated action to a wrong action");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::EndChangeAction()
+{
+ if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
+ GetMultiSpannedRange();
+ if (pCurrentAction && pCurrentAction->nActionNumber > 0)
+ aActions.push_back(pCurrentAction);
+ else
+ {
+ OSL_FAIL("no current action");
+ }
+ pCurrentAction = NULL;
+}
+
+void ScXMLChangeTrackingImportHelper::ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime)
+{
+ Date aDate(aInfo.aDateTime.Day, aInfo.aDateTime.Month, aInfo.aDateTime.Year);
+ Time aTime(aInfo.aDateTime.Hours, aInfo.aDateTime.Minutes, aInfo.aDateTime.Seconds, aInfo.aDateTime.HundredthSeconds);
+ aDateTime.SetDate( aDate.GetDate() );
+ aDateTime.SetTime( aTime.GetTime() );
+
+ // old files didn't store 100th seconds, enable again
+ if ( aInfo.aDateTime.HundredthSeconds )
+ pTrack->SetTime100thSeconds( sal_True );
+
+ StrData aStrData( aInfo.sUser );
+ sal_uInt16 nPos;
+ if ( pTrack->GetUserCollection().Search( &aStrData, nPos ) )
+ {
+ const StrData* pUser = static_cast<const StrData*>( pTrack->GetUserCollection().At( nPos ) );
+ if ( pUser )
+ rUser = pUser->GetString();
+ else
+ rUser = aInfo.sUser; // shouldn't happen
+ }
+ else
+ rUser = aInfo.sUser; // shouldn't happen
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateInsertAction(ScMyInsAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionIns(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateDeleteAction(ScMyDelAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionDel(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType, pAction->nD, pTrack);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateMoveAction(ScMyMoveAction* pAction)
+{
+ DBG_ASSERT(pAction->pMoveRanges, "no move ranges");
+ if (pAction->pMoveRanges)
+ {
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionMove(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->pMoveRanges->aTargetRange, aUser, aDateTime, sComment, pAction->pMoveRanges->aSourceRange , pTrack);
+ return pNewAction;
+ }
+ return NULL;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateRejectionAction(ScMyRejAction* pAction)
+{
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionReject(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment);
+ return pNewAction;
+}
+
+ScChangeAction* ScXMLChangeTrackingImportHelper::CreateContentAction(ScMyContentAction* pAction)
+{
+ ScBaseCell* pCell = NULL;
+ if (pAction->pCellInfo)
+ pCell = pAction->pCellInfo->CreateCell(pDoc);
+
+ DateTime aDateTime( Date(0), Time(0) );
+ String aUser;
+ ConvertInfo(pAction->aInfo, aUser, aDateTime);
+
+ String sComment (pAction->aInfo.sComment);
+
+ ScChangeAction* pNewAction = new ScChangeActionContent(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
+ pAction->aBigRange, aUser, aDateTime, sComment, pCell, pDoc, pAction->pCellInfo->sInputString);
+ return pNewAction;
+}
+
+void ScXMLChangeTrackingImportHelper::CreateGeneratedActions(ScMyGeneratedList& rList)
+{
+ if (!rList.empty())
+ {
+ ScMyGeneratedList::iterator aItr(rList.begin());
+ ScMyGeneratedList::iterator aEndItr(rList.end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr)->nID == 0))
+ {
+ ScBaseCell* pCell = NULL;
+ if ((*aItr)->pCellInfo)
+ pCell = (*aItr)->pCellInfo->CreateCell(pDoc);
+
+ if (pCell)
+ {
+ (*aItr)->nID = pTrack->AddLoadedGenerated(pCell, (*aItr)->aBigRange, (*aItr)->pCellInfo->sInputString );
+ DBG_ASSERT((*aItr)->nID, "could not insert generated action");
+ }
+ }
+ ++aItr;
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct)
+{
+ if (!pAction->aGeneratedList.empty())
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ if (pDelAct)
+ {
+ ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
+ ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nID, "a not inserted generated action");
+ pDelAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aGeneratedList.erase(aItr);
+ }
+ }
+ }
+ if (pAction->pInsCutOff)
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ ScChangeAction* pChangeAction = pTrack->GetAction(pAction->pInsCutOff->nID);
+ if (pChangeAction && pChangeAction->IsInsertType())
+ {
+ ScChangeActionIns* pInsAction = static_cast<ScChangeActionIns*>(pChangeAction);
+ if (pInsAction && pDelAct)
+ pDelAct->SetCutOffInsert(pInsAction, static_cast<sal_Int16>(pAction->pInsCutOff->nPosition));
+ }
+ else
+ {
+ OSL_FAIL("no cut off insert action");
+ }
+ }
+ if (!pAction->aMoveCutOffs.empty())
+ {
+ DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
+ (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
+ ScMyMoveCutOffs::iterator aItr(pAction->aMoveCutOffs.begin());
+ ScMyMoveCutOffs::iterator aEndItr(pAction->aMoveCutOffs.end());
+ while(aItr != aEndItr)
+ {
+ ScChangeAction* pChangeAction = pTrack->GetAction(aItr->nID);
+ if (pChangeAction && (pChangeAction->GetType() == SC_CAT_MOVE))
+ {
+ ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*>(pChangeAction);
+ if (pMoveAction && pDelAct)
+ pDelAct->AddCutOffMove(pMoveAction, static_cast<sal_Int16>(aItr->nStartPosition),
+ static_cast<sal_Int16>(aItr->nEndPosition));
+ }
+ else
+ {
+ OSL_FAIL("no cut off move action");
+ }
+ aItr = pAction->aMoveCutOffs.erase(aItr);
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct)
+{
+ if (!pAction->aGeneratedList.empty())
+ {
+ if (pAction->nActionType == SC_CAT_MOVE)
+ {
+ if (pMoveAct)
+ {
+ ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
+ ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nID, "a not inserted generated action");
+ pMoveAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aGeneratedList.erase(aItr);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent)
+{
+ if (pAction->nPreviousAction)
+ {
+ DBG_ASSERT(pAction->nActionType == SC_CAT_CONTENT, "wrong action type");
+ ScChangeAction* pPrevAct = pTrack->GetAction(pAction->nPreviousAction);
+ if (pPrevAct)
+ {
+ ScChangeActionContent* pPrevActContent = static_cast<ScChangeActionContent*>(pPrevAct);
+ if (pPrevActContent && pActContent)
+ {
+ pActContent->SetPrevContent(pPrevActContent);
+ pPrevActContent->SetNextContent(pActContent);
+ const ScBaseCell* pOldCell = pActContent->GetOldCell();
+ if (pOldCell)
+ {
+ ScBaseCell* pNewCell = pOldCell->CloneWithoutNote( *pDoc );
+ if (pNewCell)
+ {
+ pPrevActContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING);
+ pPrevActContent->SetNewValue(pActContent->GetOldCell(), pDoc);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetDependencies(ScMyBaseAction* pAction)
+{
+ ScChangeAction* pAct = pTrack->GetAction(pAction->nActionNumber);
+ if (pAct)
+ {
+ if (!pAction->aDependencies.empty())
+ {
+ ScMyDependencies::iterator aItr(pAction->aDependencies.begin());
+ ScMyDependencies::iterator aEndItr(pAction->aDependencies.end());
+ while(aItr != aEndItr)
+ {
+ pAct->AddDependent(*aItr, pTrack);
+ aItr = pAction->aDependencies.erase(aItr);
+ }
+ }
+ if (!pAction->aDeletedList.empty())
+ {
+ ScMyDeletedList::iterator aItr(pAction->aDeletedList.begin());
+ ScMyDeletedList::iterator aEndItr(pAction->aDeletedList.end());
+ while(aItr != aEndItr)
+ {
+ pAct->SetDeletedInThis((*aItr)->nID, pTrack);
+ ScChangeAction* pDeletedAct = pTrack->GetAction((*aItr)->nID);
+ if ((pDeletedAct->GetType() == SC_CAT_CONTENT) && (*aItr)->pCellInfo)
+ {
+ ScChangeActionContent* pContentAct = static_cast<ScChangeActionContent*>(pDeletedAct);
+ if (pContentAct && (*aItr)->pCellInfo)
+ {
+ ScBaseCell* pCell = (*aItr)->pCellInfo->CreateCell(pDoc);
+ if (!ScBaseCell::CellEqual(pCell, pContentAct->GetNewCell()))
+ {
+ // #i40704# Don't overwrite SetNewCell result by calling SetNewValue,
+ // instead pass the input string to SetNewCell.
+ pContentAct->SetNewCell(pCell, pDoc, (*aItr)->pCellInfo->sInputString);
+ }
+ }
+ }
+ if (*aItr)
+ delete *aItr;
+ aItr = pAction->aDeletedList.erase(aItr);
+ }
+ }
+ if ((pAction->nActionType == SC_CAT_DELETE_COLS) ||
+ (pAction->nActionType == SC_CAT_DELETE_ROWS))
+ SetDeletionDependencies(static_cast<ScMyDelAction*>(pAction), static_cast<ScChangeActionDel*>(pAct));
+ else if (pAction->nActionType == SC_CAT_MOVE)
+ SetMovementDependencies(static_cast<ScMyMoveAction*>(pAction), static_cast<ScChangeActionMove*>(pAct));
+ else if (pAction->nActionType == SC_CAT_CONTENT)
+ SetContentDependencies(static_cast<ScMyContentAction*>(pAction), static_cast<ScChangeActionContent*>(pAct));
+ }
+ else
+ {
+ OSL_FAIL("could not find the action");
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::SetNewCell(ScMyContentAction* pAction)
+{
+ ScChangeAction* pChangeAction = pTrack->GetAction(pAction->nActionNumber);
+ if (pChangeAction)
+ {
+ ScChangeActionContent* pChangeActionContent = static_cast<ScChangeActionContent*>(pChangeAction);
+ if (pChangeActionContent)
+ {
+ if (pChangeActionContent->IsTopContent() && !pChangeActionContent->IsDeletedIn())
+ {
+ sal_Int32 nCol, nRow, nTab, nCol2, nRow2, nTab2;
+ pAction->aBigRange.GetVars(nCol, nRow, nTab, nCol2, nRow2, nTab2);
+ if ((nCol >= 0) && (nCol <= MAXCOL) &&
+ (nRow >= 0) && (nRow <= MAXROW) &&
+ (nTab >= 0) && (nTab <= MAXTAB))
+ {
+ ScAddress aAddress (static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow),
+ static_cast<SCTAB>(nTab));
+ ScBaseCell* pCell = pDoc->GetCell(aAddress);
+ if (pCell)
+ {
+ ScBaseCell* pNewCell = NULL;
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ pNewCell = pCell->CloneWithoutNote( *pDoc );
+ else
+ {
+ sal_uInt8 nMatrixFlag = static_cast<ScFormulaCell*>(pCell)->GetMatrixFlag();
+ String sFormula;
+ // With GRAM_ODFF reference detection is faster on compilation.
+ /* FIXME: new cell should be created with a clone
+ * of the token array instead. Any reason why this
+ * wasn't done? */
+ static_cast<ScFormulaCell*>(pCell)->GetFormula(sFormula,formula::FormulaGrammar::GRAM_ODFF);
+ rtl::OUString sOUFormula(sFormula);
+
+ // #i87826# [Collaboration] Rejected move destroys formulas
+ // FIXME: adjust ScFormulaCell::GetFormula(), so that the right formula string
+ // is returned and no further string handling is necessary
+ rtl::OUString sOUFormula2;
+ if ( nMatrixFlag != MM_NONE )
+ {
+ sOUFormula2 = sOUFormula.copy( 2, sOUFormula.getLength() - 3 );
+ }
+ else
+ {
+ sOUFormula2 = sOUFormula.copy( 1, sOUFormula.getLength() - 1 );
+ }
+
+ String sFormula2(sOUFormula2);
+ pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2,formula::FormulaGrammar::GRAM_ODFF, nMatrixFlag);
+ if (pNewCell)
+ {
+ if (nMatrixFlag == MM_FORMULA)
+ {
+ SCCOL nCols;
+ SCROW nRows;
+ static_cast<ScFormulaCell*>(pCell)->GetMatColsRows(nCols, nRows);
+ static_cast<ScFormulaCell*>(pNewCell)->SetMatColsRows(nCols, nRows);
+ }
+ static_cast<ScFormulaCell*>(pNewCell)->SetInChangeTrack(sal_True);
+ }
+ }
+ pChangeActionContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING);
+ // #i40704# don't overwrite the formula string from above with pCell's content
+ if (pCell->GetCellType() != CELLTYPE_FORMULA)
+ pChangeActionContent->SetNewValue(pCell, pDoc);
+ }
+ }
+ else
+ {
+ OSL_FAIL("wrong cell position");
+ }
+ }
+ }
+ }
+}
+
+void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pTempDoc)
+{
+ pDoc = pTempDoc;
+ if (pDoc)
+ {
+ pTrack = new ScChangeTrack(pDoc, aUsers);
+ // old files didn't store 100th seconds, disable until encountered
+ pTrack->SetTime100thSeconds( false );
+
+ ScMyActions::iterator aItr(aActions.begin());
+ ScMyActions::iterator aEndItr(aActions.end());
+ while (aItr != aEndItr)
+ {
+ ScChangeAction* pAction = NULL;
+
+ switch ((*aItr)->nActionType)
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ {
+ pAction = CreateInsertAction(static_cast<ScMyInsAction*>(*aItr));
+ }
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ {
+ ScMyDelAction* pDelAct = static_cast<ScMyDelAction*>(*aItr);
+ pAction = CreateDeleteAction(pDelAct);
+ CreateGeneratedActions(pDelAct->aGeneratedList);
+ }
+ break;
+ case SC_CAT_MOVE:
+ {
+ ScMyMoveAction* pMovAct = static_cast<ScMyMoveAction*>(*aItr);
+ pAction = CreateMoveAction(pMovAct);
+ CreateGeneratedActions(pMovAct->aGeneratedList);
+ }
+ break;
+ case SC_CAT_CONTENT:
+ {
+ pAction = CreateContentAction(static_cast<ScMyContentAction*>(*aItr));
+ }
+ break;
+ case SC_CAT_REJECT:
+ {
+ pAction = CreateRejectionAction(static_cast<ScMyRejAction*>(*aItr));
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (pAction)
+ pTrack->AppendLoaded(pAction);
+ else
+ {
+ OSL_FAIL("no action");
+ }
+
+ ++aItr;
+ }
+ if (pTrack->GetLast())
+ pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber());
+
+ aItr = aActions.begin();
+ aEndItr = aActions.end();
+ while (aItr != aEndItr)
+ {
+ SetDependencies(*aItr);
+
+ if ((*aItr)->nActionType == SC_CAT_CONTENT)
+ ++aItr;
+ else
+ {
+ if (*aItr)
+ delete (*aItr);
+ aItr = aActions.erase(aItr);
+ }
+ }
+
+ aItr = aActions.begin();
+ aEndItr = aActions.end();
+ while (aItr != aEndItr)
+ {
+ DBG_ASSERT((*aItr)->nActionType == SC_CAT_CONTENT, "wrong action type");
+ SetNewCell(static_cast<ScMyContentAction*>(*aItr));
+ if (*aItr)
+ delete (*aItr);
+ aItr = aActions.erase(aItr);
+ }
+ if (aProtect.getLength())
+ pTrack->SetProtection(aProtect);
+ else if (pDoc->GetChangeTrack() && pDoc->GetChangeTrack()->IsProtected())
+ pTrack->SetProtection(pDoc->GetChangeTrack()->GetProtection());
+
+ if ( pTrack->GetLast() )
+ pTrack->SetLastSavedActionNumber(pTrack->GetLast()->GetActionNumber());
+
+ pDoc->SetChangeTrack(pTrack);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx
new file mode 100644
index 000000000000..5a98df08a2c7
--- /dev/null
+++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCHANGETRACKINGIMPORTHELPER_HXX
+#define SC_XMLCHANGETRACKINGIMPORTHELPER_HXX
+
+#include "chgtrack.hxx"
+#include <list>
+#include <com/sun/star/util/DateTime.hpp>
+
+class ScBaseCell;
+class ScDocument;
+class DateTime;
+
+struct ScMyActionInfo
+{
+ rtl::OUString sUser;
+ rtl::OUString sComment;
+ com::sun::star::util::DateTime aDateTime;
+};
+
+struct ScMyCellInfo
+{
+ ScBaseCell* pCell;
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ String sInputString;
+ double fValue;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+
+ ScMyCellInfo(ScBaseCell* pCell, const rtl::OUString& sFormulaAddress, const rtl::OUString& sFormula,
+ const formula::FormulaGrammar::Grammar eGrammar, const rtl::OUString& sInputString,
+ const double& fValue, const sal_uInt16 nType, const sal_uInt8 nMatrixFlag, const sal_Int32 nMatrixCols,
+ const sal_Int32 nMatrixRows);
+ ~ScMyCellInfo();
+
+ ScBaseCell* CreateCell(ScDocument* pDoc);
+
+private:
+ ScMyCellInfo(); // disabled
+};
+
+struct ScMyDeleted
+{
+ sal_uInt32 nID;
+ ScMyCellInfo* pCellInfo;
+
+ ScMyDeleted();
+ ~ScMyDeleted();
+};
+
+typedef std::list<ScMyDeleted*> ScMyDeletedList;
+
+struct ScMyGenerated
+{
+ ScBigRange aBigRange;
+ sal_uInt32 nID;
+ ScMyCellInfo* pCellInfo;
+
+ ScMyGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange);
+ ~ScMyGenerated();
+};
+
+typedef std::list<ScMyGenerated*> ScMyGeneratedList;
+
+struct ScMyInsertionCutOff
+{
+ sal_uInt32 nID;
+ sal_Int32 nPosition;
+
+ ScMyInsertionCutOff(const sal_uInt32 nTempID, const sal_Int32 nTempPosition) :
+ nID(nTempID), nPosition(nTempPosition) {}
+};
+
+struct ScMyMoveCutOff
+{
+ sal_uInt32 nID;
+ sal_Int32 nStartPosition;
+ sal_Int32 nEndPosition;
+
+ ScMyMoveCutOff(const sal_uInt32 nTempID, const sal_Int32 nStartPos, const sal_Int32 nEndPos) :
+ nID(nTempID), nStartPosition(nStartPos), nEndPosition(nEndPos) {}
+};
+
+typedef std::list<ScMyMoveCutOff> ScMyMoveCutOffs;
+
+struct ScMyMoveRanges
+{
+ ScBigRange aSourceRange;
+ ScBigRange aTargetRange;
+
+ ScMyMoveRanges(const ScBigRange& aSource, const ScBigRange aTarget) :
+ aSourceRange(aSource), aTargetRange(aTarget) {}
+};
+
+typedef std::list<sal_uInt32> ScMyDependencies;
+
+struct ScMyBaseAction
+{
+ ScMyActionInfo aInfo;
+ ScBigRange aBigRange;
+ ScMyDependencies aDependencies;
+ ScMyDeletedList aDeletedList;
+ sal_uInt32 nActionNumber;
+ sal_uInt32 nRejectingNumber;
+ sal_uInt32 nPreviousAction;
+ ScChangeActionType nActionType;
+ ScChangeActionState nActionState;
+
+ ScMyBaseAction(const ScChangeActionType nActionType);
+ virtual ~ScMyBaseAction();
+};
+
+struct ScMyInsAction : public ScMyBaseAction
+{
+ ScMyInsAction(const ScChangeActionType nActionType);
+ ~ScMyInsAction();
+};
+
+struct ScMyDelAction : public ScMyBaseAction
+{
+ ScMyGeneratedList aGeneratedList;
+ ScMyInsertionCutOff* pInsCutOff;
+ ScMyMoveCutOffs aMoveCutOffs;
+ sal_Int32 nD;
+
+ ScMyDelAction(const ScChangeActionType nActionType);
+ ~ScMyDelAction();
+};
+
+struct ScMyMoveAction : public ScMyBaseAction
+{
+ ScMyGeneratedList aGeneratedList;
+ ScMyMoveRanges* pMoveRanges;
+
+ ScMyMoveAction();
+ ~ScMyMoveAction();
+};
+
+struct ScMyContentAction : public ScMyBaseAction
+{
+ ScMyCellInfo* pCellInfo;
+
+ ScMyContentAction();
+ ~ScMyContentAction();
+};
+
+struct ScMyRejAction : public ScMyBaseAction
+{
+ ScMyRejAction();
+ ~ScMyRejAction();
+};
+
+typedef std::list<ScMyBaseAction*> ScMyActions;
+
+class ScChangeViewSettings;
+
+class ScXMLChangeTrackingImportHelper
+{
+ ScStrCollection aUsers;
+ ScMyActions aActions;
+ com::sun::star::uno::Sequence<sal_Int8> aProtect;
+ ScDocument* pDoc;
+ ScChangeTrack* pTrack;
+ ScMyBaseAction* pCurrentAction;
+ rtl::OUString sIDPrefix;
+ sal_uInt32 nPrefixLength;
+ sal_Int16 nMultiSpanned;
+ sal_Int16 nMultiSpannedSlaveCount;
+ sal_Bool bChangeTrack;
+
+private:
+ void ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime);
+ ScChangeAction* CreateInsertAction(ScMyInsAction* pAction);
+ ScChangeAction* CreateDeleteAction(ScMyDelAction* pAction);
+ ScChangeAction* CreateMoveAction(ScMyMoveAction* pAction);
+ ScChangeAction* CreateRejectionAction(ScMyRejAction* pAction);
+ ScChangeAction* CreateContentAction(ScMyContentAction* pAction);
+
+ void CreateGeneratedActions(ScMyGeneratedList& rList);
+
+public:
+ ScXMLChangeTrackingImportHelper();
+ ~ScXMLChangeTrackingImportHelper();
+
+ void SetChangeTrack(sal_Bool bValue) { bChangeTrack = bValue; }
+ void SetProtection(const com::sun::star::uno::Sequence<sal_Int8>& rProtect) { aProtect = rProtect; }
+ void StartChangeAction(const ScChangeActionType nActionType);
+
+ sal_uInt32 GetIDFromString(const rtl::OUString& sID);
+
+ void SetActionNumber(const sal_uInt32 nActionNumber) { pCurrentAction->nActionNumber = nActionNumber; }
+ void SetActionState(const ScChangeActionState nActionState) { pCurrentAction->nActionState = nActionState; }
+ void SetRejectingNumber(const sal_uInt32 nRejectingNumber) { pCurrentAction->nRejectingNumber = nRejectingNumber; }
+ void SetActionInfo(const ScMyActionInfo& aInfo);
+ void SetBigRange(const ScBigRange& aBigRange) { pCurrentAction->aBigRange = aBigRange; }
+ void SetPreviousChange(const sal_uInt32 nPreviousAction, ScMyCellInfo* pCellInfo);
+ void SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable);
+ void AddDependence(const sal_uInt32 nID) { pCurrentAction->aDependencies.push_front(nID); }
+ void AddDeleted(const sal_uInt32 nID);
+ void AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo);
+ void SetMultiSpanned(const sal_Int16 nMultiSpanned);
+ void SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition);
+ void AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition);
+ void SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange);
+ void GetMultiSpannedRange();
+ void AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange);
+
+ void EndChangeAction();
+
+ void SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct);
+ void SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct);
+ void SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent);
+ void SetDependencies(ScMyBaseAction* pAction);
+
+ void SetNewCell(ScMyContentAction* pAction);
+
+ void CreateChangeTrack(ScDocument* pDoc);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCodeNameProvider.cxx b/sc/source/filter/xml/XMLCodeNameProvider.cxx
new file mode 100644
index 000000000000..0a0a825ceb31
--- /dev/null
+++ b/sc/source/filter/xml/XMLCodeNameProvider.cxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "XMLCodeNameProvider.hxx"
+#include "document.hxx"
+
+using namespace com::sun::star;
+
+using ::rtl::OUString;
+
+sal_Bool XMLCodeNameProvider::_getCodeName( const uno::Any& aAny, String& rCodeName )
+{
+ uno::Sequence<beans::PropertyValue> aProps;
+ if( !(aAny >>= aProps) )
+ return false;
+
+ OUString sCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") );
+ sal_Int32 nPropCount = aProps.getLength();
+ for( sal_Int32 i=0; i<nPropCount; i++ )
+ {
+ if( aProps[i].Name == sCodeNameProp )
+ {
+ OUString sCodeName;
+ if( aProps[i].Value >>= sCodeName )
+ {
+ rCodeName = sCodeName;
+ return sal_True;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+XMLCodeNameProvider::XMLCodeNameProvider( ScDocument* pDoc ) :
+ mpDoc( pDoc ),
+ msDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ),
+ msCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") )
+{
+}
+
+XMLCodeNameProvider::~XMLCodeNameProvider()
+{
+}
+
+::sal_Bool SAL_CALL XMLCodeNameProvider::hasByName( const OUString& aName )
+ throw (uno::RuntimeException )
+{
+ if( aName == msDocName )
+ return mpDoc->GetCodeName().Len() > 0;
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sName( aName );
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ return sCodeName.Len() > 0;
+ }
+ }
+
+ return false;
+}
+
+uno::Any SAL_CALL XMLCodeNameProvider::getByName( const OUString& aName )
+ throw (container::NoSuchElementException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aRet;
+ uno::Sequence<beans::PropertyValue> aProps(1);
+ aProps[0].Name = msCodeNameProp;
+ if( aName == msDocName )
+ {
+ OUString sUCodeName( mpDoc->GetCodeName() );
+ aProps[0].Value <<= sUCodeName;
+ aRet <<= aProps;
+ return aRet;
+ }
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sName( aName );
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ OUString sUCodeName( sCodeName );
+ aProps[0].Value <<= sUCodeName;
+ aRet <<= aProps;
+ return aRet;
+ }
+ }
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SAL_CALL XMLCodeNameProvider::getElementNames( )
+ throw (uno::RuntimeException)
+{
+ SCTAB nCount = mpDoc->GetTableCount() + 1;
+ uno::Sequence< OUString > aNames( nCount );
+ sal_Int32 nRealCount = 0;
+
+ if( mpDoc->GetCodeName().Len() )
+ aNames[nRealCount++] = msDocName;
+
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ if( sCodeName.Len() > 0 )
+ {
+ if( mpDoc->GetName( i, sSheetName ) )
+ aNames[nRealCount++] = sSheetName;
+ }
+ }
+
+ if( nCount != nRealCount )
+ aNames.realloc( nRealCount );
+
+ return aNames;
+}
+
+uno::Type SAL_CALL XMLCodeNameProvider::getElementType( )
+ throw (uno::RuntimeException)
+{
+ return getCppuType(static_cast<uno::Sequence<beans::PropertyValue>*>(0));
+}
+
+::sal_Bool SAL_CALL XMLCodeNameProvider::hasElements()
+ throw (uno::RuntimeException )
+{
+ if( mpDoc->GetCodeName().Len() > 0 )
+ return sal_True;
+
+ SCTAB nCount = mpDoc->GetTableCount();
+ String sSheetName, sCodeName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ mpDoc->GetCodeName( i, sCodeName );
+ if( sCodeName.Len() > 0 && mpDoc->GetName( i, sSheetName ) )
+ return sal_True;
+ }
+
+ return false;
+}
+
+void XMLCodeNameProvider::set( const uno::Reference< container::XNameAccess>& xNameAccess, ScDocument *pDoc )
+{
+ uno::Any aAny;
+ OUString sDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") );
+ String sCodeName;
+ if( xNameAccess->hasByName( sDocName ) )
+ {
+ aAny = xNameAccess->getByName( sDocName );
+ if( _getCodeName( aAny, sCodeName ) )
+ pDoc->SetCodeName( sCodeName );
+ }
+
+ SCTAB nCount = pDoc->GetTableCount();
+ String sSheetName;
+ for( SCTAB i = 0; i < nCount; i++ )
+ {
+ if( pDoc->GetName( i, sSheetName ) &&
+ xNameAccess->hasByName( sSheetName ) )
+ {
+ aAny = xNameAccess->getByName( sSheetName );
+ if( _getCodeName( aAny, sCodeName ) )
+ pDoc->SetCodeName( i, sCodeName );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLCodeNameProvider.hxx b/sc/source/filter/xml/XMLCodeNameProvider.hxx
new file mode 100644
index 000000000000..81a5b5e3ebdc
--- /dev/null
+++ b/sc/source/filter/xml/XMLCodeNameProvider.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCODENAMEPROVIDER_HXX
+#define SC_XMLCODENAMEPROVIDER_HXX
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class ScDocument;
+class String;
+
+class XMLCodeNameProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameAccess >
+{
+ ScDocument* mpDoc;
+ ::rtl::OUString msDocName;
+ ::rtl::OUString msCodeNameProp;
+
+ static sal_Bool _getCodeName( const ::com::sun::star::uno::Any& aAny,
+ String& rCodeName );
+
+public:
+ XMLCodeNameProvider( ScDocument* pDoc );
+ virtual ~XMLCodeNameProvider();
+
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException );
+
+ static void set( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNameAccess, ScDocument *pDoc );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.cxx b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx
new file mode 100644
index 000000000000..858adcffeb6f
--- /dev/null
+++ b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLColumnRowGroupExport.hxx"
+#include "xmlexprt.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+
+#include <algorithm>
+
+using namespace xmloff::token;
+
+ScMyColumnRowGroup::ScMyColumnRowGroup()
+{
+}
+
+sal_Bool ScMyColumnRowGroup::operator<(const ScMyColumnRowGroup& rGroup) const
+{
+ if (rGroup.nField > nField)
+ return sal_True;
+ else
+ if (rGroup.nField == nField && rGroup.nLevel > nLevel)
+ return sal_True;
+ else
+ return false;
+}
+
+ScMyOpenCloseColumnRowGroup::ScMyOpenCloseColumnRowGroup(ScXMLExport& rTempExport, sal_uInt32 nToken)
+ : rExport(rTempExport),
+ rName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XMLTokenEnum(nToken)))),
+ aTableStart(),
+ aTableEnd()
+{
+}
+
+ScMyOpenCloseColumnRowGroup::~ScMyOpenCloseColumnRowGroup()
+{
+}
+
+void ScMyOpenCloseColumnRowGroup::NewTable()
+{
+ aTableStart.clear();
+ aTableEnd.clear();
+}
+
+void ScMyOpenCloseColumnRowGroup::AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField)
+{
+ aTableStart.push_back(aGroup);
+ aTableEnd.push_back(nEndField);
+}
+
+sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupStart(const sal_Int32 nField)
+{
+ sal_Bool bGroupStart(false);
+ if (!aTableStart.empty())
+ {
+ ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin());
+ sal_Int32 nItrField = aItr->nField;
+ if ( nItrField < nField )
+ {
+ // when used to find repeated rows at the beginning of a group,
+ // aTableStart may contain entries before nField. They must be skipped here
+ // (they will be used for OpenGroups later in the right order).
+
+ ScMyColumnRowGroupVec::iterator aEnd(aTableStart.end());
+ while ( aItr != aEnd && nItrField < nField )
+ {
+ ++aItr;
+ if ( aItr != aEnd )
+ nItrField = aItr->nField;
+ }
+ }
+
+ if (nItrField == nField)
+ bGroupStart = sal_True;
+ }
+ return bGroupStart;
+}
+
+void ScMyOpenCloseColumnRowGroup::OpenGroup(const ScMyColumnRowGroup& rGroup)
+{
+ if (!rGroup.bDisplay)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ rExport.StartElement( rName, sal_True);
+}
+
+void ScMyOpenCloseColumnRowGroup::OpenGroups(const sal_Int32 nField)
+{
+ ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin());
+ ScMyColumnRowGroupVec::iterator aEndItr(aTableStart.end());
+ sal_Bool bReady(false);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (aItr->nField == nField)
+ {
+ OpenGroup(*aItr);
+ aItr = aTableStart.erase(aItr);
+ }
+ else
+ bReady = sal_True;
+ }
+}
+
+sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupEnd(const sal_Int32 nField)
+{
+ sal_Bool bGroupEnd(false);
+ if (!aTableEnd.empty())
+ {
+ if (*(aTableEnd.begin()) == nField)
+ bGroupEnd = sal_True;
+ }
+ return bGroupEnd;
+}
+
+void ScMyOpenCloseColumnRowGroup::CloseGroup()
+{
+ rExport.EndElement( rName, sal_True );
+}
+
+void ScMyOpenCloseColumnRowGroup::CloseGroups(const sal_Int32 nField)
+{
+ ScMyFieldGroupVec::iterator aItr(aTableEnd.begin());
+ ScMyFieldGroupVec::iterator aEndItr(aTableEnd.end());
+ sal_Bool bReady(false);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (*aItr == nField)
+ {
+ CloseGroup();
+ aItr = aTableEnd.erase(aItr);
+ }
+ else
+ bReady = sal_True;
+ }
+}
+
+sal_Int32 ScMyOpenCloseColumnRowGroup::GetLast()
+{
+ sal_Int32 maximum(-1);
+ ScMyFieldGroupVec::iterator i(aTableEnd.begin());
+ ScMyFieldGroupVec::iterator endi(aTableEnd.end());
+ while (i != endi)
+ {
+ if (*i > maximum)
+ maximum = *i;
+ ++i;
+ }
+ return maximum;
+}
+
+void ScMyOpenCloseColumnRowGroup::Sort()
+{
+ aTableStart.sort();
+ aTableEnd.sort();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.hxx b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx
new file mode 100644
index 000000000000..37608b737f5e
--- /dev/null
+++ b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCOLUMNROWGROUPEXPORT_HXX
+#define SC_XMLCOLUMNROWGROUPEXPORT_HXX
+
+#include <list>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+struct ScMyColumnRowGroup
+{
+ sal_Int32 nField;
+ sal_Int16 nLevel;
+ sal_Bool bDisplay;
+
+ ScMyColumnRowGroup();
+ sal_Bool operator< (const ScMyColumnRowGroup& rGroup) const;
+};
+
+typedef std::list <ScMyColumnRowGroup> ScMyColumnRowGroupVec;
+typedef std::list <sal_Int32> ScMyFieldGroupVec;
+
+class ScXMLExport;
+class ScMyOpenCloseColumnRowGroup
+{
+ ScXMLExport& rExport;
+ const rtl::OUString rName;
+ ScMyColumnRowGroupVec aTableStart;
+ ScMyFieldGroupVec aTableEnd;
+
+ void OpenGroup(const ScMyColumnRowGroup& rGroup);
+ void CloseGroup();
+public:
+ ScMyOpenCloseColumnRowGroup(ScXMLExport& rExport, sal_uInt32 nToken);
+ ~ScMyOpenCloseColumnRowGroup();
+
+ void NewTable();
+ void AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField);
+ sal_Bool IsGroupStart(const sal_Int32 nField);
+ void OpenGroups(const sal_Int32 nField);
+ sal_Bool IsGroupEnd(const sal_Int32 nField);
+ void CloseGroups(const sal_Int32 nField);
+ sal_Int32 GetLast();
+ void Sort();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLConsolidationContext.cxx b/sc/source/filter/xml/XMLConsolidationContext.cxx
new file mode 100644
index 000000000000..5f96bad52719
--- /dev/null
+++ b/sc/source/filter/xml/XMLConsolidationContext.cxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLConsolidationContext.hxx"
+#include "document.hxx"
+#include "rangeutl.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScXMLConsolidationContext::ScXMLConsolidationContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ eFunction( SUBTOTAL_FUNC_NONE ),
+ bLinkToSource( false ),
+ bTargetAddr(false)
+{
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetConsolidationAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONSOLIDATION_ATTR_FUNCTION:
+ eFunction = ScXMLConverter::GetSubTotalFuncFromString( sValue );
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES:
+ sSourceList = sValue;
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS:
+ {
+ sal_Int32 nOffset(0);
+ bTargetAddr = ScRangeStringConverter::GetAddressFromString(
+ aTargetAddr, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ }
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_USE_LABEL:
+ sUseLabel = sValue;
+ break;
+ case XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE:
+ bLinkToSource = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLConsolidationContext::~ScXMLConsolidationContext()
+{
+}
+
+SvXMLImportContext *ScXMLConsolidationContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLConsolidationContext::EndElement()
+{
+ if (bTargetAddr)
+ {
+ ScConsolidateParam aConsParam;
+ aConsParam.nCol = aTargetAddr.Col();
+ aConsParam.nRow = aTargetAddr.Row();
+ aConsParam.nTab = aTargetAddr.Tab();
+ aConsParam.eFunction = eFunction;
+
+ sal_uInt16 nCount = (sal_uInt16) Min( ScRangeStringConverter::GetTokenCount( sSourceList ), (sal_Int32)0xFFFF );
+ ScArea** ppAreas = nCount ? new ScArea*[ nCount ] : NULL;
+ if( ppAreas )
+ {
+ sal_Int32 nOffset = 0;
+ sal_uInt16 nIndex;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ppAreas[ nIndex ] = new ScArea;
+ if ( !ScRangeStringConverter::GetAreaFromString(
+ *ppAreas[ nIndex ], sSourceList, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ) )
+ {
+ //! handle error
+ }
+ }
+
+ aConsParam.SetAreas( ppAreas, nCount );
+
+ // array is copied in SetAreas
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ delete ppAreas[nIndex];
+ delete[] ppAreas;
+ }
+
+ aConsParam.bByCol = aConsParam.bByRow = false;
+ if( IsXMLToken(sUseLabel, XML_COLUMN ) )
+ aConsParam.bByCol = sal_True;
+ else if( IsXMLToken( sUseLabel, XML_ROW ) )
+ aConsParam.bByRow = sal_True;
+ else if( IsXMLToken( sUseLabel, XML_BOTH ) )
+ aConsParam.bByCol = aConsParam.bByRow = sal_True;
+
+ aConsParam.bReferenceData = bLinkToSource;
+
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if( pDoc )
+ pDoc->SetConsolidateDlgData( &aConsParam );
+ }
+ GetScImport().UnlockSolarMutex();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLConsolidationContext.hxx b/sc/source/filter/xml/XMLConsolidationContext.hxx
new file mode 100644
index 000000000000..eabf35031dbf
--- /dev/null
+++ b/sc/source/filter/xml/XMLConsolidationContext.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCONSOLIDATIONCONTEXT_HXX
+#define SC_XMLCONSOLIDATIONCONTEXT_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+class ScXMLConsolidationContext : public SvXMLImportContext
+{
+private:
+ ::rtl::OUString sSourceList;
+ ::rtl::OUString sUseLabel;
+ ScAddress aTargetAddr;
+ ScSubTotalFunc eFunction;
+ sal_Bool bLinkToSource;
+ sal_Bool bTargetAddr;
+
+protected:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLConsolidationContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual ~ScXMLConsolidationContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx
new file mode 100644
index 000000000000..5fafe505398a
--- /dev/null
+++ b/sc/source/filter/xml/XMLConverter.cxx
@@ -0,0 +1,665 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XMLConverter.hxx"
+#include <com/sun/star/util/DateTime.hpp>
+#include <tools/datetime.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "rangelst.hxx"
+#include "rangeutl.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "document.hxx"
+#include "ftools.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScDocument* ScXMLConverter::GetScDocument( uno::Reference< frame::XModel > xModel )
+{
+ if (xModel.is())
+ {
+ ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
+ return pDocObj ? pDocObj->GetDocument() : NULL;
+ }
+ return NULL;
+}
+
+
+//___________________________________________________________________
+sheet::GeneralFunction ScXMLConverter::GetFunctionFromString( const OUString& sFunction )
+{
+ if( IsXMLToken(sFunction, XML_SUM ) )
+ return sheet::GeneralFunction_SUM;
+ if( IsXMLToken(sFunction, XML_AUTO ) )
+ return sheet::GeneralFunction_AUTO;
+ if( IsXMLToken(sFunction, XML_COUNT ) )
+ return sheet::GeneralFunction_COUNT;
+ if( IsXMLToken(sFunction, XML_COUNTNUMS ) )
+ return sheet::GeneralFunction_COUNTNUMS;
+ if( IsXMLToken(sFunction, XML_PRODUCT ) )
+ return sheet::GeneralFunction_PRODUCT;
+ if( IsXMLToken(sFunction, XML_AVERAGE ) )
+ return sheet::GeneralFunction_AVERAGE;
+ if( IsXMLToken(sFunction, XML_MAX ) )
+ return sheet::GeneralFunction_MAX;
+ if( IsXMLToken(sFunction, XML_MIN ) )
+ return sheet::GeneralFunction_MIN;
+ if( IsXMLToken(sFunction, XML_STDEV ) )
+ return sheet::GeneralFunction_STDEV;
+ if( IsXMLToken(sFunction, XML_STDEVP ) )
+ return sheet::GeneralFunction_STDEVP;
+ if( IsXMLToken(sFunction, XML_VAR ) )
+ return sheet::GeneralFunction_VAR;
+ if( IsXMLToken(sFunction, XML_VARP ) )
+ return sheet::GeneralFunction_VARP;
+ return sheet::GeneralFunction_NONE;
+}
+
+ScSubTotalFunc ScXMLConverter::GetSubTotalFuncFromString( const OUString& sFunction )
+{
+ if( IsXMLToken(sFunction, XML_SUM ) )
+ return SUBTOTAL_FUNC_SUM;
+ if( IsXMLToken(sFunction, XML_COUNT ) )
+ return SUBTOTAL_FUNC_CNT;
+ if( IsXMLToken(sFunction, XML_COUNTNUMS ) )
+ return SUBTOTAL_FUNC_CNT2;
+ if( IsXMLToken(sFunction, XML_PRODUCT ) )
+ return SUBTOTAL_FUNC_PROD;
+ if( IsXMLToken(sFunction, XML_AVERAGE ) )
+ return SUBTOTAL_FUNC_AVE;
+ if( IsXMLToken(sFunction, XML_MAX ) )
+ return SUBTOTAL_FUNC_MAX;
+ if( IsXMLToken(sFunction, XML_MIN ) )
+ return SUBTOTAL_FUNC_MIN;
+ if( IsXMLToken(sFunction, XML_STDEV ) )
+ return SUBTOTAL_FUNC_STD;
+ if( IsXMLToken(sFunction, XML_STDEVP ) )
+ return SUBTOTAL_FUNC_STDP;
+ if( IsXMLToken(sFunction, XML_VAR ) )
+ return SUBTOTAL_FUNC_VAR;
+ if( IsXMLToken(sFunction, XML_VARP ) )
+ return SUBTOTAL_FUNC_VARP;
+ return SUBTOTAL_FUNC_NONE;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromFunction(
+ OUString& rString,
+ const sheet::GeneralFunction eFunction,
+ sal_Bool bAppendStr )
+{
+ OUString sFuncStr;
+ switch( eFunction )
+ {
+ case sheet::GeneralFunction_AUTO: sFuncStr = GetXMLToken( XML_AUTO ); break;
+ case sheet::GeneralFunction_AVERAGE: sFuncStr = GetXMLToken( XML_AVERAGE ); break;
+ case sheet::GeneralFunction_COUNT: sFuncStr = GetXMLToken( XML_COUNT ); break;
+ case sheet::GeneralFunction_COUNTNUMS: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break;
+ case sheet::GeneralFunction_MAX: sFuncStr = GetXMLToken( XML_MAX ); break;
+ case sheet::GeneralFunction_MIN: sFuncStr = GetXMLToken( XML_MIN ); break;
+ case sheet::GeneralFunction_NONE: sFuncStr = GetXMLToken( XML_NONE ); break;
+ case sheet::GeneralFunction_PRODUCT: sFuncStr = GetXMLToken( XML_PRODUCT ); break;
+ case sheet::GeneralFunction_STDEV: sFuncStr = GetXMLToken( XML_STDEV ); break;
+ case sheet::GeneralFunction_STDEVP: sFuncStr = GetXMLToken( XML_STDEVP ); break;
+ case sheet::GeneralFunction_SUM: sFuncStr = GetXMLToken( XML_SUM ); break;
+ case sheet::GeneralFunction_VAR: sFuncStr = GetXMLToken( XML_VAR ); break;
+ case sheet::GeneralFunction_VARP: sFuncStr = GetXMLToken( XML_VARP ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr );
+}
+
+void ScXMLConverter::GetStringFromFunction(
+ OUString& rString,
+ const ScSubTotalFunc eFunction,
+ sal_Bool bAppendStr )
+{
+ OUString sFuncStr;
+ switch( eFunction )
+ {
+ case SUBTOTAL_FUNC_AVE: sFuncStr = GetXMLToken( XML_AVERAGE ); break;
+ case SUBTOTAL_FUNC_CNT: sFuncStr = GetXMLToken( XML_COUNT ); break;
+ case SUBTOTAL_FUNC_CNT2: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break;
+ case SUBTOTAL_FUNC_MAX: sFuncStr = GetXMLToken( XML_MAX ); break;
+ case SUBTOTAL_FUNC_MIN: sFuncStr = GetXMLToken( XML_MIN ); break;
+ case SUBTOTAL_FUNC_NONE: sFuncStr = GetXMLToken( XML_NONE ); break;
+ case SUBTOTAL_FUNC_PROD: sFuncStr = GetXMLToken( XML_PRODUCT ); break;
+ case SUBTOTAL_FUNC_STD: sFuncStr = GetXMLToken( XML_STDEV ); break;
+ case SUBTOTAL_FUNC_STDP: sFuncStr = GetXMLToken( XML_STDEVP ); break;
+ case SUBTOTAL_FUNC_SUM: sFuncStr = GetXMLToken( XML_SUM ); break;
+ case SUBTOTAL_FUNC_VAR: sFuncStr = GetXMLToken( XML_VAR ); break;
+ case SUBTOTAL_FUNC_VARP: sFuncStr = GetXMLToken( XML_VARP ); break;
+ }
+ ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+sheet::DataPilotFieldOrientation ScXMLConverter::GetOrientationFromString(
+ const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_COLUMN ) )
+ return sheet::DataPilotFieldOrientation_COLUMN;
+ if( IsXMLToken(rString, XML_ROW ) )
+ return sheet::DataPilotFieldOrientation_ROW;
+ if( IsXMLToken(rString, XML_PAGE ) )
+ return sheet::DataPilotFieldOrientation_PAGE;
+ if( IsXMLToken(rString, XML_DATA ) )
+ return sheet::DataPilotFieldOrientation_DATA;
+ return sheet::DataPilotFieldOrientation_HIDDEN;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromOrientation(
+ OUString& rString,
+ const sheet::DataPilotFieldOrientation eOrientation,
+ sal_Bool bAppendStr )
+{
+ OUString sOrientStr;
+ switch( eOrientation )
+ {
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ sOrientStr = GetXMLToken( XML_HIDDEN );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ sOrientStr = GetXMLToken( XML_COLUMN );
+ break;
+ case sheet::DataPilotFieldOrientation_ROW:
+ sOrientStr = GetXMLToken( XML_ROW );
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ sOrientStr = GetXMLToken( XML_PAGE );
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ sOrientStr = GetXMLToken( XML_DATA );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sOrientStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+ScDetectiveObjType ScXMLConverter::GetDetObjTypeFromString( const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_FROM_SAME_TABLE ) )
+ return SC_DETOBJ_ARROW;
+ if( IsXMLToken(rString, XML_FROM_ANOTHER_TABLE ) )
+ return SC_DETOBJ_FROMOTHERTAB;
+ if( IsXMLToken(rString, XML_TO_ANOTHER_TABLE ) )
+ return SC_DETOBJ_TOOTHERTAB;
+ return SC_DETOBJ_NONE;
+}
+
+sal_Bool ScXMLConverter::GetDetOpTypeFromString( ScDetOpType& rDetOpType, const OUString& rString )
+{
+ if( IsXMLToken(rString, XML_TRACE_DEPENDENTS ) )
+ rDetOpType = SCDETOP_ADDSUCC;
+ else if( IsXMLToken(rString, XML_TRACE_PRECEDENTS ) )
+ rDetOpType = SCDETOP_ADDPRED;
+ else if( IsXMLToken(rString, XML_TRACE_ERRORS ) )
+ rDetOpType = SCDETOP_ADDERROR;
+ else if( IsXMLToken(rString, XML_REMOVE_DEPENDENTS ) )
+ rDetOpType = SCDETOP_DELSUCC;
+ else if( IsXMLToken(rString, XML_REMOVE_PRECEDENTS ) )
+ rDetOpType = SCDETOP_DELPRED;
+ else
+ return false;
+ return sal_True;
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::GetStringFromDetObjType(
+ OUString& rString,
+ const ScDetectiveObjType eObjType,
+ sal_Bool bAppendStr )
+{
+ OUString sTypeStr;
+ switch( eObjType )
+ {
+ case SC_DETOBJ_ARROW:
+ sTypeStr = GetXMLToken( XML_FROM_SAME_TABLE );
+ break;
+ case SC_DETOBJ_FROMOTHERTAB:
+ sTypeStr = GetXMLToken( XML_FROM_ANOTHER_TABLE );
+ break;
+ case SC_DETOBJ_TOOTHERTAB:
+ sTypeStr = GetXMLToken( XML_TO_ANOTHER_TABLE );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr );
+}
+
+void ScXMLConverter::GetStringFromDetOpType(
+ OUString& rString,
+ const ScDetOpType eOpType,
+ sal_Bool bAppendStr )
+{
+ OUString sTypeStr;
+ switch( eOpType )
+ {
+ case SCDETOP_ADDSUCC:
+ sTypeStr = GetXMLToken( XML_TRACE_DEPENDENTS );
+ break;
+ case SCDETOP_ADDPRED:
+ sTypeStr = GetXMLToken( XML_TRACE_PRECEDENTS );
+ break;
+ case SCDETOP_ADDERROR:
+ sTypeStr = GetXMLToken( XML_TRACE_ERRORS );
+ break;
+ case SCDETOP_DELSUCC:
+ sTypeStr = GetXMLToken( XML_REMOVE_DEPENDENTS );
+ break;
+ case SCDETOP_DELPRED:
+ sTypeStr = GetXMLToken( XML_REMOVE_PRECEDENTS );
+ break;
+ }
+ ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr );
+}
+
+
+//___________________________________________________________________
+
+void ScXMLConverter::ParseFormula(OUString& sFormula, const sal_Bool bIsFormula)
+{
+ OUStringBuffer sBuffer(sFormula.getLength());
+ sal_Bool bInQuotationMarks(false);
+ sal_Bool bInDoubleQuotationMarks(false);
+ sal_Int16 nCountBraces(0);
+ sal_Unicode chPrevious('=');
+ for (sal_Int32 i = 0; i < sFormula.getLength(); ++i)
+ {
+ if (sFormula[i] == '\'' && !bInDoubleQuotationMarks &&
+ chPrevious != '\\')
+ bInQuotationMarks = !bInQuotationMarks;
+ else if (sFormula[i] == '"' && !bInQuotationMarks)
+ bInDoubleQuotationMarks = !bInDoubleQuotationMarks;
+ if (bInQuotationMarks || bInDoubleQuotationMarks)
+ sBuffer.append(sFormula[i]);
+ else if (sFormula[i] == '[')
+ ++nCountBraces;
+ else if (sFormula[i] == ']')
+ nCountBraces--;
+ else if ((sFormula[i] != '.') ||
+ ((nCountBraces == 0) && bIsFormula) ||
+ !((chPrevious == '[') || (chPrevious == ':') || (chPrevious == ' ') || (chPrevious == '=')))
+ sBuffer.append(sFormula[i]);
+ chPrevious = sFormula[i];
+ }
+
+ DBG_ASSERT(nCountBraces == 0, "there are some braces still open");
+ sFormula = sBuffer.makeStringAndClear();
+}
+
+
+//_____________________________________________________________________
+
+void ScXMLConverter::ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate)
+{
+ util::DateTime aAPIDateTime;
+ ConvertCoreToAPIDateTime(aDateTime, aAPIDateTime);
+ SvXMLUnitConverter::convertDateTime(sDate, aAPIDateTime);
+}
+
+void ScXMLConverter::ConvertCoreToAPIDateTime(const DateTime& aDateTime, util::DateTime& rDateTime)
+{
+ rDateTime.Year = aDateTime.GetYear();
+ rDateTime.Month = aDateTime.GetMonth();
+ rDateTime.Day = aDateTime.GetDay();
+ rDateTime.Hours = aDateTime.GetHour();
+ rDateTime.Minutes = aDateTime.GetMin();
+ rDateTime.Seconds = aDateTime.GetSec();
+ rDateTime.HundredthSeconds = aDateTime.Get100Sec();
+}
+
+void ScXMLConverter::ConvertAPIToCoreDateTime(const util::DateTime& aDateTime, DateTime& rDateTime)
+{
+ Date aDate(aDateTime.Day, aDateTime.Month, aDateTime.Year);
+ Time aTime(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds);
+ DateTime aTempDateTime (aDate, aTime);
+ rDateTime = aTempDateTime;
+}
+
+// ============================================================================
+
+namespace {
+
+/** Enumerates different types of condition tokens. */
+enum ScXMLConditionTokenType
+{
+ XML_COND_TYPE_KEYWORD, /// Simple keyword without parentheses, e.g. 'and'.
+ XML_COND_TYPE_COMPARISON, /// Comparison rule, e.g. 'cell-content()<=2'.
+ XML_COND_TYPE_FUNCTION0, /// Function without parameters, e.g. 'cell-content-is-whole-number()'.
+ XML_COND_TYPE_FUNCTION1, /// Function with 1 parameter, e.g. 'is-true-formula(1+1=2)'.
+ XML_COND_TYPE_FUNCTION2 /// Function with 2 parameters, e.g. 'cell-content-is-between(1,2)'.
+};
+
+struct ScXMLConditionInfo
+{
+ ScXMLConditionToken meToken;
+ ScXMLConditionTokenType meType;
+ sheet::ValidationType meValidation;
+ sheet::ConditionOperator meOperator;
+ const sal_Char* mpcIdentifier;
+ sal_Int32 mnIdentLength;
+};
+
+static const ScXMLConditionInfo spConditionInfos[] =
+{
+ { XML_COND_AND, XML_COND_TYPE_KEYWORD, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "and" ) },
+ { XML_COND_CELLCONTENT, XML_COND_TYPE_COMPARISON, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content" ) },
+ { XML_COND_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-between" ) },
+ { XML_COND_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-not-between" ) },
+ { XML_COND_ISWHOLENUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_WHOLE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-whole-number" ) },
+ { XML_COND_ISDECIMALNUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DECIMAL, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-decimal-number" ) },
+ { XML_COND_ISDATE, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DATE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-date" ) },
+ { XML_COND_ISTIME, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_TIME, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-time" ) },
+ { XML_COND_ISINLIST, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_LIST, sheet::ConditionOperator_EQUAL, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-in-list" ) },
+ { XML_COND_TEXTLENGTH, XML_COND_TYPE_COMPARISON, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length" ) },
+ { XML_COND_TEXTLENGTH_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-between" ) },
+ { XML_COND_TEXTLENGTH_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-not-between" ) },
+ { XML_COND_ISTRUEFORMULA, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_CUSTOM, sheet::ConditionOperator_FORMULA, RTL_CONSTASCII_STRINGPARAM( "is-true-formula" ) }
+};
+
+void lclSkipWhitespace( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ while( (rpcString < pcEnd) && (*rpcString <= ' ') ) ++rpcString;
+}
+
+const ScXMLConditionInfo* lclGetConditionInfo( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ lclSkipWhitespace( rpcString, pcEnd );
+ /* Search the end of an identifier name; assuming that valid identifiers
+ consist of [a-z-] only. */
+ const sal_Unicode* pcIdStart = rpcString;
+ while( (rpcString < pcEnd) && (((*rpcString >= 'a') && (*rpcString <= 'z')) || (*rpcString == '-')) ) ++rpcString;
+ sal_Int32 nLength = static_cast< sal_Int32 >( rpcString - pcIdStart );
+
+ // search the table for an entry
+ if( nLength > 0 )
+ for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_TABLE_END( spConditionInfos ); ++pInfo )
+ if( (nLength == pInfo->mnIdentLength) && (::rtl_ustr_ascii_shortenedCompare_WithLength( pcIdStart, nLength, pInfo->mpcIdentifier, nLength ) == 0) )
+ return pInfo;
+
+ return 0;
+}
+
+sheet::ConditionOperator lclGetConditionOperator( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ // check for double-char operators
+ if( (rpcString + 1 < pcEnd) && (rpcString[ 1 ] == '=') )
+ {
+ sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+ switch( *rpcString )
+ {
+ case '!': eOperator = sheet::ConditionOperator_NOT_EQUAL; break;
+ case '<': eOperator = sheet::ConditionOperator_LESS_EQUAL; break;
+ case '>': eOperator = sheet::ConditionOperator_GREATER_EQUAL; break;
+ }
+ if( eOperator != sheet::ConditionOperator_NONE )
+ {
+ rpcString += 2;
+ return eOperator;
+ }
+ }
+
+ // check for single-char operators
+ if( rpcString < pcEnd )
+ {
+ sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE;
+ switch( *rpcString )
+ {
+ case '=': eOperator = sheet::ConditionOperator_EQUAL; break;
+ case '<': eOperator = sheet::ConditionOperator_LESS; break;
+ case '>': eOperator = sheet::ConditionOperator_GREATER; break;
+ }
+ if( eOperator != sheet::ConditionOperator_NONE )
+ {
+ ++rpcString;
+ return eOperator;
+ }
+ }
+
+ return sheet::ConditionOperator_NONE;
+}
+
+/** Skips a literal string in a formula expression.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the string
+ following the leading string delimiter character. On return, points to
+ the trailing string delimiter character if existing, otherwise to
+ pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cQuoteChar
+ The string delimiter character enclosing the string.
+ */
+void lclSkipExpressionString( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cQuoteChar )
+{
+ if( rpcString < pcEnd )
+ {
+ sal_Int32 nLength = static_cast< sal_Int32 >( pcEnd - rpcString );
+ sal_Int32 nNextQuote = ::rtl_ustr_indexOfChar_WithLength( rpcString, nLength, cQuoteChar );
+ if( nNextQuote >= 0 )
+ rpcString += nNextQuote;
+ else
+ rpcString = pcEnd;
+ }
+}
+
+/** Skips a formula expression. Processes embedded parentheses, braces, and
+ literal strings.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the expression.
+ On return, points to the passed end character if existing, otherwise to
+ pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cEndChar
+ The termination character following the expression.
+ */
+void lclSkipExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+ while( rpcString < pcEnd )
+ {
+ if( *rpcString == cEndChar )
+ return;
+ switch( *rpcString )
+ {
+ case '(': lclSkipExpression( ++rpcString, pcEnd, ')' ); break;
+ case '{': lclSkipExpression( ++rpcString, pcEnd, '}' ); break;
+ case '"': lclSkipExpressionString( ++rpcString, pcEnd, '"' ); break;
+ case '\'': lclSkipExpressionString( ++rpcString, pcEnd, '\'' ); break;
+ }
+ if( rpcString < pcEnd ) ++rpcString;
+ }
+}
+
+/** Extracts a formula expression. Processes embedded parentheses, braces, and
+ literal strings.
+
+ @param rpcString
+ (in-out) On call, must point to the first character of the expression.
+ On return, points *behind* the passed end character if existing,
+ otherwise to pcEnd.
+
+ @param pcEnd
+ The end of the string to parse.
+
+ @param cEndChar
+ The termination character following the expression.
+ */
+OUString lclGetExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar )
+{
+ OUString aExp;
+ const sal_Unicode* pcExpStart = rpcString;
+ lclSkipExpression( rpcString, pcEnd, cEndChar );
+ if( rpcString < pcEnd )
+ {
+ aExp = OUString( pcExpStart, static_cast< sal_Int32 >( rpcString - pcExpStart ) ).trim();
+ ++rpcString;
+ }
+ return aExp;
+}
+
+/** Tries to skip an empty pair of parentheses (which may contain whitespace
+ characters).
+
+ @return
+ True on success, rpcString points behind the closing parentheses then.
+ */
+bool lclSkipEmptyParentheses( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd )
+{
+ if( (rpcString < pcEnd) && (*rpcString == '(') )
+ {
+ lclSkipWhitespace( ++rpcString, pcEnd );
+ if( (rpcString < pcEnd) && (*rpcString == ')') )
+ {
+ ++rpcString;
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+void ScXMLConditionHelper::parseCondition(
+ ScXMLConditionParseResult& rParseResult, const OUString& rAttribute, sal_Int32 nStartIndex )
+{
+ rParseResult.meToken = XML_COND_INVALID;
+ if( (nStartIndex < 0) || (nStartIndex >= rAttribute.getLength()) ) return;
+
+ // try to find an identifier
+ const sal_Unicode* pcBegin = rAttribute.getStr();
+ const sal_Unicode* pcString = pcBegin + nStartIndex;
+ const sal_Unicode* pcEnd = pcBegin + rAttribute.getLength();
+ if( const ScXMLConditionInfo* pCondInfo = lclGetConditionInfo( pcString, pcEnd ) )
+ {
+ // insert default values into parse result (may be changed below)
+ rParseResult.meValidation = pCondInfo->meValidation;
+ rParseResult.meOperator = pCondInfo->meOperator;
+ // continue parsing dependent on token type
+ switch( pCondInfo->meType )
+ {
+ case XML_COND_TYPE_KEYWORD:
+ // nothing specific has to follow, success
+ rParseResult.meToken = pCondInfo->meToken;
+ break;
+
+ case XML_COND_TYPE_COMPARISON:
+ // format is <condition>()<operator><expression>
+ if( lclSkipEmptyParentheses( pcString, pcEnd ) )
+ {
+ rParseResult.meOperator = lclGetConditionOperator( pcString, pcEnd );
+ if( rParseResult.meOperator != sheet::ConditionOperator_NONE )
+ {
+ lclSkipWhitespace( pcString, pcEnd );
+ if( pcString < pcEnd )
+ {
+ rParseResult.meToken = pCondInfo->meToken;
+ // comparison must be at end of attribute, remaining text is the formula
+ rParseResult.maOperand1 = OUString( pcString, static_cast< sal_Int32 >( pcEnd - pcString ) );
+ }
+ }
+ }
+ break;
+
+ case XML_COND_TYPE_FUNCTION0:
+ // format is <condition>()
+ if( lclSkipEmptyParentheses( pcString, pcEnd ) )
+ rParseResult.meToken = pCondInfo->meToken;
+ break;
+
+ case XML_COND_TYPE_FUNCTION1:
+ // format is <condition>(<expression>)
+ if( (pcString < pcEnd) && (*pcString == '(') )
+ {
+ rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ')' );
+ if( rParseResult.maOperand1.getLength() > 0 )
+ rParseResult.meToken = pCondInfo->meToken;
+ }
+ break;
+
+ case XML_COND_TYPE_FUNCTION2:
+ // format is <condition>(<expression1>,<expression2>)
+ if( (pcString < pcEnd) && (*pcString == '(') )
+ {
+ rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ',' );
+ if( rParseResult.maOperand1.getLength() > 0 )
+ {
+ rParseResult.maOperand2 = lclGetExpression( pcString, pcEnd, ')' );
+ if( rParseResult.maOperand2.getLength() > 0 )
+ rParseResult.meToken = pCondInfo->meToken;
+ }
+ }
+ break;
+ }
+ rParseResult.mnEndIndex = static_cast< sal_Int32 >( pcString - pcBegin );
+ }
+}
+
+// ============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLConverter.hxx b/sc/source/filter/xml/XMLConverter.hxx
new file mode 100644
index 000000000000..a661bc532d01
--- /dev/null
+++ b/sc/source/filter/xml/XMLConverter.hxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLCONVERTER_HXX
+#define SC_XMLCONVERTER_HXX
+
+#include "global.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+class ScDocument;
+class DateTime;
+class SvXMLUnitConverter;
+
+
+//___________________________________________________________________
+
+class ScXMLConverter
+{
+public:
+ inline ScXMLConverter() {}
+ inline ~ScXMLConverter() {}
+
+// helper methods
+ static ScDocument* GetScDocument(
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel );
+
+// IMPORT: GeneralFunction / ScSubTotalFunc
+ static ::com::sun::star::sheet::GeneralFunction
+ GetFunctionFromString(
+ const ::rtl::OUString& rString );
+ static ScSubTotalFunc GetSubTotalFuncFromString(
+ const ::rtl::OUString& rString );
+
+// EXPORT: GeneralFunction / ScSubTotalFunc
+ static void GetStringFromFunction(
+ ::rtl::OUString& rString,
+ const ::com::sun::star::sheet::GeneralFunction eFunction,
+ sal_Bool bAppendStr = false );
+ static void GetStringFromFunction(
+ ::rtl::OUString& rString,
+ const ScSubTotalFunc eFunction,
+ sal_Bool bAppendStr = false );
+
+// IMPORT: DataPilotFieldOrientation
+ static ::com::sun::star::sheet::DataPilotFieldOrientation
+ GetOrientationFromString(
+ const ::rtl::OUString& rString );
+
+// EXPORT: DataPilotFieldOrientation
+ static void GetStringFromOrientation(
+ ::rtl::OUString& rString,
+ const ::com::sun::star::sheet::DataPilotFieldOrientation eOrientation,
+ sal_Bool bAppendStr = false );
+
+// IMPORT: Detective
+ static ScDetectiveObjType
+ GetDetObjTypeFromString(
+ const ::rtl::OUString& rString );
+ static sal_Bool GetDetOpTypeFromString(
+ ScDetOpType& rDetOpType,
+ const ::rtl::OUString& rString );
+
+// EXPORT: Detective
+ static void GetStringFromDetObjType(
+ ::rtl::OUString& rString,
+ const ScDetectiveObjType eObjType,
+ sal_Bool bAppendStr = false );
+ static void GetStringFromDetOpType(
+ ::rtl::OUString& rString,
+ const ScDetOpType eOpType,
+ sal_Bool bAppendStr = false );
+
+// IMPORT: Formulas
+ static void ParseFormula(
+ ::rtl::OUString& sFormula,
+ const sal_Bool bIsFormula = sal_True);
+// EXPORT: Core Date Time
+ static void ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate);
+ static void ConvertCoreToAPIDateTime(const DateTime& aDateTime, com::sun::star::util::DateTime& rDateTime);
+
+ static void ConvertAPIToCoreDateTime(const com::sun::star::util::DateTime& aDateTime, DateTime& rDateTime);
+};
+
+// ============================================================================
+
+enum ScXMLConditionToken
+{
+ XML_COND_INVALID, /// Token not recognized.
+ XML_COND_AND, /// The 'and' token.
+ XML_COND_CELLCONTENT, /// The 'cell-content' token.
+ XML_COND_ISBETWEEN, /// The 'cell-content-is-between' token.
+ XML_COND_ISNOTBETWEEN, /// The 'cell-content-is-not-between' token.
+ XML_COND_ISWHOLENUMBER, /// The 'cell-content-is-whole-number' token.
+ XML_COND_ISDECIMALNUMBER, /// The 'cell-content-is-decimal-number' token.
+ XML_COND_ISDATE, /// The 'cell-content-is-date' token.
+ XML_COND_ISTIME, /// The 'cell-content-is-time' token.
+ XML_COND_ISINLIST, /// The 'cell-content-is-in-list' token.
+ XML_COND_TEXTLENGTH, /// The 'cell-content-text-length' token.
+ XML_COND_TEXTLENGTH_ISBETWEEN, /// The 'cell-content-text-length-is-between' token.
+ XML_COND_TEXTLENGTH_ISNOTBETWEEN, /// The 'cell-content-text-length-is-not-between' token.
+ XML_COND_ISTRUEFORMULA /// The 'is-true-formula' token.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Result of an attempt to parse a single condition in a 'condition' attribute
+ value of e.g. conditional formatting or data validation.
+ */
+struct ScXMLConditionParseResult
+{
+ ScXMLConditionToken meToken; /// The leading condition token.
+ ::com::sun::star::sheet::ValidationType
+ meValidation; /// A data validation type if existing.
+ ::com::sun::star::sheet::ConditionOperator
+ meOperator; /// A comparison operator if existing.
+ ::rtl::OUString maOperand1; /// First operand of the token or comparison value.
+ ::rtl::OUString maOperand2; /// Second operand of 'between' conditions.
+ sal_Int32 mnEndIndex; /// Index of first character following the condition.
+};
+
+// ----------------------------------------------------------------------------
+
+class ScXMLConditionHelper
+{
+public:
+ /** Parses the next condition in a 'condition' attribute value of e.g.
+ conditional formatting or data validation.
+ */
+ static void parseCondition(
+ ScXMLConditionParseResult& rParseResult,
+ const ::rtl::OUString& rAttribute,
+ sal_Int32 nStartIndex );
+
+private:
+ ScXMLConditionHelper();
+ ~ScXMLConditionHelper();
+};
+
+// ============================================================================
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLDDELinksContext.cxx b/sc/source/filter/xml/XMLDDELinksContext.cxx
new file mode 100644
index 000000000000..94cf98d39849
--- /dev/null
+++ b/sc/source/filter/xml/XMLDDELinksContext.cxx
@@ -0,0 +1,495 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLDDELinksContext.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+using rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDDELinksContext::~ScXMLDDELinksContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK))
+ pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDELinksContext::EndElement()
+{
+}
+
+ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aDDELinkTable(),
+ aDDELinkRow(),
+ sApplication(),
+ sTopic(),
+ sItem(),
+ nPosition(-1),
+ nColumns(0),
+ nRows(0),
+ nMode(SC_DDE_DEFAULT)
+{
+ // here are no attributes
+}
+
+ScXMLDDELinkContext::~ScXMLDDELinkContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE))
+ pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE))
+ pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDELinkContext::CreateDDELink()
+{
+ if (GetScImport().GetDocument() &&
+ sApplication.getLength() &&
+ sTopic.getLength() &&
+ sItem.getLength())
+ {
+ String sAppl(sApplication);
+ String sTop(sTopic);
+ String sIt(sItem);
+ GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode, ScMatrixRef());
+ sal_uInt16 nPos;
+ if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos))
+ nPosition = nPos;
+ else
+ nPosition = -1;
+ DBG_ASSERT(nPosition > -1, "DDE Link not inserted");
+ }
+}
+
+void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
+{
+ aDDELinkRow.push_back(aCell);
+}
+
+void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
+{
+ for (sal_Int32 i = 0; i < nRowsP; ++i)
+ aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
+ aDDELinkRow.clear();
+}
+
+void ScXMLDDELinkContext::EndElement()
+{
+ if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument())
+ {
+ bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size());
+ DBG_ASSERT( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count");
+ // Excel writes bad ODF in that it does not write the
+ // table:number-columns-repeated attribute of the
+ // <table:table-column> element, but apparently uses the number of
+ // <table:table-cell> elements within a <table:table-row> element to
+ // determine the column count instead. Be lenient ...
+ if (!bSizeMatch && nColumns == 1)
+ {
+ nColumns = aDDELinkTable.size() / nRows;
+ DBG_ASSERT( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
+ "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
+ }
+ ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) );
+ sal_Int32 nCol(0);
+ sal_Int32 nRow(-1);
+ sal_Int32 nIndex(0);
+ ScDDELinkCells::iterator aItr(aDDELinkTable.begin());
+ ScDDELinkCells::iterator aEndItr(aDDELinkTable.end());
+ while (aItr != aEndItr)
+ {
+ if (nIndex % nColumns == 0)
+ {
+ ++nRow;
+ nCol = 0;
+ }
+ else
+ ++nCol;
+
+ SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
+ SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
+ if( aItr->bEmpty )
+ pMatrix->PutEmpty( nScCol, nScRow );
+ else if( aItr->bString )
+ pMatrix->PutString( aItr->sValue, nScCol, nScRow );
+ else
+ pMatrix->PutDouble( aItr->fValue, nScCol, nScRow );
+
+ ++nIndex;
+ ++aItr;
+ }
+
+ GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix );
+ }
+}
+
+ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_DDE_APPLICATION))
+ pDDELink->SetApplication(sValue);
+ else if (IsXMLToken(aLocalName, XML_DDE_TOPIC))
+ pDDELink->SetTopic(sValue);
+ else if (IsXMLToken(aLocalName, XML_DDE_ITEM))
+ pDDELink->SetItem(sValue);
+ }
+ else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE))
+ {
+ if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER))
+ pDDELink->SetMode(SC_DDE_ENGLISH);
+ else if (IsXMLToken(sValue, XML_KEEP_TEXT))
+ pDDELink->SetMode(SC_DDE_TEXT);
+ else
+ pDDELink->SetMode(SC_DDE_DEFAULT);
+ }
+ }
+}
+
+ScXMLDDESourceContext::~ScXMLDDESourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDESourceContext::EndElement()
+{
+ pDDELink->CreateDDELink();
+}
+
+ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ // here are no attributes
+}
+
+ScXMLDDETableContext::~ScXMLDDETableContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_TABLE_COLUMN))
+ pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+ else if (IsXMLToken(rLName, XML_TABLE_ROW))
+ pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+ }
+
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDETableContext::EndElement()
+{
+}
+
+ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+ sal_Int32 nCols(1);
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nCols, sValue);
+ }
+ pDDELink->AddColumns(nCols);
+}
+
+ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDEColumnContext::EndElement()
+{
+}
+
+ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDDELink(pTempDDELink),
+ nRows(1)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nRows, sValue);
+ }
+ pDDELink->AddRows(nRows);
+}
+
+ScXMLDDERowContext::~ScXMLDDERowContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ if (IsXMLToken(rLName, XML_TABLE_CELL))
+ pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
+
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDERowContext::EndElement()
+{
+ pDDELink->AddRowsToTable(nRows);
+}
+
+ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pTempDDELink) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sValue(),
+ fValue(),
+ nCells(1),
+ bString(sal_True),
+ bString2(sal_True),
+ bEmpty(sal_True),
+ pDDELink(pTempDDELink)
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sTempValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
+ {
+ if (IsXMLToken(sTempValue, XML_STRING))
+ bString = sal_True;
+ else
+ bString = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_STRING_VALUE))
+ {
+ sValue = sTempValue;
+ bEmpty = false;
+ bString2 = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_VALUE))
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fValue, sTempValue);
+ bEmpty = false;
+ bString2 = false;
+ }
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
+ GetScImport().GetMM100UnitConverter().convertNumber(nCells, sTempValue);
+ }
+ }
+}
+
+ScXMLDDECellContext::~ScXMLDDECellContext()
+{
+}
+
+SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDDECellContext::EndElement()
+{
+ DBG_ASSERT(bString == bString2, "something wrong with this type");
+ ScDDELinkCell aCell;
+ aCell.sValue = sValue;
+ aCell.fValue = fValue;
+ aCell.bEmpty = bEmpty;
+ aCell.bString = bString2;
+ for(sal_Int32 i = 0; i < nCells; ++i)
+ pDDELink->AddCellToRow(aCell);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLDDELinksContext.hxx b/sc/source/filter/xml/XMLDDELinksContext.hxx
new file mode 100644
index 000000000000..2af8015d6476
--- /dev/null
+++ b/sc/source/filter/xml/XMLDDELinksContext.hxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLDDELINKSCONTEXT_HXX
+#define SC_XMLDDELINKSCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+#include <list>
+
+class ScXMLImport;
+
+class ScXMLDDELinksContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDELinksContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDDELinksContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScDDELinkCell
+{
+ rtl::OUString sValue;
+ double fValue;
+ sal_Bool bString;
+ sal_Bool bEmpty;
+};
+
+typedef std::list<ScDDELinkCell> ScDDELinkCells;
+
+class ScXMLDDELinkContext : public SvXMLImportContext
+{
+ ScDDELinkCells aDDELinkTable;
+ ScDDELinkCells aDDELinkRow;
+ rtl::OUString sApplication;
+ rtl::OUString sTopic;
+ rtl::OUString sItem;
+ sal_Int32 nPosition;
+ sal_Int32 nColumns;
+ sal_Int32 nRows;
+ sal_uInt8 nMode;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDELinkContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDDELinkContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void SetApplication(const rtl::OUString& sValue) { sApplication = sValue; }
+ void SetTopic(const rtl::OUString& sValue) { sTopic = sValue; }
+ void SetItem(const rtl::OUString& sValue) { sItem = sValue; }
+ void SetMode(const sal_uInt8 nValue) { nMode = nValue; }
+ void CreateDDELink();
+ void AddColumns(const sal_Int32 nValue) { nColumns += nValue; }
+ void AddRows(const sal_Int32 nValue) { nRows += nValue; }
+ void AddCellToRow(const ScDDELinkCell& aCell);
+ void AddRowsToTable(const sal_Int32 nRows);
+
+ virtual void EndElement();
+};
+
+class ScXMLDDESourceContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDESourceContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDESourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDETableContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDETableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDETableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDEColumnContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDEColumnContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDEColumnContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDERowContext : public SvXMLImportContext
+{
+ ScXMLDDELinkContext* pDDELink;
+ sal_Int32 nRows;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDERowContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDERowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDDECellContext : public SvXMLImportContext
+{
+ rtl::OUString sValue;
+ double fValue;
+ sal_Int32 nCells;
+ sal_Bool bString;
+ sal_Bool bString2;
+ sal_Bool bEmpty;
+
+ ScXMLDDELinkContext* pDDELink;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLDDECellContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDDELinkContext* pDDELink);
+
+ virtual ~ScXMLDDECellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLDetectiveContext.cxx b/sc/source/filter/xml/XMLDetectiveContext.cxx
new file mode 100644
index 000000000000..812b66b345f5
--- /dev/null
+++ b/sc/source/filter/xml/XMLDetectiveContext.cxx
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//___________________________________________________________________
+#include "XMLDetectiveContext.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "convuno.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <algorithm>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScMyImpDetectiveObj::ScMyImpDetectiveObj() :
+ aSourceRange(),
+ eObjType( SC_DETOBJ_NONE ),
+ bHasError( false )
+{
+}
+
+//___________________________________________________________________
+
+sal_Bool ScMyImpDetectiveOp::operator<(const ScMyImpDetectiveOp& rDetOp) const
+{
+ return (nIndex < rDetOp.nIndex);
+}
+
+void ScMyImpDetectiveOpArray::Sort()
+{
+ aDetectiveOpList.sort();
+}
+
+sal_Bool ScMyImpDetectiveOpArray::GetFirstOp( ScMyImpDetectiveOp& rDetOp )
+{
+ if( aDetectiveOpList.empty() )
+ return false;
+ ScMyImpDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ rDetOp = *aItr;
+ aDetectiveOpList.erase( aItr );
+ return sal_True;
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveContext::ScXMLDetectiveContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDetectiveObjVec( pNewDetectiveObjVec )
+{
+}
+
+ScXMLDetectiveContext::~ScXMLDetectiveContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext* pContext = NULL;
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDetectiveElemTokenMap();
+
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED:
+ pContext = new ScXMLDetectiveHighlightedContext( GetScImport(), nPrefix, rLName, xAttrList, pDetectiveObjVec );
+ break;
+ case XML_TOK_DETECTIVE_ELEM_OPERATION:
+ pContext = new ScXMLDetectiveOperationContext( GetScImport(), nPrefix, rLName, xAttrList );
+ break;
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDetectiveContext::EndElement()
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveHighlightedContext::ScXMLDetectiveHighlightedContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec ):
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDetectiveObjVec( pNewDetectiveObjVec ),
+ aDetectiveObj(),
+ bValid( false )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveHighlightedAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE:
+ {
+ sal_Int32 nOffset(0);
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ bValid = ScRangeStringConverter::GetRangeFromString( aDetectiveObj.aSourceRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ }
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION:
+ aDetectiveObj.eObjType = ScXMLConverter::GetDetObjTypeFromString( sValue );
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR:
+ aDetectiveObj.bHasError = IsXMLToken(sValue, XML_TRUE);
+ break;
+ case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID:
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aDetectiveObj.eObjType = SC_DETOBJ_CIRCLE;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDetectiveHighlightedContext::~ScXMLDetectiveHighlightedContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveHighlightedContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDetectiveHighlightedContext::EndElement()
+{
+ switch( aDetectiveObj.eObjType )
+ {
+ case SC_DETOBJ_ARROW:
+ case SC_DETOBJ_TOOTHERTAB:
+ break;
+ case SC_DETOBJ_FROMOTHERTAB:
+ case SC_DETOBJ_CIRCLE:
+ bValid = sal_True;
+ break;
+ default:
+ bValid = false;
+ }
+ if( bValid )
+ pDetectiveObjVec->push_back( aDetectiveObj );
+}
+
+
+//___________________________________________________________________
+
+ScXMLDetectiveOperationContext::ScXMLDetectiveOperationContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aDetectiveOp(),
+ bHasType( false )
+{
+ if( !xAttrList.is() ) return;
+
+ sal_Int16 nAttrCount = xAttrList->getLength();
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveOperationAttrTokenMap();
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DETECTIVE_OPERATION_ATTR_NAME:
+ bHasType = ScXMLConverter::GetDetOpTypeFromString( aDetectiveOp.eOpType, sValue );
+ break;
+ case XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX:
+ {
+ sal_Int32 nValue;
+ if( SvXMLUnitConverter::convertNumber( nValue, sValue, 0 ) )
+ aDetectiveOp.nIndex = nValue;
+ }
+ break;
+ }
+ }
+ ScUnoConversion::FillScAddress( aDetectiveOp.aPosition, rImport.GetTables().GetRealCellPos() );
+}
+
+ScXMLDetectiveOperationContext::~ScXMLDetectiveOperationContext()
+{
+}
+
+SvXMLImportContext *ScXMLDetectiveOperationContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDetectiveOperationContext::EndElement()
+{
+ if( bHasType && (aDetectiveOp.nIndex >= 0) )
+ GetScImport().GetDetectiveOpArray()->AddDetectiveOp( aDetectiveOp );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLDetectiveContext.hxx b/sc/source/filter/xml/XMLDetectiveContext.hxx
new file mode 100644
index 000000000000..0e7c8c5a957f
--- /dev/null
+++ b/sc/source/filter/xml/XMLDetectiveContext.hxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLDETECTIVECONTEXT_HXX
+#define SC_XMLDETECTIVECONTEXT_HXX
+
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "detfunc.hxx"
+#include "detdata.hxx"
+
+#include <list>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+struct ScMyImpDetectiveObj
+{
+ ScRange aSourceRange;
+ ScDetectiveObjType eObjType;
+ sal_Bool bHasError;
+
+ ScMyImpDetectiveObj();
+};
+
+typedef ::std::vector< ScMyImpDetectiveObj > ScMyImpDetectiveObjVec;
+
+
+//___________________________________________________________________
+
+struct ScMyImpDetectiveOp
+{
+ ScAddress aPosition;
+ ScDetOpType eOpType;
+ sal_Int32 nIndex;
+
+ inline ScMyImpDetectiveOp() : nIndex( -1 ) {}
+ sal_Bool operator<(const ScMyImpDetectiveOp& rDetOp) const;
+};
+
+typedef ::std::list< ScMyImpDetectiveOp > ScMyImpDetectiveOpList;
+
+class ScMyImpDetectiveOpArray
+{
+private:
+ ScMyImpDetectiveOpList aDetectiveOpList;
+
+public:
+ inline ScMyImpDetectiveOpArray() :
+ aDetectiveOpList() {}
+
+ inline void AddDetectiveOp( const ScMyImpDetectiveOp& rDetOp )
+ { aDetectiveOpList.push_back( rDetOp ); }
+
+ void Sort();
+ sal_Bool GetFirstOp( ScMyImpDetectiveOp& rDetOp );
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec
+ );
+ virtual ~ScXMLDetectiveContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveHighlightedContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+ ScMyImpDetectiveObj aDetectiveObj;
+ sal_Bool bValid;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveHighlightedContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ ScMyImpDetectiveObjVec* pNewDetectiveObjVec
+ );
+ virtual ~ScXMLDetectiveHighlightedContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLDetectiveOperationContext : public SvXMLImportContext
+{
+private:
+ ScMyImpDetectiveOp aDetectiveOp;
+ sal_Bool bHasType;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDetectiveOperationContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual ~ScXMLDetectiveOperationContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLEmptyContext.cxx b/sc/source/filter/xml/XMLEmptyContext.cxx
new file mode 100644
index 000000000000..0c38adc344d6
--- /dev/null
+++ b/sc/source/filter/xml/XMLEmptyContext.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "XMLEmptyContext.hxx"
+#include "xmlimprt.hxx"
+
+//------------------------------------------------------------------
+
+ScXMLEmptyContext::ScXMLEmptyContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+}
+
+ScXMLEmptyContext::~ScXMLEmptyContext()
+{
+}
+
+SvXMLImportContext *ScXMLEmptyContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLName);
+
+ return pContext;
+}
+
+void ScXMLEmptyContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLEmptyContext.hxx b/sc/source/filter/xml/XMLEmptyContext.hxx
new file mode 100644
index 000000000000..8c836d0aec96
--- /dev/null
+++ b/sc/source/filter/xml/XMLEmptyContext.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLEMPTYCONTEXT_HXX
+#define SC_XMLEMPTYCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+class ScXMLEmptyContext : public SvXMLImportContext
+{
+ rtl::OUString sPrintRanges;
+ sal_Bool bStartFormPage;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLEmptyContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName);
+
+ virtual ~ScXMLEmptyContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDDELinks.cxx b/sc/source/filter/xml/XMLExportDDELinks.cxx
new file mode 100644
index 000000000000..70e83b284008
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDDELinks.cxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDDELinks.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "xmlexprt.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "scmatrix.hxx"
+#include <com/sun/star/sheet/XDDELink.hpp>
+
+class ScMatrix;
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUStringBuffer;
+
+ScXMLExportDDELinks::ScXMLExportDDELinks(ScXMLExport& rTempExport)
+ : rExport(rTempExport)
+{
+}
+
+ScXMLExportDDELinks::~ScXMLExportDDELinks()
+{
+}
+
+sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+ const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) const
+{
+ if (bEmpty == bPrevEmpty)
+ if (bEmpty)
+ return sal_True;
+ else if (bString == bPrevString)
+ if (bString)
+ return (sPrevValue == sValue);
+ else
+ return (fPrevValue == fValue);
+ else
+ return false;
+ else
+ return false;
+}
+
+void ScXMLExportDDELinks::WriteCell(const ScMatrixValue& aVal, sal_Int32 nRepeat)
+{
+ bool bString = ScMatrix::IsNonValueType(aVal.nType);
+ bool bEmpty = ScMatrix::IsEmptyType(aVal.nType);
+
+ if (!bEmpty)
+ {
+ if (bString)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, aVal.GetString());
+ }
+ else
+ {
+ OUStringBuffer aBuf;
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ rExport.GetMM100UnitConverter().convertDouble(aBuf, aVal.fVal);
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aBuf.makeStringAndClear());
+ }
+ }
+
+ if (nRepeat > 1)
+ {
+ OUStringBuffer aBuf;
+ rExport.GetMM100UnitConverter().convertNumber(aBuf, nRepeat);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+}
+
+void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
+{
+ ScDocument* pDoc = rExport.GetDocument();
+ if (!pDoc)
+ return;
+
+ const ScMatrix* pMatrix = pDoc->GetDdeLinkResultMatrix(static_cast<sal_uInt16>(nPos));
+ if (!pMatrix)
+ return;
+
+ SCSIZE nCols, nRows;
+ pMatrix->GetDimensions(nCols, nRows);
+
+ SvXMLElementExport aTableElem(rExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
+ if (nCols > 1)
+ {
+ OUStringBuffer aBuf;
+ rExport.GetMM100UnitConverter().convertNumber(aBuf, static_cast<sal_Int32>(nCols));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aBuf.makeStringAndClear());
+ }
+ {
+ SvXMLElementExport aElemCol(rExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
+ }
+
+ for (SCSIZE nRow = 0; nRow < nRows; ++nRow)
+ {
+ sal_Int32 nRepeat = 0;
+ ScMatrixValue aPrevVal;
+ SvXMLElementExport aElemRow(rExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ for (SCSIZE nCol = 0; nCol < nCols; ++nCol, ++nRepeat)
+ {
+ ScMatrixValue aVal = pMatrix->Get(nCol, nRow);
+ if (nCol > 0 && aVal != aPrevVal)
+ {
+ // Cell value differs. Flush the cell content.
+ WriteCell(aPrevVal, nRepeat);
+ nRepeat = 0;
+ }
+ aPrevVal = aVal;
+ }
+
+ WriteCell(aPrevVal, nRepeat);
+ }
+}
+
+void ScXMLExportDDELinks::WriteDDELinks(uno::Reference<sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DDELINKS))), uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nCount = xIndex->getCount();
+ if (nCount)
+ {
+ SvXMLElementExport aElemDDEs(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINKS, sal_True, sal_True);
+ for (sal_uInt16 nDDELink = 0; nDDELink < nCount; ++nDDELink)
+ {
+ uno::Reference<sheet::XDDELink> xDDELink(xIndex->getByIndex(nDDELink), uno::UNO_QUERY);
+ if (xDDELink.is())
+ {
+ SvXMLElementExport aElemDDE(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINK, sal_True, sal_True);
+ {
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION, xDDELink->getApplication());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, xDDELink->getTopic());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM, xDDELink->getItem());
+ rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE, XML_TRUE);
+ sal_uInt8 nMode;
+ if (rExport.GetDocument() &&
+ rExport.GetDocument()->GetDdeLinkMode(nDDELink, nMode))
+ {
+ switch (nMode)
+ {
+ case SC_DDE_ENGLISH :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_INTO_ENGLISH_NUMBER);
+ break;
+ case SC_DDE_TEXT :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_KEEP_TEXT);
+ break;
+ }
+ }
+ SvXMLElementExport(rExport, XML_NAMESPACE_OFFICE, XML_DDE_SOURCE, sal_True, sal_True);
+ }
+ WriteTable(nDDELink);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDDELinks.hxx b/sc/source/filter/xml/XMLExportDDELinks.hxx
new file mode 100644
index 000000000000..bb58ddb49856
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDDELinks.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDDELINKS_HXX
+#define SC_XMLEXPORTDDELINKS_HXX
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+class String;
+class ScXMLExport;
+struct ScMatrixValue;
+
+class ScXMLExportDDELinks
+{
+ ScXMLExport& rExport;
+
+ sal_Bool CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+ const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) const;
+ void WriteCell(const ScMatrixValue& aVal, sal_Int32 nRepeat);
+ void WriteTable(const sal_Int32 nPos);
+public:
+ ScXMLExportDDELinks(ScXMLExport& rExport);
+ ~ScXMLExportDDELinks();
+ void WriteDDELinks(::com::sun::star::uno::Reference < ::com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc);
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx
new file mode 100644
index 000000000000..d0071a9428b2
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDataPilot.cxx
@@ -0,0 +1,903 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDataPilot.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <rtl/math.hxx>
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dociter.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "scitems.hxx"
+#include "dpsave.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "dpdimsave.hxx"
+#include "dpgroup.hxx"
+#include "rangeutl.hxx"
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pDoc( NULL )
+{
+}
+
+ScXMLExportDataPilot::~ScXMLExportDataPilot()
+{
+}
+
+rtl::OUString ScXMLExportDataPilot::getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
+ const sal_Bool bIsString, const double dVal, const String& sVal) const
+{
+ switch (aFilterOperator)
+ {
+ case SC_EQUAL :
+ {
+ rtl::OUString sReturn;
+ if (bUseRegularExpressions)
+ sReturn = GetXMLToken(XML_MATCH);
+ else
+ sReturn = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+
+ if (!bIsString && sVal == EMPTY_STRING)
+ {
+ if (dVal == SC_EMPTYFIELDS)
+ sReturn = GetXMLToken(XML_EMPTY);
+ else if (dVal == SC_NONEMPTYFIELDS)
+ sReturn = GetXMLToken(XML_NOEMPTY);
+ }
+
+ return sReturn;
+ }
+ case SC_NOT_EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_NOMATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ }
+ case SC_BOTPERC :
+ return GetXMLToken(XML_BOTTOM_PERCENT);
+ case SC_BOTVAL :
+ return GetXMLToken(XML_BOTTOM_VALUES);
+ case SC_GREATER :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ case SC_GREATER_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ case SC_LESS :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ case SC_LESS_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ case SC_TOPPERC :
+ return GetXMLToken(XML_TOP_PERCENT);
+ case SC_TOPVAL :
+ return GetXMLToken(XML_TOP_VALUES);
+ default:
+ OSL_FAIL("This FilterOperator is not supported.");
+ }
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+}
+
+void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(sal_Int32(aQueryEntry.nField)));
+ if (bIsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ if (aQueryEntry.bQueryByString)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *aQueryEntry.pStr);
+ }
+ else
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rtl::OUString(*aQueryEntry.pStr));
+ }
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getDPOperatorXML(aQueryEntry.eOp, bUseRegularExpressions,
+ aQueryEntry.bQueryByString, aQueryEntry.nVal, *aQueryEntry.pStr));
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
+}
+
+void ScXMLExportDataPilot::WriteDPFilter(const ScQueryParam& aQueryParam)
+{
+ SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
+ if (nQueryEntryCount > 0)
+ {
+ sal_Bool bAnd(false);
+ sal_Bool bOr(false);
+ sal_Bool bHasEntries(sal_True);
+ SCSIZE nEntries(0);
+ SCSIZE j;
+
+ for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
+ {
+ ScQueryEntry aEntry = aQueryParam.GetEntry(j);
+ if (aEntry.bDoQuery)
+ {
+ if (nEntries > 0)
+ {
+ if (aEntry.eConnect == SC_AND)
+ bAnd = sal_True;
+ else
+ bOr = sal_True;
+ }
+ ++nEntries;
+ }
+ else
+ bHasEntries = false;
+ }
+ nQueryEntryCount = nEntries;
+ if (nQueryEntryCount)
+ {
+ if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
+ (static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
+ (aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
+ {
+ ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
+ aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
+ rtl::OUString sConditionRange;
+ ScRangeStringConverter::GetStringFromRange( sConditionRange, aConditionRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sConditionRange);
+ }
+ if (!aQueryParam.bDuplicate)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
+ SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ if (nQueryEntryCount == 1)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ else if (bOr && !bAnd)
+ {
+ SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ for (j = 0; j < nQueryEntryCount; ++j)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ else if (bAnd && !bOr)
+ {
+ SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
+ for (j = 0; j < nQueryEntryCount; ++j)
+ {
+ WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ else
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
+ ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
+ sal_Bool bOpenAndElement;
+ rtl::OUString aName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND)));
+ if (aConnection == SC_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ }
+ else
+ bOpenAndElement = false;
+ for (j = 1; j < nQueryEntryCount; ++j)
+ {
+ if (aConnection != aQueryParam.GetEntry(j).eConnect)
+ {
+ aConnection = aQueryParam.GetEntry(j).eConnect;
+ if (aQueryParam.GetEntry(j).eConnect == SC_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (j == nQueryEntryCount - 1)
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = false;
+ }
+ }
+ else
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (bOpenAndElement)
+ {
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = false;
+ }
+ if (j == nQueryEntryCount - 1)
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ }
+ else
+ {
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ aPrevFilterField = aQueryParam.GetEntry(j);
+ if (j == nQueryEntryCount - 1)
+ WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteFieldReference(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
+ if (pRef)
+ {
+ rtl::OUString sValueStr;
+ switch (pRef->ReferenceType)
+ {
+ case sheet::DataPilotFieldReferenceType::NONE :
+ sValueStr = GetXMLToken(XML_NONE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
+ sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
+ sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE_DIFFERENCE);
+ break;
+ case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
+ sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
+ break;
+ case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
+ sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
+ break;
+ case sheet::DataPilotFieldReferenceType::INDEX :
+ sValueStr = GetXMLToken(XML_INDEX);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, sValueStr);
+
+ if (pRef->ReferenceField.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
+
+ if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, XML_NAMED);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
+ }
+ else
+ {
+ sValueStr = rtl::OUString();
+ switch(pRef->ReferenceItemType)
+ {
+ case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
+ sValueStr = GetXMLToken(XML_PREVIOUS);
+ break;
+ case sheet::DataPilotFieldReferenceItemType::NEXT :
+ sValueStr = GetXMLToken(XML_NEXT);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, sValueStr);
+ }
+ SvXMLElementExport aElemDPFR(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+}
+
+void ScXMLExportDataPilot::WriteSortInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
+ if (pSortInfo)
+ {
+ if (pSortInfo->IsAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_ASCENDING);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+ rtl::OUString sValueStr;
+ switch (pSortInfo->Mode)
+ {
+ case sheet::DataPilotFieldSortMode::NONE:
+ sValueStr = GetXMLToken(XML_NONE);
+ break;
+ case sheet::DataPilotFieldSortMode::MANUAL:
+ sValueStr = GetXMLToken(XML_MANUAL);
+ break;
+ case sheet::DataPilotFieldSortMode::NAME:
+ sValueStr = GetXMLToken(XML_NAME);
+ break;
+ case sheet::DataPilotFieldSortMode::DATA:
+ sValueStr = GetXMLToken(XML_DATA);
+ if (pSortInfo->Field.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pSortInfo->Field);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SORT_MODE, sValueStr);
+ SvXMLElementExport aElemDPLSI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteAutoShowInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
+ if (pAutoInfo)
+ {
+ if (pAutoInfo->IsEnabled)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_FALSE);
+
+ rtl::OUString sValueStr;
+ switch (pAutoInfo->ShowItemsMode)
+ {
+ case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
+ sValueStr = GetXMLToken(XML_FROM_TOP);
+ break;
+ case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
+ sValueStr = GetXMLToken(XML_FROM_BOTTOM);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_MEMBER_MODE, sValueStr);
+
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, pAutoInfo->ItemCount);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, sBuffer.makeStringAndClear());
+
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
+
+ SvXMLElementExport aElemDPLAI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
+{
+ const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
+ if (pLayoutInfo)
+ {
+ if (pLayoutInfo->AddEmptyLines)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_FALSE);
+
+ rtl::OUString sValueStr;
+ switch (pLayoutInfo->LayoutMode)
+ {
+ case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
+ sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
+ break;
+ case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
+ sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_TOP);
+ break;
+ case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
+ sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_BOTTOM);
+ break;
+ }
+ if (sValueStr.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LAYOUT_MODE, sValueStr);
+ SvXMLElementExport aElemDPLLI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
+{
+ using sheet::GeneralFunction;
+
+ sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
+ const OUString* pLayoutName = NULL;
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ // Export display names only for 1.2 extended or later.
+ pLayoutName = pDim->GetSubtotalName();
+
+ if (nSubTotalCount > 0)
+ {
+ SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
+ {
+ rtl::OUString sFunction;
+ GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
+ ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
+ if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
+{
+ const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
+ if (rMembers.begin() != rMembers.end())
+ {
+ SvXMLElementExport aElemDPMs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; ++i)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
+
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = (*i)->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
+ SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetShowDetails());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
+ SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteLevels(ScDPSaveDimension* pDim)
+{
+ // #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
+ if (pDim->HasShowEmpty())
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertBool(sBuffer, pDim->GetShowEmpty());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aElemDPL(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, sal_True, sal_True);
+
+ WriteSubTotals(pDim);
+ WriteMembers(pDim);
+ WriteAutoShowInfo(pDim);
+ WriteSortInfo(pDim);
+ WriteLayoutInfo(pDim);
+ rExport.CheckAttrList();
+}
+
+void ScXMLExportDataPilot::WriteDatePart(sal_Int32 nPart)
+{
+ switch(nPart)
+ {
+ case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_SECONDS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MINUTES);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_HOURS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_DAYS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MONTHS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_QUARTERS);
+ }
+ break;
+ case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_YEARS);
+ }
+ break;
+ }
+}
+
+void ScXMLExportDataPilot::WriteNumGroupInfo(const ScDPNumGroupInfo& rGroupInfo)
+{
+ DBG_ASSERT(rGroupInfo.Enable, "group dimension should be enabled");
+ if (rGroupInfo.DateValues)
+ {
+ if (rGroupInfo.AutoStart)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.Start);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
+ }
+ if (rGroupInfo.AutoEnd)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.End);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
+ }
+ }
+ else
+ {
+ if (rGroupInfo.AutoStart)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, XML_AUTO);
+ else
+ {
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Start,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, sValue);
+ }
+ if (rGroupInfo.AutoEnd)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, XML_AUTO);
+ else
+ {
+ rtl::OUStringBuffer sDate;
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.End,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, sValue);
+ }
+ }
+ rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Step,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STEP, sValue);
+}
+
+void ScXMLExportDataPilot::WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim)
+{
+ if (pGroupDim)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, pGroupDim->GetSourceDimName());
+ if (pGroupDim->GetDatePart())
+ {
+ WriteDatePart(pGroupDim->GetDatePart());
+ WriteNumGroupInfo(pGroupDim->GetDateInfo());
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim)
+{
+ if (pNumGroupDim)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
+ if (pNumGroupDim->GetDatePart())
+ {
+ WriteDatePart(pNumGroupDim->GetDatePart());
+ WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
+ }
+ else
+ {
+ WriteNumGroupInfo(pNumGroupDim->GetInfo());
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
+{
+ const ScDPSaveGroupDimension* pGroupDim = NULL;
+ const ScDPSaveNumGroupDimension* pNumGroupDim = NULL;
+ if (pDimData)
+ {
+ pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
+ WriteGroupDimAttributes(pGroupDim);
+ pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
+ WriteNumGroupDim(pNumGroupDim);
+
+ DBG_ASSERT((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
+ }
+ if (pGroupDim || pNumGroupDim)
+ {
+ SvXMLElementExport aElemDPGs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, sal_True, sal_True);
+ if (pGroupDim)
+ {
+ if (!pGroupDim->GetDatePart())
+ {
+ sal_Int32 nCount = pGroupDim->GetGroupCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( i );
+ if (pGroup)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, pGroup->GetGroupName());
+ SvXMLElementExport aElemDPG(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUP, sal_True, sal_True);
+ sal_Int32 nElemCount = pGroup->GetElementCount();
+ for(sal_Int32 j = 0; j < nElemCount; ++j)
+ {
+ const String* pElem = pGroup->GetElementByIndex( j );
+ if (pElem)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, *pElem);
+ SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
+ if (pDim->IsDataLayout())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
+ rtl::OUString sValueStr;
+ ScXMLConverter::GetStringFromOrientation( sValueStr,
+ (sheet::DataPilotFieldOrientation) pDim->GetOrientation() );
+ if( sValueStr.getLength() )
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, sValueStr );
+ if (pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE)
+ if (pDim->HasCurrentPage())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, pDim->GetCurrentPage());
+ if (pDim->GetUsedHierarchy() != 1)
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertNumber(sBuffer, pDim->GetUsedHierarchy());
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, sBuffer.makeStringAndClear());
+ }
+ ScXMLConverter::GetStringFromFunction( sValueStr,
+ (sheet::GeneralFunction) pDim->GetFunction() );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sValueStr);
+
+ SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, sal_True, sal_True);
+ WriteFieldReference(pDim);
+ WriteLevels(pDim);
+ if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
+ WriteGroupDimElements(pDim, pDimData);
+}
+
+void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
+{
+ const boost::ptr_vector<ScDPSaveDimension> &rDimensions = pDPSave->GetDimensions();
+ boost::ptr_vector<ScDPSaveDimension>::const_iterator iter;
+ for (iter = rDimensions.begin(); iter != rDimensions.end(); ++iter)
+ WriteDimension(const_cast<ScDPSaveDimension*>(&(*iter)), pDPSave->GetExistingDimensionData());
+}
+
+void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
+ if (pGrandTotal)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal);
+
+ SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
+}
+
+void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
+{
+ pDoc = rExport.GetDocument();
+ if (!pDoc)
+ return;
+
+ ScDPCollection* pDPs = pDoc->GetDPCollection();
+ if (!pDPs)
+ return;
+
+ size_t nDPCount = pDPs->GetCount();
+ if (!nDPCount)
+ return;
+
+ SvXMLElementExport aElemDPs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (size_t i = 0; i < nDPCount; ++i)
+ {
+ ScDPSaveData* pDPSave = (*pDPs)[i]->GetSaveData();
+ if (!pDPSave)
+ continue;
+
+ ScRange aOutRange((*pDPs)[i]->GetOutRange());
+ rtl::OUString sTargetRangeAddress;
+ ScRangeStringConverter::GetStringFromRange( sTargetRangeAddress, aOutRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ ScDocAttrIterator aAttrItr(pDoc, aOutRange.aStart.Tab(),
+ aOutRange.aStart.Col(), aOutRange.aStart.Row(),
+ aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
+ SCCOL nCol;
+ SCROW nRow1, nRow2;
+ rtl::OUString sOUButtonList;
+ const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
+ while (pAttr)
+ {
+ ScMergeFlagAttr& rItem = (ScMergeFlagAttr&)pAttr->GetItem(ATTR_MERGE_FLAG);
+ if (rItem.HasButton())
+ {
+ for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
+ {
+ ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
+ ScRangeStringConverter::GetStringFromAddress(
+ sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', sal_True );
+ }
+ }
+ pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
+ }
+ rtl::OUString sName((*pDPs)[i]->GetName());
+ rtl::OUString sApplicationData((*pDPs)[i]->GetTag());
+ sal_Bool bRowGrand = pDPSave->GetRowGrand();
+ sal_Bool bColumnGrand = pDPSave->GetColumnGrand();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, sApplicationData);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sTargetRangeAddress);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BUTTONS, sOUButtonList);
+ if (!(bRowGrand && bColumnGrand))
+ {
+ if (bRowGrand)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_ROW);
+ else if (bColumnGrand)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_COLUMN);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_NONE);
+ }
+ if (pDPSave->GetIgnoreEmptyRows())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TRUE);
+ if (pDPSave->GetRepeatIfEmpty())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TRUE);
+ if (!pDPSave->GetFilterButton())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_FALSE);
+ if (!pDPSave->GetDrillDown())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
+ if ((*pDPs)[i]->GetHeaderLayout())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HEADER_GRID_LAYOUT, XML_TRUE);
+
+ SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
+
+ // grand total elements.
+
+ const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
+ if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Use the new data-pilot-grand-total element.
+ if (bRowGrand && bColumnGrand)
+ {
+ WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
+ }
+ else
+ {
+ WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
+ WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
+ }
+ }
+
+ rExport.CheckAttrList();
+ if ((*pDPs)[i]->IsSheetData())
+ {
+ const ScSheetSourceDesc* pSheetSource = (*pDPs)[i]->GetSheetDesc();
+
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ if (pSheetSource->HasRangeName())
+ rExport.AddAttribute(
+ XML_NAMESPACE_TABLE, XML_NAME, pSheetSource->GetRangeName());
+ }
+
+ OUString sCellRangeAddress;
+ ScRangeStringConverter::GetStringFromRange(
+ sCellRangeAddress, pSheetSource->GetSourceRange(), pDoc,
+ ::formula::FormulaGrammar::CONV_OOO);
+
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sCellRangeAddress);
+ SvXMLElementExport aElemSCR(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ WriteDPFilter(pSheetSource->GetQueryParam());
+ }
+ else if ((*pDPs)[i]->IsImportData())
+ {
+ const ScImportSourceDesc* pImpSource = (*pDPs)[i]->GetImportSourceDesc();
+ switch (pImpSource->nType)
+ {
+ case sheet::DataImportMode_NONE : break;
+ case sheet::DataImportMode_QUERY :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, pImpSource->aDBName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, pImpSource->aObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_TABLE :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, pImpSource->aDBName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, pImpSource->aObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_SQL :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, pImpSource->aDBName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, pImpSource->aObject);
+ if (!pImpSource->bNative)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ break;
+ }
+ }
+ else if ((*pDPs)[i]->IsServiceData())
+ {
+ const ScDPServiceDesc* pServSource = (*pDPs)[i]->GetDPServiceDesc();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString(pServSource->aServiceName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_NAME, rtl::OUString(pServSource->aParSource));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OBJECT_NAME, rtl::OUString(pServSource->aParName));
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USER_NAME, rtl::OUString(pServSource->aParUser));
+ // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
+ // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, rtl::OUString(pServSource->aParPass));
+ SvXMLElementExport aElemSD(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ WriteDimensions(pDPSave);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx
new file mode 100644
index 000000000000..c1b9426f552d
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDataPilot.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDATAPILOT_HXX
+#define SC_XMLEXPORTDATAPILOT_HXX
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <rtl/ustring.hxx>
+#include "global.hxx"
+#include "xmloff/xmltoken.hxx"
+
+class ScXMLExport;
+class ScDocument;
+class ScDPSaveDimension;
+class ScDPSaveData;
+class ScDPDimensionSaveData;
+class ScDPSaveGroupDimension;
+class ScDPSaveNumGroupDimension;
+struct ScDPNumGroupInfo;
+struct ScQueryParam;
+
+class ScXMLExportDataPilot
+{
+ ScXMLExport& rExport;
+ ScDocument* pDoc;
+
+ rtl::OUString getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
+ const sal_Bool bIsString, const double dVal, const String& sVal) const;
+ void WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions);
+ void WriteDPFilter(const ScQueryParam& aQueryParam);
+
+ void WriteFieldReference(ScDPSaveDimension* pDim);
+ void WriteSortInfo(ScDPSaveDimension* pDim);
+ void WriteAutoShowInfo(ScDPSaveDimension* pDim);
+ void WriteLayoutInfo(ScDPSaveDimension* pDim);
+ void WriteSubTotals(ScDPSaveDimension* pDim);
+ void WriteMembers(ScDPSaveDimension* pDim);
+ void WriteLevels(ScDPSaveDimension* pDim);
+ void WriteDatePart(sal_Int32 nPart);
+ void WriteNumGroupInfo(const ScDPNumGroupInfo& pGroupInfo);
+ void WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim);
+ void WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
+ void WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim);
+ void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
+ void WriteDimensions(ScDPSaveData* pDPSave);
+
+ void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal);
+
+public:
+ ScXMLExportDataPilot(ScXMLExport& rExport);
+ ~ScXMLExportDataPilot();
+ void WriteDataPilots(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreaDoc);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
new file mode 100644
index 000000000000..44e28332dd57
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -0,0 +1,1223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportDatabaseRanges.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include "xmlexprt.hxx"
+#include "XMLExportIterator.hxx"
+#include "XMLConverter.hxx"
+#include "unonames.hxx"
+#include "dbcolect.hxx"
+#include "document.hxx"
+#include "globstr.hrc"
+#include "globalnames.hxx"
+#include "XMLExportSharedData.hxx"
+#include "rangeutl.hxx"
+#include "subtotalparam.hxx"
+#include "queryparam.hxx"
+
+#include "svx/dataaccessdescriptor.hxx"
+
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/table/TableSortFieldType.hpp>
+#include <com/sun/star/sheet/XSubTotalField.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <tools/debug.hxx>
+#include <comphelper/extract.hxx>
+
+#include <map>
+
+//! not found in unonames.hxx
+#define SC_USERLIST "UserList"
+#define SC_SORTASCENDING "SortAscending"
+#define SC_ENABLEUSERSORTLIST "EnableUserSortList"
+#define SC_USERSORTLISTINDEX "UserSortListIndex"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport)
+ : rExport(rTempExport),
+ pDoc( NULL )
+{
+}
+
+ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges()
+{
+}
+
+ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges()
+{
+ ScMyEmptyDatabaseRangesContainer aSkipRanges;
+ if (rExport.GetModel().is())
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ rExport.CheckAttrList();
+ if (xDatabaseRanges.is())
+ {
+ uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
+ sal_Int32 nDatabaseRangesCount = aRanges.getLength();
+ for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
+ {
+ rtl::OUString sDatabaseRangeName(aRanges[i]);
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
+ if (xDatabaseRangePropertySet.is() &&
+ ::cppu::any2bool(xDatabaseRangePropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
+ {
+ uno::Sequence <beans::PropertyValue> aImportProperties(xDatabaseRange->getImportDescriptor());
+ sal_Int32 nLength = aImportProperties.getLength();
+ sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+ for (sal_Int32 j = 0; j < nLength; ++j)
+ if (aImportProperties[j].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportProperties[j].Value >>= nSourceType;
+ if (nSourceType != sheet::DataImportMode_NONE)
+ {
+ table::CellRangeAddress aArea = xDatabaseRange->getDataArea();
+ aSkipRanges.AddNewEmptyDatabaseRange(aArea);
+
+ // #105276#; set last row/column so default styles are collected
+ rExport.GetSharedData()->SetLastColumn(aArea.Sheet, aArea.EndColumn);
+ rExport.GetSharedData()->SetLastRow(aArea.Sheet, aArea.EndRow);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return aSkipRanges;
+}
+
+void ScXMLExportDatabaseRanges::WriteImportDescriptor(const uno::Sequence <beans::PropertyValue> aImportDescriptor)
+{
+ sal_Int32 nProperties = aImportDescriptor.getLength();
+ rtl::OUString sDatabaseName;
+ rtl::OUString sConRes;
+ rtl::OUString sSourceObject;
+ sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+ sal_Bool bNative = false;
+ for (sal_Int16 i = 0; i < nProperties; ++i)
+ {
+ if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME)))
+ aImportDescriptor[i].Value >>= sDatabaseName;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES)))
+ aImportDescriptor[i].Value >>= sConRes;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ)))
+ aImportDescriptor[i].Value >>= sSourceObject;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportDescriptor[i].Value >>= nSourceType;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
+ bNative = ::cppu::any2bool(aImportDescriptor[i].Value);
+ }
+ switch (nSourceType)
+ {
+ case sheet::DataImportMode_NONE : break;
+ case sheet::DataImportMode_QUERY :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, sSourceObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_TABLE :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sSourceObject);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ case sheet::DataImportMode_SQL :
+ {
+ if (sDatabaseName.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, sSourceObject);
+ if (!bNative)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+ SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
+ if (sConRes.getLength())
+ {
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True);
+ }
+ rExport.CheckAttrList();
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+}
+
+rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const
+{
+ switch (aFilterOperator)
+ {
+ case sheet::FilterOperator2::EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_MATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ }
+ case sheet::FilterOperator2::NOT_EQUAL :
+ {
+ if (bUseRegularExpressions)
+ return GetXMLToken(XML_NOMATCH);
+ else
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ }
+ case sheet::FilterOperator2::BOTTOM_PERCENT :
+ return GetXMLToken(XML_BOTTOM_PERCENT);
+ case sheet::FilterOperator2::BOTTOM_VALUES :
+ return GetXMLToken(XML_BOTTOM_VALUES);
+ case sheet::FilterOperator2::EMPTY :
+ return GetXMLToken(XML_EMPTY);
+ case sheet::FilterOperator2::GREATER :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ case sheet::FilterOperator2::GREATER_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ case sheet::FilterOperator2::LESS :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ case sheet::FilterOperator2::LESS_EQUAL :
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ case sheet::FilterOperator2::NOT_EMPTY :
+ return GetXMLToken(XML_NOEMPTY);
+ case sheet::FilterOperator2::TOP_PERCENT :
+ return GetXMLToken(XML_TOP_PERCENT);
+ case sheet::FilterOperator2::TOP_VALUES :
+ return GetXMLToken(XML_TOP_VALUES);
+ case sheet::FilterOperator2::CONTAINS :
+ return GetXMLToken(XML_CONTAINS);
+ case sheet::FilterOperator2::DOES_NOT_CONTAIN :
+ return GetXMLToken(XML_DOES_NOT_CONTAIN);
+ case sheet::FilterOperator2::BEGINS_WITH :
+ return GetXMLToken(XML_BEGINS_WITH);
+ case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH :
+ return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
+ case sheet::FilterOperator2::ENDS_WITH :
+ return GetXMLToken(XML_ENDS_WITH);
+ case sheet::FilterOperator2::DOES_NOT_END_WITH :
+ return GetXMLToken(XML_DOES_NOT_END_WITH);
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+}
+
+void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aFilterField.Field));
+ if (bIsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ if (aFilterField.IsNumeric)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ rtl::OUStringBuffer sBuffer;
+ rExport.GetMM100UnitConverter().convertDouble(sBuffer, aFilterField.NumericValue);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, sBuffer.makeStringAndClear());
+ }
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aFilterField.StringValue);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(aFilterField.Operator, bUseRegularExpressions));
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
+}
+
+void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName)
+{
+ uno::Sequence< sheet::TableFilterField2 > aTableFilterFields( xSheetFilterDescriptor->getFilterFields2() );
+ sal_Int32 nTableFilterFields = aTableFilterFields.getLength();
+ if (nTableFilterFields > 0)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)))))
+ {
+ table::CellAddress aOutputPosition;
+ if (xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS))) >>= aOutputPosition)
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
+ }
+ }
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromRange( sOUCellAddress, aAdvSource, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sOUCellAddress);
+ }
+
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
+ SvXMLElementExport aElemF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
+ rExport.CheckAttrList();
+ sal_Bool bIsCaseSensitive = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE))));
+ sal_Bool bUseRegularExpressions = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX))));
+ sal_Bool bAnd = false;
+ sal_Bool bOr = false;
+ for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
+ {
+ if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
+ bAnd = sal_True;
+ else
+ bOr = sal_True;
+ }
+ if (bOr && !bAnd)
+ {
+ SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
+ {
+ WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ else if (bAnd && !bOr)
+ {
+ SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nTableFilterFields; ++i)
+ {
+ WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ else if (nTableFilterFields == 1)
+ {
+ WriteCondition(aTableFilterFields[0], bIsCaseSensitive, bUseRegularExpressions);
+ }
+ else
+ {
+ SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
+ sheet::TableFilterField2 aPrevFilterField = aTableFilterFields[0];
+ sheet::FilterConnection aConnection = aTableFilterFields[1].Connection;
+ sal_Bool bOpenAndElement;
+ rtl::OUString aName = rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
+ if (aConnection == sheet::FilterConnection_AND)
+ {
+ rExport.StartElement( aName, sal_True);
+ bOpenAndElement = sal_True;
+ }
+ else
+ bOpenAndElement = false;
+ for (sal_Int32 i = 1; i < nTableFilterFields; ++i)
+ {
+ if (aConnection != aTableFilterFields[i].Connection)
+ {
+ aConnection = aTableFilterFields[i].Connection;
+ if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND)
+ {
+ rExport.StartElement( aName, sal_True );
+ bOpenAndElement = sal_True;
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (i == nTableFilterFields - 1)
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = false;
+ }
+ }
+ else
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (bOpenAndElement)
+ {
+ rExport.EndElement(aName, sal_True);
+ bOpenAndElement = false;
+ }
+ if (i == nTableFilterFields - 1)
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ }
+ else
+ {
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ aPrevFilterField = aTableFilterFields[i];
+ if (i == nTableFilterFields - 1)
+ WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions);
+ }
+ }
+ if(bOpenAndElement)
+ rExport.EndElement(aName, sal_True);
+ }
+ }
+ }
+}
+
+void ScXMLExportDatabaseRanges::WriteSortDescriptor(const uno::Sequence <beans::PropertyValue> aSortProperties)
+{
+ uno::Sequence <table::TableSortField> aSortFields;
+ sal_Bool bBindFormatsToContent (sal_True);
+ sal_Bool bCopyOutputData (false);
+ sal_Bool bIsUserListEnabled (false);
+ table::CellAddress aOutputPosition;
+ sal_Int32 nUserListIndex = 0;
+ sal_Int32 nProperties = aSortProperties.getLength();
+ sal_Int32 i;
+ for (i = 0; i < nProperties; ++i)
+ {
+ if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_BINDFMT) == 0)
+ bBindFormatsToContent = ::cppu::any2bool(aSortProperties[i].Value);
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COPYOUT) == 0)
+ bCopyOutputData = ::cppu::any2bool(aSortProperties[i].Value);
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISULIST) == 0)
+ bIsUserListEnabled = ::cppu::any2bool(aSortProperties[i].Value);
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_OUTPOS) == 0)
+ aSortProperties[i].Value >>= aOutputPosition;
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_UINDEX) == 0)
+ aSortProperties[i].Value >>= nUserListIndex;
+ else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_SORTFLD) == 0)
+ aSortProperties[i].Value >>= aSortFields;
+ }
+ sal_Int32 nSortFields = aSortFields.getLength();
+ if (nSortFields > 0)
+ {
+ if (!bBindFormatsToContent)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+ if (bCopyOutputData)
+ {
+ rtl::OUString sOUCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress);
+ }
+
+ if (aSortFields[0].IsCaseSensitive)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+#ifdef DBG_UTIL
+ sal_Bool bCaseSensitive(aSortFields[0].IsCaseSensitive);
+ for (i = 1; i < nSortFields; ++i)
+ {
+ DBG_ASSERT(bCaseSensitive == aSortFields[i].IsCaseSensitive, "seems that it is now possible to have every field case sensitive");
+ }
+#endif
+ if (aSortFields[0].CollatorLocale.Language.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aSortFields[0].CollatorLocale.Language);
+ if (aSortFields[0].CollatorLocale.Country.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aSortFields[0].CollatorLocale.Country);
+ if (aSortFields[0].CollatorAlgorithm.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aSortFields[0].CollatorAlgorithm);
+#ifdef DBG_UTIL
+ rtl::OUString sLanguage(aSortFields[0].CollatorLocale.Language);
+ rtl::OUString sCountry(aSortFields[0].CollatorLocale.Country);
+ rtl::OUString sAlgorithm(aSortFields[0].CollatorAlgorithm);
+ for (i = 1; i < nSortFields; ++i)
+ {
+ DBG_ASSERT(sLanguage == aSortFields[i].CollatorLocale.Language, "seems that it is now possible to have every field localized");
+ DBG_ASSERT(sCountry == aSortFields[i].CollatorLocale.Country, "seems that it is now possible to have every field localized");
+ DBG_ASSERT(sAlgorithm == aSortFields[i].CollatorAlgorithm, "seems that it is now possible to have every field localized");
+ }
+#endif
+ SvXMLElementExport aElemS(rExport, XML_NAMESPACE_TABLE, XML_SORT, sal_True, sal_True);
+ rExport.CheckAttrList();
+ for (i = 0; i < nSortFields; ++i)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSortFields[i].Field));
+ if (!aSortFields[i].IsAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+ if (!bIsUserListEnabled)
+ {
+ switch (aSortFields[i].FieldType)
+ {
+ case table::TableSortFieldType_ALPHANUMERIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TEXT);
+ break;
+ case table::TableSortFieldType_AUTOMATIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
+ break;
+ case table::TableSortFieldType_NUMERIC :
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST)) + rtl::OUString::valueOf(nUserListIndex));
+ SvXMLElementExport aElemSb(rExport, XML_NAMESPACE_TABLE, XML_SORT_BY, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+}
+
+void ScXMLExportDatabaseRanges::WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName)
+{
+ uno::Reference <container::XIndexAccess> xIndexAccess (xSubTotalDescriptor, uno::UNO_QUERY);
+ if (xIndexAccess.is())
+ {
+ sal_Int32 nSubTotalFields = xIndexAccess->getCount();
+ if (nSubTotalFields > 0)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (xSubTotalDescriptor, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (!::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
+ if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ }
+ SvXMLElementExport aElemSTRs(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True);
+ rExport.CheckAttrList();
+ {
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam(aSubTotalParam);
+ if (aSubTotalParam.bDoSort)
+ {
+ if (!aSubTotalParam.bAscending)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+ if (aSubTotalParam.bUserDef)
+ {
+ rtl::OUString sUserList(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST));
+ sUserList += rtl::OUString::valueOf(aSubTotalParam.nUserIndex);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, sUserList);
+ }
+ SvXMLElementExport aElemSGs(rExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+ for (sal_Int32 i = 0; i < nSubTotalFields; ++i)
+ {
+ uno::Reference <sheet::XSubTotalField> xSubTotalField(xIndexAccess->getByIndex(i), uno::UNO_QUERY);
+ if (xSubTotalField.is())
+ {
+ sal_Int32 nGroupColumn = xSubTotalField->getGroupColumn();
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nGroupColumn));
+ SvXMLElementExport aElemSTR(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ uno::Sequence <sheet::SubTotalColumn> aSubTotalColumns = xSubTotalField->getSubTotalColumns();
+ sal_Int32 nSubTotalColumns = aSubTotalColumns.getLength();
+ for (sal_Int32 j = 0; j < nSubTotalColumns; ++j)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSubTotalColumns[j].Column));
+ rtl::OUString sFunction;
+ ScXMLConverter::GetStringFromFunction( sFunction, aSubTotalColumns[j].Function );
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
+ SvXMLElementExport aElemSTF(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True);
+ rExport.CheckAttrList();
+ }
+ }
+ }
+ }
+ }
+}
+
+namespace {
+
+class WriteDatabaseRange : public ::std::unary_function<ScDBData, void>
+{
+public:
+ WriteDatabaseRange(ScXMLExport& rExport, ScDocument* pDoc) :
+ mrExport(rExport), mpDoc(pDoc), mnCounter(0) {}
+
+ void operator() (const ::std::pair<SCTAB, const ScDBData*>& r)
+ {
+ // name
+ OUStringBuffer aBuf;
+ aBuf.appendAscii(STR_DB_LOCAL_NONAME);
+ aBuf.append(static_cast<sal_Int32>(r.first)); // appended number equals sheet index on import.
+
+ write(aBuf.makeStringAndClear(), *r.second);
+ }
+
+ void operator() (const ScDBData& rData)
+ {
+ // name
+ OUStringBuffer aBuf;
+ aBuf.appendAscii(STR_DB_GLOBAL_NONAME);
+ aBuf.append(++mnCounter); // 1-based, for entirely arbitrary reasons. The numbers are ignored on import.
+
+ write(aBuf.makeStringAndClear(), rData);
+ }
+
+private:
+ void write(const OUString& rName, const ScDBData& rData)
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rName);
+
+ // range
+ ScRange aRange;
+ rData.GetArea(aRange);
+ OUString aRangeStr;
+ ScRangeStringConverter::GetStringFromRange(
+ aRangeStr, aRange, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aRangeStr);
+
+ // various boolean flags.
+ if (rData.HasImportSelection())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
+ if (rData.HasAutoFilter())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
+ if (rData.IsKeepFmt())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
+ if (rData.IsDoSize())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
+ if (rData.IsStripData())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
+
+ ScQueryParam aQueryParam;
+ rData.GetQueryParam(aQueryParam);
+ if (!aQueryParam.bHasHeader)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
+
+ ScSortParam aSortParam;
+ rData.GetSortParam(aSortParam);
+ if (!aSortParam.bByRow)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
+
+ sal_Int32 nRefresh = rData.GetRefreshDelay();
+ if (nRefresh)
+ {
+ OUStringBuffer aBuf;
+ SvXMLUnitConverter::convertTime(aBuf, static_cast<double>(nRefresh) / 86400.0);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, aBuf.makeStringAndClear());
+ }
+
+ SvXMLElementExport aElemDR(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
+
+ writeImport(rData);
+ writeFilter(rData);
+ writeSort(rData);
+ writeSubtotals(rData);
+ }
+
+ void writeImport(const ScDBData& rData)
+ {
+ ScImportParam aParam;
+ rData.GetImportParam(aParam);
+
+ OUString sDatabaseName;
+ OUString sConRes;
+
+ ::svx::ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(aParam.aDBName);
+ if (aDescriptor.has(::svx::daDataSource))
+ {
+ sDatabaseName = aParam.aDBName;
+ }
+ else if (aDescriptor.has(::svx::daConnectionResource))
+ {
+ sConRes = aParam.aDBName;
+ }
+
+ sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE;
+ if (aParam.bImport)
+ {
+ if (aParam.bSql)
+ nSourceType = sheet::DataImportMode_SQL;
+ else if (aParam.nType == ScDbQuery)
+ nSourceType = sheet::DataImportMode_QUERY;
+ else
+ nSourceType = sheet::DataImportMode_TABLE;
+ }
+
+ switch (nSourceType)
+ {
+ case sheet::DataImportMode_NONE : break;
+ case sheet::DataImportMode_QUERY :
+ {
+ if (sDatabaseName.getLength())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, aParam.aStatement);
+ SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, true, true);
+ if (sConRes.getLength())
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+ }
+ }
+ break;
+ case sheet::DataImportMode_TABLE :
+ {
+ if (sDatabaseName.getLength())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, aParam.aStatement);
+ SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, true, true);
+ if (sConRes.getLength())
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+ }
+ }
+ break;
+ case sheet::DataImportMode_SQL :
+ {
+ if (sDatabaseName.getLength())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, aParam.aStatement);
+ if (!aParam.bNative)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
+ SvXMLElementExport aElemID(mrExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, true, true);
+ if (sConRes.getLength())
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes );
+ SvXMLElementExport aElemCR(mrExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, true, true);
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ void writeSort(const ScDBData& rData)
+ {
+ ScSortParam aParam;
+ rData.GetSortParam(aParam);
+
+ // Count sort items first.
+ size_t nSortCount = 0;
+ for (; nSortCount < MAXSORT; ++nSortCount)
+ {
+ if (!aParam.bDoSort[nSortCount])
+ break;
+ }
+
+ if (!nSortCount)
+ // Nothing to export.
+ return;
+
+ ScAddress aOutPos(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab);
+
+ if (!aParam.bIncludePattern)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+
+ if (!aParam.bInplace)
+ {
+ OUString aStr;
+ ScRangeStringConverter::GetStringFromAddress(
+ aStr, aOutPos, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aStr);
+ }
+
+ if (aParam.bCaseSens)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+
+ if (!aParam.aCollatorLocale.Language.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aParam.aCollatorLocale.Language);
+ if (!aParam.aCollatorLocale.Country.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aParam.aCollatorLocale.Country);
+ if (!aParam.aCollatorAlgorithm.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aParam.aCollatorAlgorithm);
+
+ SvXMLElementExport aElemS(mrExport, XML_NAMESPACE_TABLE, XML_SORT, true, true);
+
+ ScRange aRange;
+ rData.GetArea(aRange);
+ SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+
+ for (size_t i = 0; i < nSortCount; ++i)
+ {
+ // Convert field value from absolute to relative.
+ SCCOLROW nField = aParam.nField[i] - nFieldStart;
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nField));
+
+ if (!aParam.bAscending[i])
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+ if (aParam.bUserDef)
+ {
+ OUStringBuffer aBuf;
+ aBuf.appendAscii(SC_USERLIST);
+ aBuf.append(aParam.nUserIndex);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
+ }
+ else
+ {
+ // Right now we only support automatic field type. In the
+ // future we may support numeric or alphanumeric field type.
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC);
+ }
+
+ SvXMLElementExport aElemSb(mrExport, XML_NAMESPACE_TABLE, XML_SORT_BY, true, true);
+ }
+ }
+
+ OUString getOperatorXML(const ScQueryEntry& rEntry, bool bRegExp) const
+ {
+ switch (rEntry.eOp)
+ {
+ case SC_BEGINS_WITH:
+ return GetXMLToken(XML_BEGINS_WITH);
+ case SC_BOTPERC:
+ return GetXMLToken(XML_BOTTOM_PERCENT);
+ case SC_BOTVAL:
+ return GetXMLToken(XML_BOTTOM_VALUES);
+ case SC_CONTAINS:
+ return GetXMLToken(XML_CONTAINS);
+ case SC_DOES_NOT_BEGIN_WITH:
+ return GetXMLToken(XML_DOES_NOT_BEGIN_WITH);
+ case SC_DOES_NOT_CONTAIN:
+ return GetXMLToken(XML_DOES_NOT_CONTAIN);
+ case SC_DOES_NOT_END_WITH:
+ return GetXMLToken(XML_DOES_NOT_END_WITH);
+ case SC_ENDS_WITH:
+ return GetXMLToken(XML_ENDS_WITH);
+ case SC_EQUAL:
+ if (!rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING)
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ return GetXMLToken(XML_EMPTY);
+ else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ return GetXMLToken(XML_NOEMPTY);
+ }
+ if (bRegExp)
+ return GetXMLToken(XML_MATCH);
+ else
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ case SC_GREATER:
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ case SC_GREATER_EQUAL:
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ case SC_LESS:
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ case SC_LESS_EQUAL:
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ case SC_NOT_EQUAL:
+ if (bRegExp)
+ return GetXMLToken(XML_NOMATCH);
+ else
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ case SC_TOPPERC:
+ return GetXMLToken(XML_TOP_PERCENT);
+ case SC_TOPVAL:
+ return GetXMLToken(XML_TOP_VALUES);
+ default:
+ ;
+ }
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ }
+
+ void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField - nFieldStart));
+ if (bCaseSens)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+ if (rEntry.bQueryByString)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *rEntry.pStr);
+ else
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
+ OUStringBuffer aBuf;
+ mrExport.GetMM100UnitConverter().convertDouble(aBuf, rEntry.nVal);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aBuf.makeStringAndClear());
+ }
+
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(rEntry, bRegExp));
+ SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
+ }
+
+ void writeFilter(const ScDBData& rData)
+ {
+ ScQueryParam aParam;
+ rData.GetQueryParam(aParam);
+ size_t nCount = 0;
+ for (size_t n = aParam.GetEntryCount(); nCount < n; ++nCount)
+ {
+ if (!aParam.GetEntry(nCount).bDoQuery)
+ break;
+ }
+
+ if (!nCount)
+ // No filter criteria to save. Bail out.
+ return;
+
+ if (!aParam.bInplace)
+ {
+ OUString aAddrStr;
+ ScRangeStringConverter::GetStringFromAddress(
+ aAddrStr, ScAddress(aParam.nDestCol, aParam.nDestRow, aParam.nDestTab), mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, aAddrStr);
+ }
+
+ ScRange aAdvSource;
+ if (rData.GetAdvancedQuerySource(aAdvSource))
+ {
+ OUString aAddrStr;
+ ScRangeStringConverter::GetStringFromRange(
+ aAddrStr, aAdvSource, mpDoc, ::formula::FormulaGrammar::CONV_OOO);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, aAddrStr);
+ }
+
+ if (!aParam.bDuplicate)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
+
+ SvXMLElementExport aElemF(mrExport, XML_NAMESPACE_TABLE, XML_FILTER, true, true);
+
+ bool bAnd = false;
+ bool bOr = false;
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ const ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (rEntry.eConnect == SC_AND)
+ bAnd = true;
+ else
+ bOr = true;
+ }
+
+ // Note that export field index values are relative to the first field.
+ ScRange aRange;
+ rData.GetArea(aRange);
+ SCCOLROW nFieldStart = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+
+ if (bOr && !bAnd)
+ {
+ SvXMLElementExport aElemOr(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
+ for (size_t i = 0; i < nCount; ++i)
+ writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ }
+ else if (bAnd && !bOr)
+ {
+ SvXMLElementExport aElemAnd(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, true, true);
+ for (size_t i = 0; i < nCount; ++i)
+ writeCondition(aParam.GetEntry(i), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ }
+ else if (nCount == 1)
+ {
+ writeCondition(aParam.GetEntry(0), nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ }
+ else
+ {
+ SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, true, true);
+ ScQueryEntry aPrevEntry = aParam.GetEntry(0);
+ ScQueryConnect eConnect = aParam.GetEntry(1).eConnect;
+ bool bOpenAndElement = false;
+ OUString aName = mrExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND));
+
+ if (eConnect == SC_AND)
+ {
+ mrExport.StartElement(aName, true);
+ bOpenAndElement = true;
+ }
+ else
+ bOpenAndElement = false;
+
+ for (size_t i = 1; i < nCount; ++i)
+ {
+ const ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (eConnect != rEntry.eConnect)
+ {
+ eConnect = rEntry.eConnect;
+ if (rEntry.eConnect == SC_AND)
+ {
+ mrExport.StartElement(aName, true );
+ bOpenAndElement = true;
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ aPrevEntry = rEntry;
+ if (i == nCount - 1)
+ {
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ mrExport.EndElement(aName, true);
+ bOpenAndElement = false;
+ }
+ }
+ else
+ {
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ aPrevEntry = rEntry;
+ if (bOpenAndElement)
+ {
+ mrExport.EndElement(aName, true);
+ bOpenAndElement = false;
+ }
+ if (i == nCount - 1)
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ }
+ }
+ else
+ {
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ aPrevEntry = rEntry;
+ if (i == nCount - 1)
+ writeCondition(aPrevEntry, nFieldStart, aParam.bCaseSens, aParam.bRegExp);
+ }
+ }
+ if(bOpenAndElement)
+ mrExport.EndElement(aName, true);
+ }
+ }
+
+ void writeSubtotals(const ScDBData& rData)
+ {
+ ScSubTotalParam aParam;
+ rData.GetSubTotalParam(aParam);
+
+ size_t nCount = 0;
+ for (; nCount < MAXSUBTOTAL; ++nCount)
+ {
+ if (!aParam.bGroupActive[nCount])
+ break;
+ }
+
+ if (!nCount)
+ return;
+
+ if (!aParam.bIncludePattern)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE);
+
+ if (aParam.bPagebreak)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE);
+
+ if (aParam.bCaseSens)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
+
+ SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True);
+
+ if (aParam.bDoSort)
+ {
+ if (!aParam.bAscending)
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
+
+ if (aParam.bUserDef)
+ {
+ OUStringBuffer aBuf;
+ aBuf.appendAscii(SC_USERLIST);
+ aBuf.append(static_cast<sal_Int32>(aParam.nUserIndex));
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True);
+ }
+
+ for (size_t i = 0; i < MAXSUBTOTAL; ++i)
+ {
+ if (!aParam.bGroupActive[i])
+ // We're done!
+ break;
+
+ sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nFieldCol));
+ SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True);
+
+ for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j)
+ {
+ sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
+ ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
+
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(nCol));
+ OUString aFuncStr;
+ ScXMLConverter::GetStringFromFunction(aFuncStr, eFunc);
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, aFuncStr);
+
+ SvXMLElementExport aElemSTF(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True);
+ }
+ }
+ }
+
+private:
+ ScXMLExport& mrExport;
+ ScDocument* mpDoc;
+ sal_Int32 mnCounter;
+};
+
+}
+
+void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ typedef ::std::map<SCTAB, const ScDBData*> SheetLocalDBs;
+
+ pDoc = rExport.GetDocument();
+ if (pDoc)
+ {
+ // Get sheet-local anonymous ranges.
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SheetLocalDBs aSheetDBs;
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ const ScDBData* p = pDoc->GetAnonymousDBData(i);
+ if (p)
+ aSheetDBs.insert(SheetLocalDBs::value_type(i, p));
+ }
+
+ bool bHasRanges = !aSheetDBs.empty();
+
+ // See if we have global ranges.
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ if (pDBCollection)
+ if (pDBCollection->GetCount() > 0 || !pDBCollection->getAnonRanges().empty())
+ bHasRanges = true;
+
+ if (!bHasRanges)
+ // No ranges to export. Bail out.
+ return;
+
+ SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True);
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ rExport.CheckAttrList();
+ if (xDatabaseRanges.is())
+ {
+ uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames());
+ sal_Int32 nDatabaseRangesCount = aRanges.getLength();
+ if (nDatabaseRangesCount > 0)
+ {
+ for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i)
+ {
+ rtl::OUString sDatabaseRangeName(aRanges[i]);
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ rtl::OUString sOUUnbenannt (ScGlobal::GetRscString(STR_DB_NONAME));
+ if (sOUUnbenannt != sDatabaseRangeName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName);
+ table::CellRangeAddress aRangeAddress(xDatabaseRange->getDataArea());
+ rtl::OUString sOUAddress;
+ ScRangeStringConverter::GetStringFromRange( sOUAddress, aRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ rExport.AddAttribute (XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUAddress);
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ if (pDBData->HasImportSelection())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE);
+ if (pDBData->HasAutoFilter())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE);
+ uno::Reference <beans::XPropertySet> xPropertySetDatabaseRange (xDatabaseRange, uno::UNO_QUERY);
+ if (xPropertySetDatabaseRange.is())
+ {
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE);
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE);
+ if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE);
+ }
+
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ uno::Sequence <beans::PropertyValue> aSortProperties(xDatabaseRange->getSortDescriptor());
+ if (xSheetFilterDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xFilterProperties (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xFilterProperties.is())
+ {
+ if (!::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)))))
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE);
+
+ sal_Bool bSortColumns(sal_True);
+ sal_Bool bFound(false);
+ sal_Int32 nProperty(0);
+ while (!bFound && (nProperty < aSortProperties.getLength()))
+ {
+ if (aSortProperties[nProperty].Name.compareToAscii(SC_UNONAME_ISSORTCOLUMNS) == 0)
+ {
+ bSortColumns = ::cppu::any2bool(aSortProperties[nProperty].Value);
+ bFound = sal_True;
+ }
+ else
+ ++nProperty;
+ }
+
+ if (bSortColumns)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN);
+ }
+ }
+ sal_Int32 nRefresh( pDBData->GetRefreshDelay() );
+ if( nRefresh )
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
+ rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
+ }
+ SvXMLElementExport aElemDR(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True);
+ rExport.CheckAttrList();
+ WriteImportDescriptor(xDatabaseRange->getImportDescriptor());
+ if (xSheetFilterDescriptor.is())
+ WriteFilterDescriptor(xSheetFilterDescriptor, sDatabaseRangeName);
+ WriteSortDescriptor(aSortProperties);
+ WriteSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor(), sDatabaseRangeName);
+ }
+ }
+ }
+ }
+ }
+
+ WriteDatabaseRange func(rExport, pDoc);
+
+ // Write sheet-local ranges.
+ ::std::for_each(aSheetDBs.begin(), aSheetDBs.end(), func);
+
+ // Add global anonymous DB ranges.
+ const ScDBCollection::AnonDBsType& rAnonDBs = pDBCollection->getAnonRanges();
+ ::std::for_each(rAnonDBs.begin(), rAnonDBs.end(), func);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.hxx b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
new file mode 100644
index 000000000000..31b27c4c87d2
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTDATABASERANGES_HXX
+#define SC_XMLEXPORTDATABASERANGES_HXX
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+class ScXMLExport;
+class ScDocument;
+class ScMyEmptyDatabaseRangesContainer;
+
+class ScXMLExportDatabaseRanges
+{
+ ScXMLExport& rExport;
+ ScDocument* pDoc;
+
+ void WriteImportDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aImportDescriptor);
+ rtl::OUString getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const;
+ void WriteCondition(const com::sun::star::sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions);
+ void WriteFilterDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName);
+ void WriteSortDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortProperties);
+ void WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName);
+public:
+ ScXMLExportDatabaseRanges(ScXMLExport& rExport);
+ ~ScXMLExportDatabaseRanges();
+ ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
+ void WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx
new file mode 100644
index 000000000000..d990bf035038
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportIterator.cxx
@@ -0,0 +1,895 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportIterator.hxx"
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <tools/debug.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include "dociter.hxx"
+#include "convuno.hxx"
+#include "xmlexprt.hxx"
+#include "XMLExportSharedData.hxx"
+#include "XMLStylesExportHelper.hxx"
+#include "document.hxx"
+
+#include <algorithm>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+//==============================================================================
+
+ScMyIteratorBase::ScMyIteratorBase()
+{
+}
+
+ScMyIteratorBase::~ScMyIteratorBase()
+{
+}
+
+void ScMyIteratorBase::UpdateAddress( table::CellAddress& rCellAddress )
+{
+ table::CellAddress aNewAddr( rCellAddress );
+ if( GetFirstAddress( aNewAddr ) )
+ {
+ if( (aNewAddr.Sheet == rCellAddress.Sheet) &&
+ ((aNewAddr.Row < rCellAddress.Row) ||
+ ((aNewAddr.Row == rCellAddress.Row) && (aNewAddr.Column < rCellAddress.Column))) )
+ rCellAddress = aNewAddr;
+ }
+}
+
+
+//==============================================================================
+
+sal_Bool ScMyShape::operator<(const ScMyShape& aShape) const
+{
+ if( aAddress.Tab() != aShape.aAddress.Tab() )
+ return (aAddress.Tab() < aShape.aAddress.Tab());
+ else if( aAddress.Row() != aShape.aAddress.Row() )
+ return (aAddress.Row() < aShape.aAddress.Row());
+ else
+ return (aAddress.Col() < aShape.aAddress.Col());
+}
+
+ScMyShapesContainer::ScMyShapesContainer()
+ : aShapeList()
+{
+}
+
+ScMyShapesContainer::~ScMyShapesContainer()
+{
+}
+
+void ScMyShapesContainer::AddNewShape( const ScMyShape& aShape )
+{
+ aShapeList.push_back(aShape);
+}
+
+sal_Bool ScMyShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aShapeList.begin()->aAddress );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aShapeList.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyShapeList::iterator aItr(aShapeList.begin());
+ ScMyShapeList::iterator aEndItr(aShapeList.end());
+ while( (aItr != aEndItr) && (aItr->aAddress == aAddress) )
+ {
+ rMyCell.aShapeList.push_back(*aItr);
+ aItr = aShapeList.erase(aItr);
+ }
+ rMyCell.bHasShape = !rMyCell.aShapeList.empty();
+}
+
+void ScMyShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyShapeList::iterator aItr = aShapeList.begin();
+ while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) )
+ aItr = aShapeList.erase(aItr);
+}
+
+void ScMyShapesContainer::Sort()
+{
+ aShapeList.sort();
+}
+
+sal_Bool ScMyNoteShape::operator<(const ScMyNoteShape& aNote) const
+{
+ if( aPos.Tab() != aNote.aPos.Tab() )
+ return (aPos.Tab() < aNote.aPos.Tab());
+ else if( aPos.Row() != aNote.aPos.Row() )
+ return (aPos.Row() < aNote.aPos.Row());
+ else
+ return (aPos.Col() < aNote.aPos.Col());
+}
+
+ScMyNoteShapesContainer::ScMyNoteShapesContainer()
+ : aNoteShapeList()
+{
+}
+
+ScMyNoteShapesContainer::~ScMyNoteShapesContainer()
+{
+}
+
+void ScMyNoteShapesContainer::AddNewNote( const ScMyNoteShape& aNote )
+{
+ aNoteShapeList.push_back(aNote);
+}
+
+sal_Bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int16 nTable = rCellAddress.Sheet;
+ if( !aNoteShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aNoteShapeList.begin()->aPos );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.xNoteShape.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) )
+ {
+ rMyCell.xNoteShape = aItr->xShape;
+ aItr = aNoteShapeList.erase(aItr);
+ }
+}
+
+void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) )
+ aItr = aNoteShapeList.erase(aItr);
+}
+
+void ScMyNoteShapesContainer::Sort()
+{
+ aNoteShapeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyMergedRange::operator<(const ScMyMergedRange& aRange) const
+{
+ if( aCellRange.Sheet != aRange.aCellRange.Sheet )
+ return (aCellRange.Sheet < aRange.aCellRange.Sheet);
+ else if( aCellRange.StartRow != aRange.aCellRange.StartRow )
+ return (aCellRange.StartRow < aRange.aCellRange.StartRow);
+ else
+ return (aCellRange.StartColumn < aRange.aCellRange.StartColumn);
+}
+
+
+ScMyMergedRangesContainer::ScMyMergedRangesContainer()
+ : aRangeList()
+{
+}
+
+ScMyMergedRangesContainer::~ScMyMergedRangesContainer()
+{
+}
+
+void ScMyMergedRangesContainer::AddRange(const table::CellRangeAddress aMergedRange)
+{
+ sal_Int32 nStartRow(aMergedRange.StartRow);
+ sal_Int32 nEndRow(aMergedRange.EndRow);
+
+ ScMyMergedRange aRange;
+ aRange.bIsFirst = sal_True;
+ aRange.aCellRange = aMergedRange;
+ aRange.aCellRange.EndRow = nStartRow;
+ aRange.nRows = nEndRow - nStartRow + 1;
+ aRangeList.push_back( aRange );
+
+ aRange.bIsFirst = false;
+ aRange.nRows = 0;
+ for( sal_Int32 nRow = nStartRow + 1; nRow <= nEndRow; ++nRow )
+ {
+ aRange.aCellRange.StartRow = aRange.aCellRange.EndRow = nRow;
+ aRangeList.push_back(aRange);
+ }
+}
+
+sal_Bool ScMyMergedRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aRangeList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aRangeList.begin()->aCellRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMergedBase = rMyCell.bIsCovered = false;
+ ScMyMergedRangeList::iterator aItr(aRangeList.begin());
+ if( aItr != aRangeList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, aItr->aCellRange );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.aMergeRange = aItr->aCellRange;
+ if (aItr->bIsFirst)
+ rMyCell.aMergeRange.EndRow = rMyCell.aMergeRange.StartRow + aItr->nRows - 1;
+ rMyCell.bIsMergedBase = aItr->bIsFirst;
+ rMyCell.bIsCovered = !aItr->bIsFirst;
+ if( aItr->aCellRange.StartColumn < aItr->aCellRange.EndColumn )
+ {
+ ++(aItr->aCellRange.StartColumn);
+ aItr->bIsFirst = false;
+ }
+ else
+ aRangeList.erase(aItr);
+ }
+ }
+}
+
+void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyMergedRangeList::iterator aItr = aRangeList.begin();
+ while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) )
+ aItr = aRangeList.erase(aItr);
+}
+
+void ScMyMergedRangesContainer::Sort()
+{
+ aRangeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyAreaLink::Compare( const ScMyAreaLink& rAreaLink ) const
+{
+ return (GetRowCount() == rAreaLink.GetRowCount()) &&
+ (sFilter == rAreaLink.sFilter) &&
+ (sFilterOptions == rAreaLink.sFilterOptions) &&
+ (sURL == rAreaLink.sURL) &&
+ (sSourceStr == rAreaLink.sSourceStr);
+}
+
+sal_Bool ScMyAreaLink::operator<(const ScMyAreaLink& rAreaLink ) const
+{
+ if( aDestRange.Sheet != rAreaLink.aDestRange.Sheet )
+ return (aDestRange.Sheet < rAreaLink.aDestRange.Sheet);
+ else if( aDestRange.StartRow != rAreaLink.aDestRange.StartRow )
+ return (aDestRange.StartRow < rAreaLink.aDestRange.StartRow);
+ else
+ return (aDestRange.StartColumn < rAreaLink.aDestRange.StartColumn);
+}
+
+ScMyAreaLinksContainer::ScMyAreaLinksContainer() :
+ aAreaLinkList()
+{
+}
+
+ScMyAreaLinksContainer::~ScMyAreaLinksContainer()
+{
+}
+
+sal_Bool ScMyAreaLinksContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aAreaLinkList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aAreaLinkList.begin()->aDestRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasAreaLink = false;
+ ScMyAreaLinkList::iterator aItr(aAreaLinkList.begin());
+ if( aItr != aAreaLinkList.end() )
+ {
+ table::CellAddress aAddress;
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if( aAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasAreaLink = sal_True;
+ rMyCell.aAreaLink = *aItr;
+ aItr = aAreaLinkList.erase( aItr );
+ sal_Bool bFound = sal_True;
+ while (aItr != aAreaLinkList.end() && bFound)
+ {
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if (aAddress == rMyCell.aCellAddress)
+ {
+ OSL_FAIL("more than one linked range on one cell");
+ aItr = aAreaLinkList.erase( aItr );
+ }
+ else
+ bFound = false;
+ }
+ }
+ }
+}
+
+void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin();
+ while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) )
+ aItr = aAreaLinkList.erase(aItr);
+}
+
+void ScMyAreaLinksContainer::Sort()
+{
+ aAreaLinkList.sort();
+}
+
+//==============================================================================
+
+ScMyCellRangeAddress::ScMyCellRangeAddress(const table::CellRangeAddress& rRange)
+ : table::CellRangeAddress(rRange)
+{
+}
+
+sal_Bool ScMyCellRangeAddress::operator<(const ScMyCellRangeAddress& rRange ) const
+{
+ if( Sheet != rRange.Sheet )
+ return (Sheet < rRange.Sheet);
+ else if( StartRow != rRange.StartRow )
+ return (StartRow < rRange.StartRow);
+ else
+ return (StartColumn < rRange.StartColumn);
+}
+
+ScMyEmptyDatabaseRangesContainer::ScMyEmptyDatabaseRangesContainer()
+ : aDatabaseList()
+{
+}
+
+ScMyEmptyDatabaseRangesContainer::~ScMyEmptyDatabaseRangesContainer()
+{
+}
+
+void ScMyEmptyDatabaseRangesContainer::AddNewEmptyDatabaseRange(const table::CellRangeAddress& aCellRange)
+{
+ sal_Int32 nStartRow(aCellRange.StartRow);
+ sal_Int32 nEndRow(aCellRange.EndRow);
+ ScMyCellRangeAddress aRange( aCellRange );
+ for( sal_Int32 nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ aRange.StartRow = aRange.EndRow = nRow;
+ aDatabaseList.push_back( aRange );
+ }
+}
+
+sal_Bool ScMyEmptyDatabaseRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDatabaseList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, *(aDatabaseList.begin()) );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasEmptyDatabase = false;
+ ScMyEmptyDatabaseRangeList::iterator aItr(aDatabaseList.begin());
+ if( aItr != aDatabaseList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, *aItr );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasEmptyDatabase = sal_True;
+ if( aItr->StartColumn < aItr->EndColumn )
+ ++(aItr->StartColumn);
+ else
+ aDatabaseList.erase(aItr);
+ }
+ }
+}
+
+void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin();
+ while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) )
+ aItr = aDatabaseList.erase(aItr);
+}
+
+void ScMyEmptyDatabaseRangesContainer::Sort()
+{
+ aDatabaseList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveObj::operator<( const ScMyDetectiveObj& rDetObj) const
+{
+ if( aPosition.Sheet != rDetObj.aPosition.Sheet )
+ return (aPosition.Sheet < rDetObj.aPosition.Sheet);
+ else if( aPosition.Row != rDetObj.aPosition.Row )
+ return (aPosition.Row < rDetObj.aPosition.Row);
+ else
+ return (aPosition.Column < rDetObj.aPosition.Column);
+}
+
+ScMyDetectiveObjContainer::ScMyDetectiveObjContainer() :
+ aDetectiveObjList()
+{
+}
+
+ScMyDetectiveObjContainer::~ScMyDetectiveObjContainer()
+{
+}
+
+void ScMyDetectiveObjContainer::AddObject( ScDetectiveObjType eObjType, const SCTAB nSheet,
+ const ScAddress& rPosition, const ScRange& rSourceRange,
+ sal_Bool bHasError )
+{
+ if( (eObjType == SC_DETOBJ_ARROW) ||
+ (eObjType == SC_DETOBJ_FROMOTHERTAB) ||
+ (eObjType == SC_DETOBJ_TOOTHERTAB) ||
+ (eObjType == SC_DETOBJ_CIRCLE) )
+ {
+ ScMyDetectiveObj aDetObj;
+ aDetObj.eObjType = eObjType;
+ if( eObjType == SC_DETOBJ_TOOTHERTAB )
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rSourceRange.aStart );
+ else
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rPosition );
+ ScUnoConversion::FillApiRange( aDetObj.aSourceRange, rSourceRange );
+
+ // #111064#; take the sheet where the object is found and not the sheet given in the ranges, because they are not always true
+ if (eObjType != SC_DETOBJ_FROMOTHERTAB)
+ {
+ // if the ObjType == SC_DETOBJ_FROMOTHERTAB then the SourceRange is not used and so it has not to be tested and changed
+ DBG_ASSERT(aDetObj.aPosition.Sheet == aDetObj.aSourceRange.Sheet, "It seems to be possible to have different sheets");
+ aDetObj.aSourceRange.Sheet = nSheet;
+ }
+ aDetObj.aPosition.Sheet = nSheet;
+
+ aDetObj.bHasError = bHasError;
+ aDetectiveObjList.push_back( aDetObj );
+ }
+}
+
+sal_Bool ScMyDetectiveObjContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveObjList.empty() )
+ {
+ rCellAddress = aDetectiveObjList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveObjVec.clear();
+ ScMyDetectiveObjList::iterator aItr(aDetectiveObjList.begin());
+ ScMyDetectiveObjList::iterator aEndItr(aDetectiveObjList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveObjVec.push_back( *aItr );
+ aItr = aDetectiveObjList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0);
+}
+
+void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin();
+ while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveObjList.erase(aItr);
+}
+
+void ScMyDetectiveObjContainer::Sort()
+{
+ aDetectiveObjList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveOp::operator<( const ScMyDetectiveOp& rDetOp) const
+{
+ if( aPosition.Sheet != rDetOp.aPosition.Sheet )
+ return (aPosition.Sheet < rDetOp.aPosition.Sheet);
+ else if( aPosition.Row != rDetOp.aPosition.Row )
+ return (aPosition.Row < rDetOp.aPosition.Row);
+ else
+ return (aPosition.Column < rDetOp.aPosition.Column);
+}
+
+ScMyDetectiveOpContainer::ScMyDetectiveOpContainer() :
+ aDetectiveOpList()
+{
+}
+
+ScMyDetectiveOpContainer::~ScMyDetectiveOpContainer()
+{
+}
+
+void ScMyDetectiveOpContainer::AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex )
+{
+ ScMyDetectiveOp aDetOp;
+ aDetOp.eOpType = eOpType;
+ ScUnoConversion::FillApiAddress( aDetOp.aPosition, rPosition );
+ aDetOp.nIndex = nIndex;
+ aDetectiveOpList.push_back( aDetOp );
+}
+
+sal_Bool ScMyDetectiveOpContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveOpList.empty() )
+ {
+ rCellAddress = aDetectiveOpList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveOpVec.clear();
+ ScMyDetectiveOpList::iterator aItr(aDetectiveOpList.begin());
+ ScMyDetectiveOpList::iterator aEndItr(aDetectiveOpList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveOpVec.push_back( *aItr );
+ aItr = aDetectiveOpList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0);
+}
+
+void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveOpList.erase(aItr);
+}
+
+void ScMyDetectiveOpContainer::Sort()
+{
+ aDetectiveOpList.sort();
+}
+
+//==============================================================================
+
+ScMyCell::ScMyCell() :
+ aShapeList(),
+ aDetectiveObjVec(),
+ fValue(0.0),
+ nValidationIndex(-1),
+ pBaseCell(NULL),
+ bIsAutoStyle( false ),
+ bHasShape( false ),
+ bIsMergedBase( false ),
+ bIsCovered( false ),
+ bHasAreaLink( false ),
+ bHasEmptyDatabase( false ),
+ bHasDetectiveObj( false ),
+ bHasDetectiveOp( false ),
+ bIsEditCell( false ),
+ bKnowWhetherIsEditCell( false ),
+ bHasStringValue( false ),
+ bHasDoubleValue( false ),
+ bHasXText( false ),
+ bIsMatrixBase( false ),
+ bIsMatrixCovered( false ),
+ bHasAnnotation( false )
+{
+}
+
+ScMyCell::~ScMyCell()
+{
+}
+
+//==============================================================================
+
+sal_Bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const
+{
+ if( aCellAddress.Row != rAnno.aCellAddress.Row )
+ return (aCellAddress.Row < rAnno.aCellAddress.Row);
+ else
+ return (aCellAddress.Column < rAnno.aCellAddress.Column);
+}
+
+
+ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport)
+ : pShapes(NULL),
+ pNoteShapes(NULL),
+ pEmptyDatabaseRanges(NULL),
+ pMergedRanges(NULL),
+ pAreaLinks(NULL),
+ pDetectiveObj(NULL),
+ pDetectiveOp(NULL),
+ rExport(rTempXMLExport),
+ pCellItr(NULL),
+ nCurrentTable(SCTAB_MAX)
+{
+}
+
+ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator()
+{
+ Clear();
+}
+
+void ScMyNotEmptyCellsIterator::Clear()
+{
+ if (pCellItr)
+ delete pCellItr;
+ if (!aAnnotations.empty())
+ {
+ OSL_FAIL("not all Annotations saved");
+ aAnnotations.clear();
+ }
+ pCellItr = NULL;
+ pShapes = NULL;
+ pNoteShapes = NULL;
+ pMergedRanges = NULL;
+ pAreaLinks = NULL;
+ pEmptyDatabaseRanges = NULL;
+ pDetectiveObj = NULL;
+ pDetectiveOp = NULL;
+ nCurrentTable = SCTAB_MAX;
+}
+
+void ScMyNotEmptyCellsIterator::UpdateAddress( table::CellAddress& rAddress )
+{
+ if( pCellItr->ReturnNext( nCellCol, nCellRow ) )
+ {
+ rAddress.Column = nCellCol;
+ rAddress.Row = nCellRow;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddress& rAddress )
+{
+ rMyCell.aCellAddress = rAddress;
+ rMyCell.bHasStringValue = false;
+ rMyCell.bHasDoubleValue = false;
+ rMyCell.bHasXText = false;
+ rMyCell.bKnowWhetherIsEditCell = false;
+ rMyCell.bIsEditCell = false;
+ if( (nCellCol == rAddress.Column) && (nCellRow == rAddress.Row) )
+ pCellItr->GetNext( nCellCol, nCellRow );
+}
+
+void ScMyNotEmptyCellsIterator::SetMatrixCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMatrixCovered = false;
+ rMyCell.bIsMatrixBase = false;
+
+ sal_Bool bIsMatrixBase(false);
+
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rMyCell.aCellAddress );
+ CellType eCalcType = rExport.GetDocument()->GetCellType( aScAddress );
+ switch (eCalcType)
+ {
+ case CELLTYPE_VALUE:
+ rMyCell.nType = table::CellContentType_VALUE;
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ rMyCell.nType = table::CellContentType_TEXT;
+ break;
+ case CELLTYPE_FORMULA:
+ rMyCell.nType = table::CellContentType_FORMULA;
+ break;
+ default:
+ rMyCell.nType = table::CellContentType_EMPTY;
+ }
+
+ if (rMyCell.nType == table::CellContentType_FORMULA)
+ if( rExport.IsMatrix( aScAddress, rMyCell.aMatrixRange, bIsMatrixBase ) )
+ {
+ rMyCell.bIsMatrixBase = bIsMatrixBase;
+ rMyCell.bIsMatrixCovered = !bIsMatrixBase;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell)
+{
+ aCell.bHasAnnotation = false;
+ if (!aAnnotations.empty())
+ {
+ ScMyExportAnnotationList::iterator aItr(aAnnotations.begin());
+ if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) &&
+ (aCell.aCellAddress.Row == aItr->aCellAddress.Row))
+ {
+ aCell.xAnnotation.set(aItr->xAnnotation);
+ uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY);
+ if (aCell.xAnnotation.is() && xSimpleText.is())
+ {
+ aCell.sAnnotationText = xSimpleText->getString();
+ if (aCell.sAnnotationText.getLength())
+ aCell.bHasAnnotation = sal_True;
+ }
+ aAnnotations.erase(aItr);
+ }
+ }
+
+ // test - bypass the API
+ // if (xCellRange.is())
+ // aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row));
+}
+
+void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable,
+ uno::Reference<sheet::XSpreadsheet>& rxTable)
+{
+ DBG_ASSERT(aAnnotations.empty(), "not all Annotations saved");
+ aLastAddress.Row = 0;
+ aLastAddress.Column = 0;
+ aLastAddress.Sheet = nTable;
+ if (nCurrentTable != nTable)
+ {
+ nCurrentTable = nTable;
+ if (pCellItr)
+ delete pCellItr;
+ pCellItr = new ScHorizontalCellIterator(rExport.GetDocument(), nCurrentTable, 0, 0,
+ static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable)));
+ xTable.set(rxTable);
+ xCellRange.set(xTable, uno::UNO_QUERY);
+ uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY);
+ if (xSheetAnnotationsSupplier.is())
+ {
+ uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY);
+ if (xAnnotationAccess.is())
+ {
+ uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration());
+ if (xAnnotations.is())
+ {
+ while (xAnnotations->hasMoreElements())
+ {
+ ScMyExportAnnotation aAnnotation;
+ aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY);
+ if (aAnnotation.xAnnotation.is())
+ {
+ aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition();
+ aAnnotations.push_back(aAnnotation);
+ }
+ }
+ if (!aAnnotations.empty())
+ aAnnotations.sort();
+ }
+ }
+ }
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip)
+{
+ // Skip entries for a sheet that is copied instead of saving normally.
+ // Cells (including aAnnotations) are handled separately in SetCurrentTable.
+
+ if( pShapes )
+ pShapes->SkipTable(nSkip);
+ if( pNoteShapes )
+ pNoteShapes->SkipTable(nSkip);
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SkipTable(nSkip);
+ if( pMergedRanges )
+ pMergedRanges->SkipTable(nSkip);
+ if( pAreaLinks )
+ pAreaLinks->SkipTable(nSkip);
+ if( pDetectiveObj )
+ pDetectiveObj->SkipTable(nSkip);
+ if( pDetectiveOp )
+ pDetectiveOp->SkipTable(nSkip);
+}
+
+sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles)
+{
+ table::CellAddress aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 );
+
+ UpdateAddress( aAddress );
+ if( pShapes )
+ pShapes->UpdateAddress( aAddress );
+ if( pNoteShapes )
+ pNoteShapes->UpdateAddress( aAddress );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->UpdateAddress( aAddress );
+ if( pMergedRanges )
+ pMergedRanges->UpdateAddress( aAddress );
+ if( pAreaLinks )
+ pAreaLinks->UpdateAddress( aAddress );
+ if( pDetectiveObj )
+ pDetectiveObj->UpdateAddress( aAddress );
+ if( pDetectiveOp )
+ pDetectiveOp->UpdateAddress( aAddress );
+
+ sal_Bool bFoundCell((aAddress.Column <= MAXCOL) && (aAddress.Row <= MAXROW));
+ if( bFoundCell )
+ {
+ SetCellData( aCell, aAddress );
+ if( pShapes )
+ pShapes->SetCellData( aCell );
+ if( pNoteShapes )
+ pNoteShapes->SetCellData( aCell );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SetCellData( aCell );
+ if( pMergedRanges )
+ pMergedRanges->SetCellData( aCell );
+ if( pAreaLinks )
+ pAreaLinks->SetCellData( aCell );
+ if( pDetectiveObj )
+ pDetectiveObj->SetCellData( aCell );
+ if( pDetectiveOp )
+ pDetectiveOp->SetCellData( aCell );
+
+ HasAnnotation( aCell );
+ SetMatrixCellData( aCell );
+ sal_Bool bIsAutoStyle;
+ // Ranges before the previous cell are not needed by ExportFormatRanges anymore and can be removed
+ sal_Int32 nRemoveBeforeRow = aLastAddress.Row;
+ aCell.nStyleIndex = pCellStyles->GetStyleNameIndex(aCell.aCellAddress.Sheet,
+ aCell.aCellAddress.Column, aCell.aCellAddress.Row,
+ bIsAutoStyle, aCell.nValidationIndex, aCell.nNumberFormat, nRemoveBeforeRow);
+ aLastAddress = aCell.aCellAddress;
+ aCell.bIsAutoStyle = bIsAutoStyle;
+
+ //#102799#; if the cell is in a DatabaseRange which should saved empty, the cell should have the type empty
+ if (aCell.bHasEmptyDatabase)
+ aCell.nType = table::CellContentType_EMPTY;
+ }
+ return bFoundCell;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx
new file mode 100644
index 000000000000..faa3e9bf75c2
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportIterator.hxx
@@ -0,0 +1,417 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTITERATOR_HXX
+#define SC_XMLEXPORTITERATOR_HXX
+
+#include <vector>
+#include <list>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include "global.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+
+class ScHorizontalCellIterator;
+struct ScMyCell;
+class ScXMLExport;
+class ScFormatRangeStyles;
+class ScBaseCell;
+
+//==============================================================================
+
+class ScMyIteratorBase
+{
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ) = 0;
+
+public:
+ ScMyIteratorBase();
+ virtual ~ScMyIteratorBase();
+
+ virtual void SetCellData( ScMyCell& rMyCell ) = 0;
+ virtual void Sort() = 0;
+
+ virtual void UpdateAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+};
+
+//==============================================================================
+
+struct ScMyShape
+{
+ ScAddress aAddress;
+ ScAddress aEndAddress;
+ sal_Int32 nEndX;
+ sal_Int32 nEndY;
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape;
+
+ sal_Bool operator<(const ScMyShape& aShape) const;
+};
+
+typedef std::list<ScMyShape> ScMyShapeList;
+
+class ScMyShapesContainer : ScMyIteratorBase
+{
+private:
+ ScMyShapeList aShapeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyShapesContainer();
+ virtual ~ScMyShapesContainer();
+
+ using ScMyIteratorBase::UpdateAddress;
+ void AddNewShape(const ScMyShape& aShape);
+ sal_Bool HasShapes() { return !aShapeList.empty(); }
+ const ScMyShapeList* GetShapes() const { return &aShapeList; }
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+struct ScMyNoteShape
+{
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape;
+ ScAddress aPos;
+
+ sal_Bool operator<(const ScMyNoteShape& aNote) const;
+};
+
+typedef std::list<ScMyNoteShape> ScMyNoteShapeList;
+
+class ScMyNoteShapesContainer : ScMyIteratorBase
+{
+private:
+ ScMyNoteShapeList aNoteShapeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyNoteShapesContainer();
+ virtual ~ScMyNoteShapesContainer();
+
+ using ScMyIteratorBase::UpdateAddress;
+ void AddNewNote(const ScMyNoteShape& aNote);
+ sal_Bool HasNotes() { return !aNoteShapeList.empty(); }
+ const ScMyNoteShapeList* GetNotes() const { return &aNoteShapeList; }
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyMergedRange
+{
+ com::sun::star::table::CellRangeAddress aCellRange;
+ sal_Int32 nRows;
+ sal_Bool bIsFirst;
+ sal_Bool operator<(const ScMyMergedRange& aRange) const;
+};
+
+typedef std::list<ScMyMergedRange> ScMyMergedRangeList;
+
+class ScMyMergedRangesContainer : ScMyIteratorBase
+{
+private:
+ ScMyMergedRangeList aRangeList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyMergedRangesContainer();
+ virtual ~ScMyMergedRangesContainer();
+ void AddRange(const com::sun::star::table::CellRangeAddress aMergedRange);
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort(); // + remove doublets
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyAreaLink
+{
+ ::rtl::OUString sFilter;
+ ::rtl::OUString sFilterOptions;
+ ::rtl::OUString sURL;
+ ::rtl::OUString sSourceStr;
+ ::com::sun::star::table::CellRangeAddress aDestRange;
+ sal_Int32 nRefresh;
+
+ inline ScMyAreaLink() : nRefresh( 0 ) {}
+
+ inline sal_Int32 GetColCount() const { return aDestRange.EndColumn - aDestRange.StartColumn + 1; }
+ inline sal_Int32 GetRowCount() const { return aDestRange.EndRow - aDestRange.StartRow + 1; }
+
+ sal_Bool Compare( const ScMyAreaLink& rAreaLink ) const;
+ sal_Bool operator<(const ScMyAreaLink& rAreaLink ) const;
+};
+
+typedef ::std::list< ScMyAreaLink > ScMyAreaLinkList;
+
+class ScMyAreaLinksContainer : ScMyIteratorBase
+{
+private:
+ ScMyAreaLinkList aAreaLinkList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyAreaLinksContainer();
+ virtual ~ScMyAreaLinksContainer();
+
+ inline void AddNewAreaLink( const ScMyAreaLink& rAreaLink )
+ { aAreaLinkList.push_back( rAreaLink ); }
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyCellRangeAddress : com::sun::star::table::CellRangeAddress
+{
+ ScMyCellRangeAddress(const com::sun::star::table::CellRangeAddress& rRange);
+ sal_Bool operator<(const ScMyCellRangeAddress& rCellRangeAddress ) const;
+};
+
+typedef std::list<ScMyCellRangeAddress> ScMyEmptyDatabaseRangeList;
+
+class ScMyEmptyDatabaseRangesContainer : ScMyIteratorBase
+{
+private:
+ ScMyEmptyDatabaseRangeList aDatabaseList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyEmptyDatabaseRangesContainer();
+ virtual ~ScMyEmptyDatabaseRangesContainer();
+ void AddNewEmptyDatabaseRange(const com::sun::star::table::CellRangeAddress& aCellRangeAddress);
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyDetectiveObj
+{
+ ::com::sun::star::table::CellAddress aPosition;
+ ::com::sun::star::table::CellRangeAddress aSourceRange;
+ ScDetectiveObjType eObjType;
+ sal_Bool bHasError;
+ sal_Bool operator<(const ScMyDetectiveObj& rDetObj) const;
+};
+
+typedef ::std::list< ScMyDetectiveObj > ScMyDetectiveObjList;
+typedef ::std::vector< ScMyDetectiveObj > ScMyDetectiveObjVec;
+
+class ScMyDetectiveObjContainer : ScMyIteratorBase
+{
+private:
+ ScMyDetectiveObjList aDetectiveObjList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyDetectiveObjContainer();
+ virtual ~ScMyDetectiveObjContainer();
+
+ void AddObject(
+ ScDetectiveObjType eObjType,
+ const SCTAB nSheet,
+ const ScAddress& rPosition,
+ const ScRange& rSourceRange,
+ sal_Bool bHasError );
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+struct ScMyDetectiveOp
+{
+ ::com::sun::star::table::CellAddress aPosition;
+ ScDetOpType eOpType;
+ sal_Int32 nIndex;
+ sal_Bool operator<(const ScMyDetectiveOp& rDetOp) const;
+};
+
+typedef ::std::list< ScMyDetectiveOp > ScMyDetectiveOpList;
+typedef ::std::vector< ScMyDetectiveOp > ScMyDetectiveOpVec;
+
+class ScMyDetectiveOpContainer : ScMyIteratorBase
+{
+private:
+ ScMyDetectiveOpList aDetectiveOpList;
+protected:
+ virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress );
+public:
+ ScMyDetectiveOpContainer();
+ virtual ~ScMyDetectiveOpContainer();
+
+ void AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex );
+
+ using ScMyIteratorBase::UpdateAddress;
+ virtual void SetCellData( ScMyCell& rMyCell );
+ virtual void Sort();
+ void SkipTable(SCTAB nSkip);
+};
+
+//==============================================================================
+
+// contains data to export for the current cell position
+struct ScMyCell
+{
+// com::sun::star::uno::Reference<com::sun::star::table::XCell> xCell;
+// com::sun::star::uno::Reference<com::sun::star::text::XText> xText;
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation;
+ com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xNoteShape;
+ com::sun::star::table::CellAddress aCellAddress;
+ com::sun::star::table::CellRangeAddress aMergeRange;
+ com::sun::star::table::CellRangeAddress aMatrixRange;
+
+ rtl::OUString sStringValue;
+ rtl::OUString sAnnotationText;
+
+ ScMyAreaLink aAreaLink;
+ ScMyShapeList aShapeList;
+ ScMyDetectiveObjVec aDetectiveObjVec;
+ ScMyDetectiveOpVec aDetectiveOpVec;
+
+ double fValue;
+ sal_Int32 nValidationIndex;
+ sal_Int32 nStyleIndex;
+ sal_Int32 nNumberFormat;
+ com::sun::star::table::CellContentType nType;
+
+ ScBaseCell* pBaseCell;
+
+ sal_Bool bIsAutoStyle;
+
+ sal_Bool bHasShape;
+ sal_Bool bIsMergedBase;
+ sal_Bool bIsCovered;
+ sal_Bool bHasAreaLink;
+ sal_Bool bHasEmptyDatabase;
+ sal_Bool bHasDetectiveObj;
+ sal_Bool bHasDetectiveOp;
+
+ sal_Bool bIsEditCell;
+ sal_Bool bKnowWhetherIsEditCell;
+ sal_Bool bHasStringValue;
+ sal_Bool bHasDoubleValue;
+ sal_Bool bHasXText;
+
+ sal_Bool bIsMatrixBase;
+ sal_Bool bIsMatrixCovered;
+ sal_Bool bHasAnnotation;
+
+ ScMyCell();
+ ~ScMyCell();
+};
+
+//==============================================================================
+
+struct ScMyExportAnnotation
+{
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation;
+ com::sun::star::table::CellAddress aCellAddress;
+ sal_Bool operator<(const ScMyExportAnnotation& rAnno) const;
+};
+
+typedef ::std::list< ScMyExportAnnotation > ScMyExportAnnotationList;
+
+class ScMyNotEmptyCellsIterator
+{
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet> xTable;
+ com::sun::star::uno::Reference<com::sun::star::table::XCellRange> xCellRange;
+ com::sun::star::table::CellAddress aLastAddress;
+ ScMyExportAnnotationList aAnnotations;
+
+ ScMyShapesContainer* pShapes;
+ ScMyNoteShapesContainer* pNoteShapes;
+ ScMyEmptyDatabaseRangesContainer* pEmptyDatabaseRanges;
+ ScMyMergedRangesContainer* pMergedRanges;
+ ScMyAreaLinksContainer* pAreaLinks;
+ ScMyDetectiveObjContainer* pDetectiveObj;
+ ScMyDetectiveOpContainer* pDetectiveOp;
+
+ ScXMLExport& rExport;
+ ScHorizontalCellIterator* pCellItr;
+
+ SCCOL nCellCol;
+ SCROW nCellRow;
+ SCTAB nCurrentTable;
+
+ void UpdateAddress( ::com::sun::star::table::CellAddress& rAddress );
+ void SetCellData( ScMyCell& rMyCell, ::com::sun::star::table::CellAddress& rAddress );
+
+ void SetMatrixCellData( ScMyCell& rMyCell );
+ void HasAnnotation( ScMyCell& aCell );
+public:
+ ScMyNotEmptyCellsIterator(ScXMLExport& rExport);
+ ~ScMyNotEmptyCellsIterator();
+
+ void Clear();
+
+ inline void SetShapes(ScMyShapesContainer* pNewShapes)
+ { pShapes = pNewShapes; }
+ inline void SetNoteShapes(ScMyNoteShapesContainer* pNewNoteShapes)
+ { pNoteShapes = pNewNoteShapes; }
+ inline void SetEmptyDatabaseRanges(ScMyEmptyDatabaseRangesContainer* pNewEmptyDatabaseRanges)
+ { pEmptyDatabaseRanges = pNewEmptyDatabaseRanges; }
+ inline void SetMergedRanges(ScMyMergedRangesContainer* pNewMergedRanges)
+ { pMergedRanges = pNewMergedRanges; }
+ inline void SetAreaLinks(ScMyAreaLinksContainer* pNewAreaLinks)
+ { pAreaLinks = pNewAreaLinks; }
+ inline void SetDetectiveObj(ScMyDetectiveObjContainer* pNewDetectiveObj)
+ { pDetectiveObj = pNewDetectiveObj; }
+ inline void SetDetectiveOp(ScMyDetectiveOpContainer* pNewDetectiveOp)
+ { pDetectiveOp = pNewDetectiveOp; }
+
+ void SetCurrentTable(const SCTAB nTable,
+ com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& rxTable);
+ void SkipTable(SCTAB nSkip);
+
+ sal_Bool GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportSharedData.cxx b/sc/source/filter/xml/XMLExportSharedData.cxx
new file mode 100644
index 000000000000..7849b64efe9c
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportSharedData.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportSharedData.hxx"
+#include "XMLExportIterator.hxx"
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+
+ScMySharedData::ScMySharedData(const sal_Int32 nTempTableCount) :
+ nLastColumns(nTempTableCount, 0),
+ nLastRows(nTempTableCount, 0),
+ pTableShapes(NULL),
+ pDrawPages(NULL),
+ pShapesContainer(NULL),
+ pDetectiveObjContainer(new ScMyDetectiveObjContainer()),
+ pNoteShapes(NULL),
+ nTableCount(nTempTableCount)
+{
+}
+
+ScMySharedData::~ScMySharedData()
+{
+ if (pShapesContainer)
+ delete pShapesContainer;
+ if (pTableShapes)
+ delete pTableShapes;
+ if (pDrawPages)
+ delete pDrawPages;
+ if (pDetectiveObjContainer)
+ delete pDetectiveObjContainer;
+ if (pNoteShapes)
+ delete pNoteShapes;
+}
+
+void ScMySharedData::SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol)
+{
+ if(nCol > nLastColumns[nTable]) nLastColumns[nTable] = nCol;
+}
+
+sal_Int32 ScMySharedData::GetLastColumn(const sal_Int32 nTable) const
+{
+ return nLastColumns[nTable];
+}
+
+void ScMySharedData::SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow)
+{
+ if(nRow > nLastRows[nTable]) nLastRows[nTable] = nRow;
+}
+
+sal_Int32 ScMySharedData::GetLastRow(const sal_Int32 nTable) const
+{
+ return nLastRows[nTable];
+}
+
+void ScMySharedData::AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable)
+{
+ if (!pDrawPages)
+ pDrawPages = new ScMyDrawPages(nTableCount, ScMyDrawPage());
+ (*pDrawPages)[nTable] = aDrawPage;
+}
+
+void ScMySharedData::SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms)
+{
+ DBG_ASSERT(pDrawPages, "DrawPages not collected");
+ if (pDrawPages)
+ (*pDrawPages)[nTable].bHasForms = bHasForms;
+}
+
+uno::Reference<drawing::XDrawPage> ScMySharedData::GetDrawPage(const sal_Int32 nTable)
+{
+ DBG_ASSERT(pDrawPages, "DrawPages not collected");
+ if (pDrawPages)
+ return (*pDrawPages)[nTable].xDrawPage;
+ else
+ return uno::Reference<drawing::XDrawPage>();
+}
+
+sal_Bool ScMySharedData::HasForm(const sal_Int32 nTable, uno::Reference<drawing::XDrawPage>& xDrawPage)
+{
+ sal_Bool bResult(false);
+ if (pDrawPages)
+ {
+ if ((*pDrawPages)[nTable].bHasForms)
+ {
+ bResult = sal_True;
+ xDrawPage = (*pDrawPages)[nTable].xDrawPage;
+ }
+ }
+ return bResult;
+}
+
+void ScMySharedData::AddNewShape(const ScMyShape& aMyShape)
+{
+ if (!pShapesContainer)
+ pShapesContainer = new ScMyShapesContainer();
+ pShapesContainer->AddNewShape(aMyShape);
+}
+
+void ScMySharedData::SortShapesContainer()
+{
+ if (pShapesContainer)
+ pShapesContainer->Sort();
+}
+
+sal_Bool ScMySharedData::HasShapes()
+{
+ return ((pShapesContainer && pShapesContainer->HasShapes()) ||
+ (pTableShapes && !pTableShapes->empty()));
+}
+
+void ScMySharedData::AddTableShape(const sal_Int32 nTable, const uno::Reference<drawing::XShape>& xShape)
+{
+ if (!pTableShapes)
+ pTableShapes = new ScMyTableShapes(nTableCount);
+ (*pTableShapes)[nTable].push_back(xShape);
+}
+
+void ScMySharedData::AddNoteObj(const uno::Reference<drawing::XShape>& xShape, const ScAddress& rPos)
+{
+ if (!pNoteShapes)
+ pNoteShapes = new ScMyNoteShapesContainer();
+ ScMyNoteShape aNote;
+ aNote.xShape = xShape;
+ aNote.aPos = rPos;
+ pNoteShapes->AddNewNote(aNote);
+}
+
+void ScMySharedData::SortNoteShapes()
+{
+ if (pNoteShapes)
+ pNoteShapes->Sort();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportSharedData.hxx b/sc/source/filter/xml/XMLExportSharedData.hxx
new file mode 100644
index 000000000000..3c131f5925fe
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportSharedData.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXPORTSHAREDDATA_HXX
+#define SC_XMLEXPORTSHAREDDATA_HXX
+
+#include "global.hxx"
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+#include <vector>
+#include <list>
+
+struct ScMyDrawPage
+{
+ com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> xDrawPage;
+ sal_Bool bHasForms;
+
+ ScMyDrawPage() : bHasForms(false) {}
+};
+
+typedef std::list< com::sun::star::uno::Reference<com::sun::star::drawing::XShape> > ScMyTableXShapes;
+typedef std::vector<ScMyTableXShapes> ScMyTableShapes;
+typedef std::vector<ScMyDrawPage> ScMyDrawPages;
+
+class ScMyShapesContainer;
+class ScMyDetectiveObjContainer;
+struct ScMyShape;
+class ScMyNoteShapesContainer;
+
+class ScMySharedData
+{
+ std::vector<sal_Int32> nLastColumns;
+ std::vector<sal_Int32> nLastRows;
+ ScMyTableShapes* pTableShapes;
+ ScMyDrawPages* pDrawPages;
+ ScMyShapesContainer* pShapesContainer;
+ ScMyDetectiveObjContainer* pDetectiveObjContainer;
+ ScMyNoteShapesContainer* pNoteShapes;
+ sal_Int32 nTableCount;
+public:
+ ScMySharedData(const sal_Int32 nTableCount);
+ ~ScMySharedData();
+
+ void SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol);
+ void SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow);
+ sal_Int32 GetLastColumn(const sal_Int32 nTable) const;
+ sal_Int32 GetLastRow(const sal_Int32 nTable) const;
+ void AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable);
+ void SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms);
+ com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> GetDrawPage(const sal_Int32 nTable);
+ sal_Bool HasDrawPage() const { return pDrawPages != NULL; }
+ sal_Bool HasForm(const sal_Int32 nTable, com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage>& xDrawPage);
+ void AddNewShape(const ScMyShape& aMyShape);
+ void SortShapesContainer();
+ ScMyShapesContainer* GetShapesContainer() { return pShapesContainer; }
+ sal_Bool HasShapes();
+ void AddTableShape(const sal_Int32 nTable, const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape);
+ ScMyTableShapes* GetTableShapes() { return pTableShapes; }
+ ScMyDetectiveObjContainer* GetDetectiveObjContainer() { return pDetectiveObjContainer; }
+ void AddNoteObj(const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape, const ScAddress& rPos);
+ void SortNoteShapes();
+ ScMyNoteShapesContainer* GetNoteShapes() { return pNoteShapes; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
new file mode 100644
index 000000000000..c3685941c736
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -0,0 +1,1280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLStylesExportHelper.hxx"
+#include "global.hxx"
+#include "unonames.hxx"
+#include "XMLConverter.hxx"
+#include "xmlexprt.hxx"
+#include "document.hxx"
+#include "rangeutl.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/XMLEventExport.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <comphelper/extract.hxx>
+#include <sfx2/app.hxx>
+
+#include <algorithm>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScMyValidation::ScMyValidation()
+ : sName(),
+ sErrorMessage(),
+ sErrorTitle(),
+ sImputMessage(),
+ sImputTitle(),
+ sFormula1(),
+ sFormula2(),
+ bShowErrorMessage(false),
+ bShowImputMessage(false),
+ bIgnoreBlanks(false)
+{
+}
+
+ScMyValidation::~ScMyValidation()
+{
+}
+
+sal_Bool ScMyValidation::IsEqual(const ScMyValidation& aVal) const
+{
+ if (aVal.bIgnoreBlanks == bIgnoreBlanks &&
+ aVal.bShowImputMessage == bShowImputMessage &&
+ aVal.bShowErrorMessage == bShowErrorMessage &&
+ aVal.aBaseCell.Sheet == aBaseCell.Sheet &&
+ aVal.aBaseCell.Column == aBaseCell.Column &&
+ aVal.aBaseCell.Row == aBaseCell.Row &&
+ aVal.aAlertStyle == aAlertStyle &&
+ aVal.aValidationType == aValidationType &&
+ aVal.aOperator == aOperator &&
+ aVal.sErrorTitle == sErrorTitle &&
+ aVal.sImputTitle == sImputTitle &&
+ aVal.sErrorMessage == sErrorMessage &&
+ aVal.sImputMessage == sImputMessage &&
+ aVal.sFormula1 == sFormula1 &&
+ aVal.sFormula2 == sFormula2)
+ return sal_True;
+ else
+ return false;
+}
+
+ScMyValidationsContainer::ScMyValidationsContainer()
+ : aValidationVec(),
+ sEmptyString(),
+ sERRALSTY(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)),
+ sIGNOREBL(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)),
+ sSHOWLIST(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)),
+ sTYPE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)),
+ sSHOWINP(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)),
+ sSHOWERR(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)),
+ sINPTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)),
+ sINPMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)),
+ sERRTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)),
+ sERRMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)),
+ sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError")),
+ sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
+ sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")),
+ sScript(RTL_CONSTASCII_USTRINGPARAM("Script")),
+ sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
+ sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName"))
+{
+}
+
+ScMyValidationsContainer::~ScMyValidationsContainer()
+{
+}
+
+sal_Bool ScMyValidationsContainer::AddValidation(const uno::Any& aTempAny,
+ sal_Int32& nValidationIndex)
+{
+ sal_Bool bAdded(false);
+ uno::Reference<beans::XPropertySet> xPropertySet(aTempAny, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ rtl::OUString sErrorMessage;
+ xPropertySet->getPropertyValue(sERRMESS) >>= sErrorMessage;
+ rtl::OUString sErrorTitle;
+ xPropertySet->getPropertyValue(sERRTITLE) >>= sErrorTitle;
+ rtl::OUString sImputMessage;
+ xPropertySet->getPropertyValue(sINPMESS) >>= sImputMessage;
+ rtl::OUString sImputTitle;
+ xPropertySet->getPropertyValue(sINPTITLE) >>= sImputTitle;
+ sal_Bool bShowErrorMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWERR));
+ sal_Bool bShowImputMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWINP));
+ sheet::ValidationType aValidationType;
+ xPropertySet->getPropertyValue(sTYPE) >>= aValidationType;
+ if (bShowErrorMessage || bShowImputMessage || aValidationType != sheet::ValidationType_ANY ||
+ sErrorMessage.getLength() || sErrorTitle.getLength() || sImputMessage.getLength() || sImputTitle.getLength())
+ {
+ ScMyValidation aValidation;
+ aValidation.sErrorMessage = sErrorMessage;
+ aValidation.sErrorTitle = sErrorTitle;
+ aValidation.sImputMessage = sImputMessage;
+ aValidation.sImputTitle = sImputTitle;
+ aValidation.bShowErrorMessage = bShowErrorMessage;
+ aValidation.bShowImputMessage = bShowImputMessage;
+ aValidation.aValidationType = aValidationType;
+ aValidation.bIgnoreBlanks = ::cppu::any2bool(xPropertySet->getPropertyValue(sIGNOREBL));
+ xPropertySet->getPropertyValue(sSHOWLIST) >>= aValidation.nShowList;
+ xPropertySet->getPropertyValue(sERRALSTY) >>= aValidation.aAlertStyle;
+ uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
+ if (xCondition.is())
+ {
+ aValidation.sFormula1 = xCondition->getFormula1();
+ aValidation.sFormula2 = xCondition->getFormula2();
+ aValidation.aOperator = xCondition->getOperator();
+ aValidation.aBaseCell = xCondition->getSourcePosition();
+ }
+ //ScMyValidationRange aValidationRange;
+ sal_Bool bEqualFound(false);
+ sal_Int32 i(0);
+ sal_Int32 nCount(aValidationVec.size());
+ while (i < nCount && !bEqualFound)
+ {
+ bEqualFound = aValidationVec[i].IsEqual(aValidation);
+ if (!bEqualFound)
+ ++i;
+ }
+ if (bEqualFound)
+ nValidationIndex = i;
+ else
+ {
+ sal_Int32 nNameIndex(nCount + 1);
+ rtl::OUString sCount(rtl::OUString::valueOf(nNameIndex));
+ rtl::OUString sPrefix(RTL_CONSTASCII_USTRINGPARAM("val"));
+ aValidation.sName += sPrefix;
+ aValidation.sName += sCount;
+ aValidationVec.push_back(aValidation);
+ nValidationIndex = nCount;
+ bAdded = sal_True;
+ }
+ }
+ }
+ return bAdded;
+}
+
+rtl::OUString ScMyValidationsContainer::GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation)
+{
+ /* ATTENTION! Should the condition to not write sheet::ValidationType_ANY
+ * ever be changed, adapt the conditional call of
+ * MarkUsedExternalReferences() in
+ * ScTableValidationObj::ScTableValidationObj() accordingly! */
+ rtl::OUString sCondition;
+ if (aValidation.aValidationType != sheet::ValidationType_ANY)
+ {
+ switch (aValidation.aValidationType)
+ {
+ //case sheet::ValidationType_CUSTOM
+ case sheet::ValidationType_DATE :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-date()"));
+ break;
+ case sheet::ValidationType_DECIMAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-decimal-number()"));
+ break;
+ case sheet::ValidationType_LIST :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-in-list("));
+ sCondition += aValidation.sFormula1;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ break;
+ case sheet::ValidationType_TEXT_LEN :
+ if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length()"));
+ break;
+ case sheet::ValidationType_TIME :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-time()"));
+ break;
+ case sheet::ValidationType_WHOLE :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-whole-number()"));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if (aValidation.aValidationType != sheet::ValidationType_LIST &&
+ (aValidation.sFormula1.getLength() ||
+ (aValidation.aOperator == sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator == sheet::ConditionOperator_NOT_BETWEEN &&
+ aValidation.sFormula2.getLength())))
+ {
+ if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" and "));
+ if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN &&
+ aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN)
+ {
+ if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()"));
+ switch (aValidation.aOperator)
+ {
+ case sheet::ConditionOperator_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ break;
+ case sheet::ConditionOperator_GREATER :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ break;
+ case sheet::ConditionOperator_LESS :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL :
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ sCondition += aValidation.sFormula1;
+ }
+ else
+ {
+ if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN)
+ {
+ if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-between("));
+ else
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-not-between("));
+ }
+ else
+ {
+ if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between("));
+ else
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between("));
+ }
+ sCondition += aValidation.sFormula1;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ sCondition += aValidation.sFormula2;
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+ }
+ else
+ if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN)
+ sCondition = rtl::OUString();
+ }
+ if (sCondition.getLength())
+ {
+ const formula::FormulaGrammar::Grammar eGrammar = rExport.GetDocument()->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ sCondition = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sCondition, false );
+ }
+
+ return sCondition;
+}
+
+rtl::OUString ScMyValidationsContainer::GetBaseCellAddress(ScDocument* pDoc, const table::CellAddress& aCell)
+{
+ rtl::OUString sAddress;
+ ScRangeStringConverter::GetStringFromAddress( sAddress, aCell, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ return sAddress;
+}
+
+void ScMyValidationsContainer::WriteMessage(ScXMLExport& rExport,
+ const rtl::OUString& sTitle, const rtl::OUString& sOUMessage,
+ const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage)
+{
+ if (sTitle.getLength())
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TITLE, sTitle);
+ if (bShowMessage)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ SvXMLElementExport* pMessage(NULL);
+ if (bIsHelpMessage)
+ pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, sal_True, sal_True);
+ else
+ pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, sal_True, sal_True);
+ if (sOUMessage.getLength())
+ {
+ sal_Int32 i(0);
+ rtl::OUStringBuffer sTemp;
+ String sMessage(sOUMessage);
+ rtl::OUString sText (sMessage.ConvertLineEnd(LINEEND_LF));
+ sal_Bool bPrevCharWasSpace(sal_True);
+ while(i < sText.getLength())
+ {
+ if ((sText[i] == '\n'))
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace);
+ }
+ else
+ sTemp.append(sText[i]);
+ ++i;
+ }
+ if (sTemp.getLength())
+ {
+ SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace);
+ }
+ }
+ if (pMessage)
+ delete pMessage;
+}
+
+void ScMyValidationsContainer::WriteValidations(ScXMLExport& rExport)
+{
+ if (aValidationVec.size())
+ {
+ SvXMLElementExport aElemVs(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, sal_True, sal_True);
+ ScMyValidationVec::iterator aItr(aValidationVec.begin());
+ ScMyValidationVec::iterator aEndItr(aValidationVec.end());
+ while (aItr != aEndItr)
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sName);
+ rtl::OUString sCondition(GetCondition(rExport, *aItr));
+ if (sCondition.getLength())
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION, sCondition);
+ if (aItr->bIgnoreBlanks)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_FALSE);
+ if (aItr->aValidationType == sheet::ValidationType_LIST)
+ {
+ switch (aItr->nShowList)
+ {
+ case sheet::TableValidationVisibility::INVISIBLE:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_NO);
+ break;
+ case sheet::TableValidationVisibility::UNSORTED:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_UNSORTED);
+ break;
+ case sheet::TableValidationVisibility::SORTEDASCENDING:
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_SORTED_ASCENDING);
+ break;
+ default:
+ OSL_FAIL("unknown ListType");
+ }
+ }
+ }
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, GetBaseCellAddress(rExport.GetDocument(), aItr->aBaseCell));
+ SvXMLElementExport aElemV(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, sal_True, sal_True);
+ if (aItr->bShowImputMessage || aItr->sImputMessage.getLength() || aItr->sImputTitle.getLength())
+ {
+ WriteMessage(rExport, aItr->sImputTitle, aItr->sImputMessage, aItr->bShowImputMessage, sal_True);
+ }
+ if (aItr->bShowErrorMessage || aItr->sErrorMessage.getLength() || aItr->sErrorTitle.getLength())
+ {
+ switch (aItr->aAlertStyle)
+ {
+ case sheet::ValidationAlertStyle_INFO :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_INFORMATION);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, false);
+ }
+ break;
+ case sheet::ValidationAlertStyle_WARNING :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_WARNING);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, false);
+ }
+ break;
+ case sheet::ValidationAlertStyle_STOP :
+ {
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_STOP);
+ WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, false);
+ }
+ break;
+ case sheet::ValidationAlertStyle_MACRO :
+ {
+ {
+ //rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sErrorTitle);
+ if (aItr->bShowErrorMessage)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TRUE);
+ else
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_FALSE);
+ SvXMLElementExport aEMElem(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MACRO, sal_True, sal_True);
+ }
+ {
+ // #i47525# for a script URL the type and the property name for the URL
+ // are both "Script", for a simple macro name the type is "StarBasic"
+ // and the property name is "MacroName".
+ bool bScriptURL = SfxApplication::IsXScriptURL( aItr->sErrorTitle );
+
+ uno::Sequence<beans::PropertyValue> aSeq(3);
+ beans::PropertyValue* pArr(aSeq.getArray());
+ pArr[0].Name = sEventType;
+ pArr[0].Value <<= bScriptURL ? sScript : sStarBasic;
+ pArr[1].Name = sLibrary;
+ pArr[1].Value <<= sEmptyString;
+ pArr[2].Name = bScriptURL ? sScript : sMacroName;
+ pArr[2].Value <<= aItr->sErrorTitle;
+
+ // 2) export the sequence
+ rExport.GetEventExport().ExportSingleEvent( aSeq, sOnError);
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ ++aItr;
+ }
+ }
+}
+
+const rtl::OUString& ScMyValidationsContainer::GetValidationName(const sal_Int32 nIndex)
+{
+ DBG_ASSERT( static_cast<size_t>(nIndex) < aValidationVec.size(), "out of range" );
+ return aValidationVec[nIndex].sName;
+}
+
+//==============================================================================
+
+sal_Int32 ScMyDefaultStyles::GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles,
+ const sal_Int32 nTable, const sal_Int32 nPos,
+ const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle)
+{
+ if (bRow)
+ return pCellStyles->GetStyleNameIndex(nTable, nPos, i,
+ bIsAutoStyle);
+ else
+ return pCellStyles->GetStyleNameIndex(nTable, i, nPos,
+ bIsAutoStyle);
+}
+
+void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc,
+ const sal_Bool bRow)
+{
+ if (pDoc)
+ {
+ SCTAB nTab = static_cast<SCTAB>(nTable);
+ sal_Int32 nPos;
+ sal_Int32 nLast;
+ ScMyDefaultStyleList* pDefaults;
+ if (bRow)
+ {
+ pDefaults = pRowDefaults;
+ nLast = nLastRow;
+ }
+ else
+ {
+ pDefaults = pColDefaults;
+ nLast = nLastCol;
+ }
+ sal_Bool bPrevAutoStyle(false);
+ sal_Bool bIsAutoStyle;
+ sal_Bool bResult;
+ sal_Int32 nPrevIndex(0);
+ sal_Int32 nIndex;
+ sal_Int32 nRepeat(0);
+ sal_Int32 nEmptyRepeat(0);
+ for (sal_Int32 i = nLast; i >= 0; --i)
+ {
+ if (bRow)
+ {
+ SCCOL nCol;
+ bResult = pDoc->GetRowDefault(nTab,
+ static_cast<SCROW>(i), static_cast<SCCOL>(nLastCol), nCol);
+ nPos = static_cast<sal_Int32>(nCol);
+ }
+ else
+ {
+ SCROW nRow;
+ bResult = pDoc->GetColDefault(nTab,
+ static_cast<SCCOL>(i), static_cast<SCROW>(nLastRow), nRow);
+ nPos = static_cast<sal_Int32>(nRow);
+ }
+ if (bResult)
+ {
+ nEmptyRepeat = 0;
+ if (!nRepeat)
+ {
+ nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bPrevAutoStyle);
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ nRepeat = 1;
+ }
+ else
+ {
+ nIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bIsAutoStyle);
+ if ((nIndex != nPrevIndex) || (bIsAutoStyle != bPrevAutoStyle))
+ {
+ nRepeat = 1;
+ nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i,
+ bRow, bPrevAutoStyle);
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ }
+ else
+ {
+ (*pDefaults)[i].nIndex = nPrevIndex;
+ (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle;
+ ++nRepeat;
+ if (nRepeat > 1)
+ (*pDefaults)[i].nRepeat = nRepeat;
+ }
+ }
+ }
+ else
+ {
+ nRepeat = 0;
+ if (!nEmptyRepeat)
+ nEmptyRepeat = 1;
+ else
+ {
+ ++nEmptyRepeat;
+ if (nEmptyRepeat > 1)
+ (*pDefaults)[i].nRepeat = nEmptyRepeat;
+ }
+ }
+ }
+ }
+}
+
+void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc)
+{
+ if (pRowDefaults)
+ delete pRowDefaults;
+ pRowDefaults = new ScMyDefaultStyleList(nLastRow + 1);
+ FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, sal_True);
+ if (pColDefaults)
+ delete pColDefaults;
+ pColDefaults = new ScMyDefaultStyleList(nLastCol + 1);
+ FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, false);
+}
+
+ScMyDefaultStyles::~ScMyDefaultStyles()
+{
+ if (pRowDefaults)
+ delete pRowDefaults;
+ if (pColDefaults)
+ delete pColDefaults;
+}
+
+ScMyRowFormatRange::ScMyRowFormatRange()
+ : nStartColumn(0),
+ nRepeatColumns(0),
+ nRepeatRows(0),
+ nIndex(-1),
+ nValidationIndex(-1),
+ bIsAutoStyle(sal_True)
+{
+}
+
+sal_Bool ScMyRowFormatRange::operator< (const ScMyRowFormatRange& rRange) const
+{
+ return (nStartColumn < rRange.nStartColumn);
+}
+
+ScRowFormatRanges::ScRowFormatRanges()
+ : aRowFormatRanges(),
+ pRowDefaults(NULL),
+ pColDefaults(NULL),
+ nSize(0)
+{
+}
+
+ScRowFormatRanges::ScRowFormatRanges(const ScRowFormatRanges* pRanges)
+ : aRowFormatRanges(pRanges->aRowFormatRanges),
+ pRowDefaults(pRanges->pRowDefaults),
+ pColDefaults(pRanges->pColDefaults),
+ nSize(pRanges->nSize)
+{
+}
+
+ScRowFormatRanges::~ScRowFormatRanges()
+{
+}
+
+void ScRowFormatRanges::Clear()
+{
+ aRowFormatRanges.clear();
+ nSize = 0;
+}
+
+void ScRowFormatRanges::AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex,
+ const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange)
+{
+ sal_Int32 nIndex(-1);
+ if ((nPrevIndex != rFormatRange.nIndex) ||
+ (bPrevAutoStyle != rFormatRange.bIsAutoStyle))
+ nIndex = rFormatRange.nIndex;
+
+ sal_Bool bInserted(false);
+ if (!aRowFormatRanges.empty())
+ {
+ ScMyRowFormatRange* pRange(&aRowFormatRanges.back());
+ if (pRange)
+ {
+ if ((nPrevStartCol == (pRange->nStartColumn + pRange->nRepeatColumns)) &&
+ (pRange->bIsAutoStyle == rFormatRange.bIsAutoStyle) &&
+ (pRange->nIndex == nIndex) &&
+ (pRange->nValidationIndex == rFormatRange.nValidationIndex))
+ {
+ if (rFormatRange.nRepeatRows < pRange->nRepeatRows)
+ pRange->nRepeatRows = rFormatRange.nRepeatRows;
+ pRange->nRepeatColumns += nRepeat;
+ bInserted = sal_True;
+ }
+ }
+ }
+ if (!bInserted)
+ {
+ ScMyRowFormatRange aRange;
+ aRange.nStartColumn = nPrevStartCol;
+ aRange.nRepeatColumns = nRepeat;
+ aRange.nRepeatRows = rFormatRange.nRepeatRows;
+ aRange.nValidationIndex = rFormatRange.nValidationIndex;
+ aRange.bIsAutoStyle = rFormatRange.bIsAutoStyle;
+ aRange.nIndex = nIndex;
+ aRowFormatRanges.push_back(aRange);
+ ++nSize;
+ }
+}
+
+void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
+ const sal_Int32 nRow)
+{
+ DBG_ASSERT(pRowDefaults, "no row defaults");
+ DBG_ASSERT(pColDefaults, "no column defaults");
+ sal_uInt32 nEnd (rFormatRange.nRepeatRows + nRow - 1);
+ sal_Int32 nPrevIndex((*pRowDefaults)[nRow].nIndex);
+ sal_Bool bPrevAutoStyle((*pRowDefaults)[nRow].bIsAutoStyle);
+ sal_uInt32 i(nRow + 1);
+ sal_Bool bReady(false);
+ while ((i < nEnd) && !bReady && (i < pRowDefaults->size()))
+ {
+ if ((nPrevIndex != (*pRowDefaults)[i].nIndex) ||
+ (bPrevAutoStyle != (*pRowDefaults)[i].bIsAutoStyle))
+ bReady = sal_True;
+ else
+ i += (*pRowDefaults)[i].nRepeat;
+ }
+ if (i > nEnd)
+ i = nEnd;
+ if (bReady)
+ rFormatRange.nRepeatRows = i - nRow + 1;
+ if (nPrevIndex == -1)
+ {
+ nPrevIndex = (*pColDefaults)[rFormatRange.nStartColumn].nIndex;
+ bPrevAutoStyle = (*pColDefaults)[rFormatRange.nStartColumn].bIsAutoStyle;
+ sal_uInt32 nPrevStartCol(rFormatRange.nStartColumn);
+ sal_uInt32 nRepeat((*pColDefaults)[rFormatRange.nStartColumn].nRepeat);
+ nEnd = rFormatRange.nStartColumn + rFormatRange.nRepeatColumns;
+ for(i = nPrevStartCol + nRepeat; i < nEnd; i += (*pColDefaults)[i].nRepeat)
+ {
+ DBG_ASSERT(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd, "something wents wrong");
+ if ((nPrevIndex != (*pColDefaults)[i].nIndex) ||
+ (bPrevAutoStyle != (*pColDefaults)[i].bIsAutoStyle))
+ {
+ AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
+ nPrevStartCol = i;
+ nRepeat = (*pColDefaults)[i].nRepeat;
+ nPrevIndex = (*pColDefaults)[i].nIndex;
+ bPrevAutoStyle = (*pColDefaults)[i].bIsAutoStyle;
+ }
+ else
+ nRepeat += (*pColDefaults)[i].nRepeat;
+ }
+ if (sal_uInt32(nPrevStartCol + nRepeat) > nEnd)
+ nRepeat = nEnd - nPrevStartCol;
+ AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
+ }
+ else if ((nPrevIndex == rFormatRange.nIndex) &&
+ (bPrevAutoStyle == rFormatRange.bIsAutoStyle))
+ {
+ rFormatRange.nIndex = -1;
+ aRowFormatRanges.push_back(rFormatRange);
+ ++nSize;
+ }
+}
+
+sal_Bool ScRowFormatRanges::GetNext(ScMyRowFormatRange& aFormatRange)
+{
+ ScMyRowFormatRangesList::iterator aItr(aRowFormatRanges.begin());
+ if (aItr != aRowFormatRanges.end())
+ {
+ aFormatRange = (*aItr);
+ aRowFormatRanges.erase(aItr);
+ --nSize;
+ return sal_True;
+ }
+ return false;
+}
+
+sal_Int32 ScRowFormatRanges::GetMaxRows() const
+{
+ ScMyRowFormatRangesList::const_iterator aItr(aRowFormatRanges.begin());
+ ScMyRowFormatRangesList::const_iterator aEndItr(aRowFormatRanges.end());
+ sal_Int32 nMaxRows = MAXROW + 1;
+ if (aItr != aEndItr)
+ {
+ while (aItr != aEndItr)
+ {
+ if ((*aItr).nRepeatRows < nMaxRows)
+ nMaxRows = (*aItr).nRepeatRows;
+ ++aItr;
+ }
+ }
+ else
+ {
+ OSL_FAIL("no ranges found");
+ }
+ return nMaxRows;
+}
+
+sal_Int32 ScRowFormatRanges::GetSize() const
+{
+ return nSize;
+}
+
+void ScRowFormatRanges::Sort()
+{
+ aRowFormatRanges.sort();
+}
+
+// ============================================================================
+ScMyFormatRange::ScMyFormatRange()
+ : nStyleNameIndex(-1),
+ nValidationIndex(-1),
+ bIsAutoStyle(sal_True)
+{
+}
+
+sal_Bool ScMyFormatRange::operator<(const ScMyFormatRange& rRange) const
+{
+ if (aRangeAddress.StartRow < rRange.aRangeAddress.StartRow)
+ return sal_True;
+ else
+ if (aRangeAddress.StartRow == rRange.aRangeAddress.StartRow)
+ return (aRangeAddress.StartColumn < rRange.aRangeAddress.StartColumn);
+ else
+ return false;
+}
+
+ScFormatRangeStyles::ScFormatRangeStyles()
+ : aTables(),
+ aStyleNames(),
+ aAutoStyleNames()
+{
+}
+
+ScFormatRangeStyles::~ScFormatRangeStyles()
+{
+ ScMyOUStringVec::iterator i(aStyleNames.begin());
+ ScMyOUStringVec::iterator endi(aStyleNames.end());
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+ i = aAutoStyleNames.begin();
+ endi = aAutoStyleNames.end();
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+ ScMyFormatRangeListVec::iterator j(aTables.begin());
+ ScMyFormatRangeListVec::iterator endj(aTables.end());
+ while (j != endj)
+ {
+ delete *j;
+ ++j;
+ }
+}
+
+void ScFormatRangeStyles::AddNewTable(const sal_Int32 nTable)
+{
+ sal_Int32 nSize = aTables.size() - 1;
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ ScMyFormatRangeAddresses* aRangeAddresses(new ScMyFormatRangeAddresses);
+ aTables.push_back(aRangeAddresses);
+ }
+}
+
+sal_Bool ScFormatRangeStyles::AddStyleName(rtl::OUString* rpString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle)
+{
+ if (bIsAutoStyle)
+ {
+ aAutoStyleNames.push_back(rpString);
+ rIndex = aAutoStyleNames.size() - 1;
+ return sal_True;
+ }
+ else
+ {
+ sal_Int32 nCount(aStyleNames.size());
+ sal_Bool bFound(false);
+ sal_Int32 i(nCount - 1);
+ while ((i >= 0) && (!bFound))
+ {
+ if (aStyleNames.at(i)->equals(*rpString))
+ bFound = sal_True;
+ else
+ i--;
+ }
+ if (bFound)
+ {
+ rIndex = i;
+ return false;
+ }
+ else
+ {
+ aStyleNames.push_back(rpString);
+ rIndex = aStyleNames.size() - 1;
+ return sal_True;
+ }
+ }
+}
+
+sal_Int32 ScFormatRangeStyles::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle)
+{
+ sal_Int32 nPrefixLength(rPrefix.getLength());
+ rtl::OUString sTemp(rString.copy(nPrefixLength));
+ sal_Int32 nIndex(sTemp.toInt32());
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aAutoStyleNames.size() && aAutoStyleNames.at(nIndex - 1)->equals(rString))
+ {
+ bIsAutoStyle = sal_True;
+ return nIndex - 1;
+ }
+ else
+ {
+ sal_Int32 i(0);
+ sal_Bool bFound(false);
+ while (!bFound && static_cast<size_t>(i) < aStyleNames.size())
+ {
+ if (aStyleNames[i]->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ {
+ bIsAutoStyle = false;
+ return i;
+ }
+ else
+ {
+ i = 0;
+ while (!bFound && static_cast<size_t>(i) < aAutoStyleNames.size())
+ {
+ if (aAutoStyleNames[i]->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ {
+ bIsAutoStyle = sal_True;
+ return i;
+ }
+ else
+ return -1;
+ }
+ }
+}
+
+sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable,
+ const sal_Int32 nColumn, const sal_Int32 nRow, sal_Bool& bIsAutoStyle) const
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr).aRangeAddress.StartColumn <= nColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nColumn) &&
+ ((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ bIsAutoStyle = aItr->bIsAutoStyle;
+ return (*aItr).nStyleNameIndex;
+ }
+ else
+ ++aItr;
+ }
+ return -1;
+}
+
+sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ while (aItr != aEndItr)
+ {
+ if (((*aItr).aRangeAddress.StartColumn <= nColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nColumn) &&
+ ((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ bIsAutoStyle = aItr->bIsAutoStyle;
+ nValidationIndex = aItr->nValidationIndex;
+ nNumberFormat = aItr->nNumberFormat;
+ if (((*pRowDefaults)[nRow].nIndex != -1))
+ {
+ if (((*pRowDefaults)[nRow].nIndex == (*aItr).nStyleNameIndex) &&
+ ((*pRowDefaults)[nRow].bIsAutoStyle == (*aItr).bIsAutoStyle))
+ return -1;
+ else
+ return (*aItr).nStyleNameIndex;
+ }
+ else if (((*pColDefaults)[nColumn].nIndex != -1) &&
+ ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
+ ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
+ return -1;
+ else
+ return (*aItr).nStyleNameIndex;
+ }
+ else
+ {
+ if ((*aItr).aRangeAddress.EndRow < nRemoveBeforeRow)
+ aItr = pFormatRanges->erase(aItr);
+ else
+ ++aItr;
+ }
+ }
+ return -1;
+}
+
+void ScFormatRangeStyles::GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow,
+ const sal_Int32 nTable, ScRowFormatRanges* pRowFormatRanges)
+{
+ sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1);
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
+ ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
+ ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
+ sal_Int32 nColumns = 0;
+ while (aItr != aEndItr && nColumns < nTotalColumns)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ table::CellRangeAddress aTempRangeAddress((*aItr).aRangeAddress);
+#endif
+ if (((*aItr).aRangeAddress.StartRow <= nRow) &&
+ ((*aItr).aRangeAddress.EndRow >= nRow))
+ {
+ if ((((*aItr).aRangeAddress.StartColumn <= nStartColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nStartColumn)) ||
+ (((*aItr).aRangeAddress.StartColumn <= nEndColumn) &&
+ ((*aItr).aRangeAddress.EndColumn >= nEndColumn)) ||
+ (((*aItr).aRangeAddress.StartColumn >= nStartColumn) &&
+ ((*aItr).aRangeAddress.EndColumn <= nEndColumn)))
+ {
+ ScMyRowFormatRange aRange;
+ aRange.nIndex = aItr->nStyleNameIndex;
+ aRange.nValidationIndex = aItr->nValidationIndex;
+ aRange.bIsAutoStyle = aItr->bIsAutoStyle;
+ if ((aItr->aRangeAddress.StartColumn < nStartColumn) &&
+ (aItr->aRangeAddress.EndColumn >= nStartColumn))
+ {
+ if (aItr->aRangeAddress.EndColumn >= nEndColumn)
+ aRange.nRepeatColumns = nTotalColumns;
+ else
+ aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - nStartColumn + 1;
+ aRange.nStartColumn = nStartColumn;
+ }
+ else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
+ (aItr->aRangeAddress.EndColumn <= nEndColumn))
+ {
+ aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - aItr->aRangeAddress.StartColumn + 1;
+ aRange.nStartColumn = aItr->aRangeAddress.StartColumn;
+ }
+ else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
+ (aItr->aRangeAddress.StartColumn <= nEndColumn) &&
+ (aItr->aRangeAddress.EndColumn > nEndColumn))
+ {
+ aRange.nRepeatColumns = nEndColumn - aItr->aRangeAddress.StartColumn + 1;
+ aRange.nStartColumn = aItr->aRangeAddress.StartColumn;
+ }
+ aRange.nRepeatRows = aItr->aRangeAddress.EndRow - nRow + 1;
+ pRowFormatRanges->AddRange(aRange, nRow);
+ nColumns += aRange.nRepeatColumns;
+ }
+ ++aItr;
+ }
+ else
+ if(aItr->aRangeAddress.EndRow < nRow)
+ aItr = pFormatRanges->erase(aItr);
+ else
+ ++aItr;
+ }
+ pRowFormatRanges->Sort();
+}
+
+void ScFormatRangeStyles::AddRangeStyleName(const table::CellRangeAddress aCellRangeAddress,
+ const sal_Int32 nStringIndex, const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex,
+ const sal_Int32 nNumberFormat)
+{
+ ScMyFormatRange aFormatRange;
+ aFormatRange.aRangeAddress = aCellRangeAddress;
+ aFormatRange.nStyleNameIndex = nStringIndex;
+ aFormatRange.nValidationIndex = nValidationIndex;
+ aFormatRange.nNumberFormat = nNumberFormat;
+ aFormatRange.bIsAutoStyle = bIsAutoStyle;
+ DBG_ASSERT(static_cast<size_t>(aCellRangeAddress.Sheet) < aTables.size(), "wrong table");
+ ScMyFormatRangeAddresses* pFormatRanges(aTables[aCellRangeAddress.Sheet]);
+ pFormatRanges->push_back(aFormatRange);
+}
+
+rtl::OUString* ScFormatRangeStyles::GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle)
+{
+ if (bIsAutoStyle)
+ return aAutoStyleNames[nIndex];
+ else
+ return aStyleNames[nIndex];
+}
+
+void ScFormatRangeStyles::Sort()
+{
+ sal_Int32 nTables = aTables.size();
+ for (sal_Int16 i = 0; i < nTables; ++i)
+ if (!aTables[i]->empty())
+ aTables[i]->sort();
+}
+
+//===========================================================================
+
+ScColumnRowStylesBase::ScColumnRowStylesBase()
+ : aStyleNames()
+{
+}
+
+ScColumnRowStylesBase::~ScColumnRowStylesBase()
+{
+ ScMyOUStringVec::iterator i(aStyleNames.begin());
+ ScMyOUStringVec::iterator endi(aStyleNames.end());
+ while (i != endi)
+ {
+ delete *i;
+ ++i;
+ }
+}
+
+sal_Int32 ScColumnRowStylesBase::AddStyleName(rtl::OUString* pString)
+{
+ aStyleNames.push_back(pString);
+ return aStyleNames.size() - 1;
+}
+
+sal_Int32 ScColumnRowStylesBase::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix)
+{
+ sal_Int32 nPrefixLength(rPrefix.getLength());
+ rtl::OUString sTemp(rString.copy(nPrefixLength));
+ sal_Int32 nIndex(sTemp.toInt32());
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aStyleNames.size() && aStyleNames.at(nIndex - 1)->equals(rString))
+ return nIndex - 1;
+ else
+ {
+ sal_Int32 i(0);
+ sal_Bool bFound(false);
+ while (!bFound && static_cast<size_t>(i) < aStyleNames.size())
+ {
+ if (aStyleNames.at(i)->equals(rString))
+ bFound = sal_True;
+ else
+ ++i;
+ }
+ if (bFound)
+ return i;
+ else
+ return -1;
+ }
+}
+
+rtl::OUString* ScColumnRowStylesBase::GetStyleNameByIndex(const sal_Int32 nIndex)
+{
+ if ( nIndex < 0 || nIndex >= sal::static_int_cast<sal_Int32>( aStyleNames.size() ) )
+ {
+ // should no longer happen, use first style then
+ DBG_ERRORFILE("GetStyleNameByIndex: invalid index");
+ return aStyleNames[0];
+ }
+
+ return aStyleNames[nIndex];
+}
+
+//===========================================================================
+
+ScColumnStyles::ScColumnStyles()
+ : ScColumnRowStylesBase(),
+ aTables()
+{
+}
+
+ScColumnStyles::~ScColumnStyles()
+{
+}
+
+void ScColumnStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields)
+{
+ sal_Int32 nSize(aTables.size() - 1);
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ ScMyColumnStyleVec aFieldsVec(nFields + 1, ScColumnStyle());
+ aTables.push_back(aFieldsVec);
+ }
+}
+
+sal_Int32 ScColumnStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField,
+ sal_Bool& bIsVisible)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ if (static_cast<size_t>(nField) < aTables[nTable].size())
+ {
+ bIsVisible = aTables[nTable][nField].bIsVisible;
+ return aTables[nTable][nField].nIndex;
+ }
+ else
+ {
+ bIsVisible = aTables[nTable][aTables[nTable].size() - 1].bIsVisible;
+ return aTables[nTable][aTables[nTable].size() - 1].nIndex;
+ }
+}
+
+void ScColumnStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField,
+ const sal_Int32 nStringIndex, const sal_Bool bIsVisible)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<sal_uInt32>(nField), "wrong field");
+ ScColumnStyle aStyle;
+ aStyle.nIndex = nStringIndex;
+ aStyle.bIsVisible = bIsVisible;
+ if (aTables[nTable].size() == static_cast<sal_uInt32>(nField))
+ aTables[nTable].push_back(aStyle);
+ aTables[nTable][nField] = aStyle;
+}
+
+rtl::OUString* ScColumnStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ sal_Bool bTemp;
+ return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField, bTemp));
+}
+
+//===========================================================================
+
+ScRowStyles::Cache::Cache() :
+ mnTable(-1), mnStart(-1), mnEnd(-1), mnStyle(-1) {}
+
+bool ScRowStyles::Cache::hasCache(sal_Int32 nTable, sal_Int32 nField) const
+{
+ return mnTable == nTable && mnStart <= nField && nField < mnEnd;
+}
+
+ScRowStyles::ScRowStyles()
+ : ScColumnRowStylesBase()
+{
+}
+
+ScRowStyles::~ScRowStyles()
+{
+}
+
+void ScRowStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields)
+{
+ sal_Int32 nSize(aTables.size() - 1);
+ if (nTable > nSize)
+ for (sal_Int32 i = nSize; i < nTable; ++i)
+ {
+ aTables.push_back(new StylesType(0, nFields+1, -1));
+ }
+}
+
+sal_Int32 ScRowStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ if (maCache.hasCache(nTable, nField))
+ // Cache hit !
+ return maCache.mnStyle;
+
+ StylesType& r = aTables[nTable];
+ if (!r.is_tree_valid())
+ r.build_tree();
+ sal_Int32 nStyle;
+ sal_Int32 nStart, nEnd;
+ if (r.search_tree(nField, nStyle, &nStart, &nEnd))
+ {
+ // Cache this value for better performance.
+ maCache.mnTable = nTable;
+ maCache.mnStart = nStart;
+ maCache.mnEnd = nEnd;
+ maCache.mnStyle = nStyle;
+ return nStyle;
+ }
+
+ return -1;
+}
+
+void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField,
+ const sal_Int32 nStringIndex)
+{
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ StylesType& r = aTables[nTable];
+ r.insert_back(nField, nField+1, nStringIndex);
+}
+
+void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField,
+ const sal_Int32 nStringIndex, const sal_Int32 nEndField)
+{
+ DBG_ASSERT( nStartField <= nEndField, "bad field range");
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ StylesType& r = aTables[nTable];
+ r.insert_back(nStartField, nEndField+1, nStringIndex);
+}
+
+rtl::OUString* ScRowStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField)
+{
+ return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.hxx b/sc/source/filter/xml/XMLStylesExportHelper.hxx
new file mode 100644
index 000000000000..e3baa64cb68c
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesExportHelper.hxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLESEXPORTHELPER_HXX
+#define SC_XMLSTYLESEXPORTHELPER_HXX
+
+#include <vector>
+#include <list>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <mdds/flat_segment_tree.hpp>
+
+class ScDocument;
+class ScXMLExport;
+
+struct ScMyValidation
+{
+ rtl::OUString sName;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sImputMessage;
+ rtl::OUString sImputTitle;
+ rtl::OUString sFormula1;
+ rtl::OUString sFormula2;
+ com::sun::star::table::CellAddress aBaseCell;
+ com::sun::star::sheet::ValidationAlertStyle aAlertStyle;
+ com::sun::star::sheet::ValidationType aValidationType;
+ com::sun::star::sheet::ConditionOperator aOperator;
+ sal_Int16 nShowList;
+ sal_Bool bShowErrorMessage;
+ sal_Bool bShowImputMessage;
+ sal_Bool bIgnoreBlanks;
+
+ ScMyValidation();
+ ~ScMyValidation();
+
+ sal_Bool IsEqual(const ScMyValidation& aVal) const;
+};
+
+typedef std::vector<ScMyValidation> ScMyValidationVec;
+
+class ScMyValidationsContainer
+{
+private:
+ ScMyValidationVec aValidationVec;
+ const rtl::OUString sEmptyString;
+ const rtl::OUString sERRALSTY;
+ const rtl::OUString sIGNOREBL;
+ const rtl::OUString sSHOWLIST;
+ const rtl::OUString sTYPE;
+ const rtl::OUString sSHOWINP;
+ const rtl::OUString sSHOWERR;
+ const rtl::OUString sINPTITLE;
+ const rtl::OUString sINPMESS;
+ const rtl::OUString sERRTITLE;
+ const rtl::OUString sERRMESS;
+ const rtl::OUString sOnError;
+ const rtl::OUString sEventType;
+ const rtl::OUString sStarBasic;
+ const rtl::OUString sScript;
+ const rtl::OUString sLibrary;
+ const rtl::OUString sMacroName;
+
+public:
+ ScMyValidationsContainer();
+ ~ScMyValidationsContainer();
+ sal_Bool AddValidation(const com::sun::star::uno::Any& aAny,
+ sal_Int32& nValidationIndex);
+ rtl::OUString GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation);
+ rtl::OUString GetBaseCellAddress(ScDocument* pDoc, const com::sun::star::table::CellAddress& aCell);
+ void WriteMessage(ScXMLExport& rExport,
+ const rtl::OUString& sTitle, const rtl::OUString& sMessage,
+ const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage);
+ void WriteValidations(ScXMLExport& rExport);
+ const rtl::OUString& GetValidationName(const sal_Int32 nIndex);
+};
+
+//==============================================================================
+
+struct ScMyDefaultStyle
+{
+ sal_Int32 nIndex;
+ sal_Int32 nRepeat;
+ sal_Bool bIsAutoStyle;
+
+ ScMyDefaultStyle() : nIndex(-1), nRepeat(1),
+ bIsAutoStyle(sal_True) {}
+};
+
+typedef std::vector<ScMyDefaultStyle> ScMyDefaultStyleList;
+
+class ScFormatRangeStyles;
+
+class ScMyDefaultStyles
+{
+ ScMyDefaultStyleList* pRowDefaults;
+ ScMyDefaultStyleList* pColDefaults;
+
+ sal_Int32 GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles,
+ const sal_Int32 nTable, const sal_Int32 nPos,
+ const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle);
+ void FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc,
+ const sal_Bool bRow);
+public:
+ ScMyDefaultStyles() : pRowDefaults(NULL), pColDefaults(NULL) {}
+ ~ScMyDefaultStyles();
+
+ void FillDefaultStyles(const sal_Int32 nTable,
+ const sal_Int32 nLastRow, const sal_Int32 nLastCol,
+ const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc);
+
+ const ScMyDefaultStyleList* GetRowDefaults() const { return pRowDefaults; }
+ const ScMyDefaultStyleList* GetColDefaults() const { return pColDefaults; }
+};
+
+struct ScMyRowFormatRange
+{
+ sal_Int32 nStartColumn;
+ sal_Int32 nRepeatColumns;
+ sal_Int32 nRepeatRows;
+ sal_Int32 nIndex;
+ sal_Int32 nValidationIndex;
+ sal_Bool bIsAutoStyle;
+
+ ScMyRowFormatRange();
+ sal_Bool operator<(const ScMyRowFormatRange& rRange) const;
+};
+
+class ScRowFormatRanges
+{
+ typedef std::list<ScMyRowFormatRange> ScMyRowFormatRangesList;
+ ScMyRowFormatRangesList aRowFormatRanges;
+ const ScMyDefaultStyleList* pRowDefaults;
+ const ScMyDefaultStyleList* pColDefaults;
+ sal_uInt32 nSize;
+
+ void AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex,
+ const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange);
+
+public:
+ ScRowFormatRanges();
+ ScRowFormatRanges(const ScRowFormatRanges* pRanges);
+ ~ScRowFormatRanges();
+
+ void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; }
+ void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; }
+ void Clear();
+ void AddRange(ScMyRowFormatRange& rFormatRange, const sal_Int32 nStartRow);
+ sal_Bool GetNext(ScMyRowFormatRange& rFormatRange);
+ sal_Int32 GetMaxRows() const;
+ sal_Int32 GetSize() const;
+ void Sort();
+};
+
+typedef std::vector<rtl::OUString*> ScMyOUStringVec;
+
+struct ScMyFormatRange
+{
+ com::sun::star::table::CellRangeAddress aRangeAddress;
+ sal_Int32 nStyleNameIndex;
+ sal_Int32 nValidationIndex;
+ sal_Int32 nNumberFormat;
+ sal_Bool bIsAutoStyle;
+
+ ScMyFormatRange();
+ sal_Bool operator< (const ScMyFormatRange& rRange) const;
+};
+
+class ScFormatRangeStyles
+{
+ typedef std::list<ScMyFormatRange> ScMyFormatRangeAddresses;
+ typedef std::vector<ScMyFormatRangeAddresses*> ScMyFormatRangeListVec;
+
+ ScMyFormatRangeListVec aTables;
+ ScMyOUStringVec aStyleNames;
+ ScMyOUStringVec aAutoStyleNames;
+ const ScMyDefaultStyleList* pRowDefaults;
+ const ScMyDefaultStyleList* pColDefaults;
+
+public:
+ ScFormatRangeStyles();
+ ~ScFormatRangeStyles();
+
+ void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; }
+ void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; }
+ void AddNewTable(const sal_Int32 nTable);
+ sal_Bool AddStyleName(rtl::OUString* pString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle = sal_True);
+ sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle);
+ // does not delete ranges
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle) const;
+ // deletes not necessary ranges if wanted
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow,
+ sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow);
+ void GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow,
+ const sal_Int32 nTable, ScRowFormatRanges* pFormatRanges);
+ void AddRangeStyleName(const com::sun::star::table::CellRangeAddress aCellRangeAddress, const sal_Int32 nStringIndex,
+ const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex, const sal_Int32 nNumberFormat);
+ rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle);
+ void Sort();
+};
+
+class ScColumnRowStylesBase
+{
+ ScMyOUStringVec aStyleNames;
+
+public:
+ ScColumnRowStylesBase();
+ virtual ~ScColumnRowStylesBase();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) = 0;
+ sal_Int32 AddStyleName(rtl::OUString* pString);
+ sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField) = 0;
+ rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex);
+};
+
+struct ScColumnStyle
+{
+ sal_Int32 nIndex;
+ sal_Bool bIsVisible;
+
+ ScColumnStyle() : nIndex(-1), bIsVisible(sal_True) {}
+};
+
+class ScColumnStyles : public ScColumnRowStylesBase
+{
+ typedef std::vector<ScColumnStyle> ScMyColumnStyleVec;
+ typedef std::vector<ScMyColumnStyleVec> ScMyColumnVectorVec;
+ ScMyColumnVectorVec aTables;
+
+public:
+ ScColumnStyles();
+ ~ScColumnStyles();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields);
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField,
+ sal_Bool& bIsVisible);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex, const sal_Bool bIsVisible);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField);
+};
+
+class ScRowStyles : public ScColumnRowStylesBase
+{
+ typedef ::mdds::flat_segment_tree<sal_Int32, sal_Int32> StylesType;
+ ::boost::ptr_vector<StylesType> aTables;
+ struct Cache
+ {
+ sal_Int32 mnTable;
+ sal_Int32 mnStart;
+ sal_Int32 mnEnd;
+ sal_Int32 mnStyle;
+ Cache();
+
+ bool hasCache(sal_Int32 nTable, sal_Int32 nField) const;
+ };
+ Cache maCache;
+
+public:
+ ScRowStyles();
+ ~ScRowStyles();
+
+ virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields);
+ sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField, const sal_Int32 nStringIndex, const sal_Int32 nEndField);
+ virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.cxx b/sc/source/filter/xml/XMLStylesImportHelper.cxx
new file mode 100644
index 000000000000..1087a6840e8d
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesImportHelper.cxx
@@ -0,0 +1,577 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLStylesImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+using namespace com::sun::star;
+using ::std::list;
+
+void ScMyStyleNumberFormats::AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat)
+{
+ aSet.insert(ScMyStyleNumberFormat(rStyleName, nNumberFormat));
+}
+
+sal_Int32 ScMyStyleNumberFormats::GetStyleNumberFormat(const rtl::OUString& rStyleName)
+{
+ ScMyStyleNumberFormat aStyleNumberFormat(rStyleName);
+ ScMyStyleNumberFormatSet::iterator aItr(aSet.find(aStyleNumberFormat));
+ if (aItr == aSet.end())
+ return -1;
+ else
+ return aItr->nNumberFormat;
+}
+
+ScMyStyleRanges::ScMyStyleRanges() :
+ pCurrencyList(NULL)
+{
+}
+
+ScMyStyleRanges::~ScMyStyleRanges()
+{
+ delete pCurrencyList;
+}
+
+void ScMyStyleRanges::AddRange(const ScRange& rRange,
+ const rtl::OUString* /*pStyleName*/, const sal_Int16 nType,
+ ScXMLImport& /*rImport*/, const sal_uInt32 /*nMaxRanges*/)
+{
+ switch (nType)
+ {
+ case util::NumberFormat::NUMBER:
+ {
+ if (!mpNumberList)
+ mpNumberList.reset(new ScSimpleRangeList);
+ mpNumberList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::TEXT:
+ {
+ if (!mpTextList)
+ mpTextList.reset(new ScSimpleRangeList);
+ mpTextList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::TIME:
+ {
+ if (!mpTimeList)
+ mpTimeList.reset(new ScSimpleRangeList);
+ mpTimeList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::DATETIME:
+ {
+ if (!mpDateTimeList)
+ mpDateTimeList.reset(new ScSimpleRangeList);
+ mpDateTimeList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::PERCENT:
+ {
+ if (!mpPercentList)
+ mpPercentList.reset(new ScSimpleRangeList);
+ mpPercentList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::LOGICAL:
+ {
+ if (!mpLogicalList)
+ mpLogicalList.reset(new ScSimpleRangeList);
+ mpLogicalList->addRange(rRange);
+ }
+ break;
+ case util::NumberFormat::UNDEFINED:
+ {
+ if (!mpUndefinedList)
+ mpUndefinedList.reset(new ScSimpleRangeList);
+ mpUndefinedList->addRange(rRange);
+ }
+ break;
+ default:
+ {
+ OSL_FAIL("wrong type");
+ }
+ break;
+ }
+}
+
+void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange,
+ const rtl::OUString* /*pStyleName*/, const rtl::OUString* pCurrency,
+ ScXMLImport& /*rImport*/, const sal_uInt32 /*nMaxRanges*/)
+{
+ if (!pCurrencyList)
+ pCurrencyList = new ScMyCurrencyStylesSet();
+ ScMyCurrencyStyle aStyle;
+ if (pCurrency)
+ aStyle.sCurrency = *pCurrency;
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->find(aStyle));
+ if (aItr == pCurrencyList->end())
+ {
+ std::pair<ScMyCurrencyStylesSet::iterator, bool> aPair(pCurrencyList->insert(aStyle));
+ if (aPair.second)
+ {
+ aItr = aPair.first;
+ aItr->mpRanges->addRange(rRange);
+ }
+ }
+ else
+ aItr->mpRanges->addRange(rRange);
+}
+
+void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* /*pDoc*/)
+{
+ if (mpTextList)
+ mpTextList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpNumberList)
+ mpNumberList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpTimeList)
+ mpTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpDateTimeList)
+ mpDateTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpPercentList)
+ mpPercentList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpLogicalList)
+ mpLogicalList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ if (mpUndefinedList)
+ mpUndefinedList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+
+ if (pCurrencyList)
+ {
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+ ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+ while (aItr != aEndItr)
+ {
+ aItr->mpRanges->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+ ++aItr;
+ }
+ }
+}
+
+void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* /*pDoc*/)
+{
+ if (mpTextList)
+ mpTextList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpNumberList)
+ mpNumberList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpTimeList)
+ mpTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpDateTimeList)
+ mpDateTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpPercentList)
+ mpPercentList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpLogicalList)
+ mpLogicalList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ if (mpUndefinedList)
+ mpUndefinedList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+
+ if (pCurrencyList)
+ {
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+ ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+ while (aItr != aEndItr)
+ {
+ aItr->mpRanges->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+ ++aItr;
+ }
+ }
+}
+
+void ScMyStyleRanges::SetStylesToRanges(const list<ScRange>& rRanges,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport)
+{
+ list<ScRange>::const_iterator itr = rRanges.begin(), itrEnd = rRanges.end();
+ for (; itr != itrEnd; ++itr)
+ rImport.SetStyleToRange(*itr, pStyleName, nCellType, pCurrency);
+}
+
+void ScMyStyleRanges::SetStylesToRanges(ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport)
+{
+ for ( size_t i = 0, nCount = pList->size(); i < nCount; ++i)
+ rImport.SetStyleToRange( *(*pList)[i], pStyleName, nCellType, pCurrency );
+}
+
+void ScMyStyleRanges::SetStylesToRanges(ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport)
+{
+ for (size_t i = 0, nCount = xList->size(); i < nCount; ++i)
+ rImport.SetStyleToRange( *(*xList)[i], pStyleName, nCellType, pCurrency );
+}
+
+void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport)
+{
+ if (mpNumberList)
+ {
+ list<ScRange> aList;
+ mpNumberList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
+ mpNumberList->clear();
+ }
+ if (mpTextList)
+ {
+ list<ScRange> aList;
+ mpTextList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
+ mpTextList->clear();
+ }
+ if (mpTimeList)
+ {
+ list<ScRange> aList;
+ mpTimeList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
+ mpTimeList->clear();
+ }
+ if (mpDateTimeList)
+ {
+ list<ScRange> aList;
+ mpDateTimeList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
+ mpDateTimeList->clear();
+ }
+ if (mpPercentList)
+ {
+ list<ScRange> aList;
+ mpPercentList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
+ mpPercentList->clear();
+ }
+ if (mpLogicalList)
+ {
+ list<ScRange> aList;
+ mpLogicalList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
+ mpLogicalList->clear();
+ }
+ if (mpUndefinedList)
+ {
+ list<ScRange> aList;
+ mpUndefinedList->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
+ mpUndefinedList->clear();
+ }
+ if (pCurrencyList)
+ {
+ ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+ ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+ while (aItr != aEndItr)
+ {
+ list<ScRange> aList;
+ aItr->mpRanges->getRangeList(aList);
+ SetStylesToRanges(aList, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
+ ++aItr;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+ScMyStylesImportHelper::ScMyStylesImportHelper(ScXMLImport& rTempImport)
+ :
+ aRowDefaultStyle(aCellStyles.end()),
+ rImport(rTempImport),
+ pStyleName(NULL),
+ pPrevStyleName(NULL),
+ pCurrency(NULL),
+ pPrevCurrency(NULL),
+ nMaxRanges(0),
+ bPrevRangeAdded(sal_True)
+{
+}
+
+ScMyStylesImportHelper::~ScMyStylesImportHelper()
+{
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ if (pPrevCurrency)
+ delete pPrevCurrency;
+ if (pStyleName)
+ delete pStyleName;
+ if (pCurrency)
+ delete pCurrency;
+}
+
+void ScMyStylesImportHelper::ResetAttributes()
+{
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ if (pPrevCurrency)
+ delete pPrevCurrency;
+ pPrevStyleName = pStyleName;
+ pPrevCurrency = pCurrency;
+ nPrevCellType = nCellType;
+ pStyleName = NULL;
+ pCurrency = NULL;
+ nCellType = 0;
+}
+
+ScMyStylesSet::iterator ScMyStylesImportHelper::GetIterator(const rtl::OUString* pStyleNameP)
+{
+ ScMyStyle aStyle;
+ if (pStyleNameP)
+ aStyle.sStyleName = *pStyleNameP;
+ else
+ {
+ OSL_FAIL("here is no stylename given");
+ }
+ ScMyStylesSet::iterator aItr(aCellStyles.find(aStyle));
+ if (aItr == aCellStyles.end())
+ {
+ std::pair<ScMyStylesSet::iterator, bool> aPair(aCellStyles.insert(aStyle));
+ if (aPair.second)
+ aItr = aPair.first;
+ else
+ {
+ OSL_FAIL("not possible to insert style");
+ return aCellStyles.end();
+ }
+ }
+ return aItr;
+}
+
+void ScMyStylesImportHelper::AddDefaultRange(const ScRange& rRange)
+{
+ DBG_ASSERT(aRowDefaultStyle != aCellStyles.end(), "no row default style");
+ if (!aRowDefaultStyle->sStyleName.getLength())
+ {
+ SCCOL nStartCol(rRange.aStart.Col());
+ SCCOL nEndCol(rRange.aEnd.Col());
+ if (aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nStartCol))
+ {
+ ScMyStylesSet::iterator aPrevItr(aColDefaultStyles[nStartCol]);
+ DBG_ASSERT(aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nEndCol), "to much columns");
+ for (SCCOL i = nStartCol + 1; (i <= nEndCol) && (i < sal::static_int_cast<SCCOL>(aColDefaultStyles.size())); ++i)
+ {
+ if (aPrevItr != aColDefaultStyles[i])
+ {
+ DBG_ASSERT(aPrevItr != aCellStyles.end(), "no column default style");
+ ScRange aRange(rRange);
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aEnd.SetCol(i - 1);
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName);
+ AddSingleRange(aRange);
+ nStartCol = i;
+ aPrevItr = aColDefaultStyles[i];
+ }
+ }
+ if (aPrevItr != aCellStyles.end())
+ {
+ ScRange aRange(rRange);
+ aRange.aStart.SetCol(nStartCol);
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName);
+ AddSingleRange(aRange);
+ }
+ else
+ {
+ DBG_ERRORFILE("no column default style");
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("to much columns");
+ }
+ }
+ else
+ {
+ if (pPrevStyleName)
+ delete pPrevStyleName;
+ pPrevStyleName = new rtl::OUString(aRowDefaultStyle->sStyleName);
+ AddSingleRange(rRange);
+ }
+}
+
+void ScMyStylesImportHelper::AddSingleRange(const ScRange& rRange)
+{
+ if (nMaxRanges == 0)
+ nMaxRanges = aColDefaultStyles.size();
+ ScMyStylesSet::iterator aItr(GetIterator(pPrevStyleName));
+ if (aItr != aCellStyles.end())
+ {
+ if (nPrevCellType != util::NumberFormat::CURRENCY)
+ aItr->xRanges->AddRange(rRange, pPrevStyleName, nPrevCellType,
+ rImport, nMaxRanges);
+ else
+ aItr->xRanges->AddCurrencyRange(rRange, pPrevStyleName, pPrevCurrency,
+ rImport, nMaxRanges);
+ }
+}
+
+void ScMyStylesImportHelper::AddRange()
+{
+ if (pPrevStyleName && pPrevStyleName->getLength())
+ AddSingleRange(aPrevRange);
+ else
+ AddDefaultRange(aPrevRange);
+ ResetAttributes();
+}
+
+void ScMyStylesImportHelper::AddColumnStyle(const rtl::OUString& sStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat)
+{
+ (void)nColumn; // avoid warning in product version
+ DBG_ASSERT(static_cast<sal_uInt32>(nColumn) == aColDefaultStyles.size(), "some columns are absent");
+ ScMyStylesSet::iterator aItr(GetIterator(&sStyleName));
+ DBG_ASSERT(aItr != aCellStyles.end(), "no column default style");
+ aColDefaultStyles.reserve(aColDefaultStyles.size() + nRepeat);
+ for (sal_Int32 i = 0; i < nRepeat; ++i)
+ aColDefaultStyles.push_back(aItr);
+}
+
+void ScMyStylesImportHelper::SetRowStyle(const rtl::OUString& sStyleName)
+{
+ aRowDefaultStyle = GetIterator(&sStyleName);
+}
+
+void ScMyStylesImportHelper::SetAttributes(rtl::OUString* pStyleNameP,
+ rtl::OUString* pCurrencyP, const sal_Int16 nCellTypeP)
+{
+ if (this->pStyleName)
+ delete this->pStyleName;
+ if (this->pCurrency)
+ delete this->pCurrency;
+ this->pStyleName = pStyleNameP;
+ this->pCurrency = pCurrencyP;
+ this->nCellType = nCellTypeP;
+}
+
+void ScMyStylesImportHelper::AddRange(const ScRange& rRange)
+{
+ if (!bPrevRangeAdded)
+ {
+ sal_Bool bAddRange(false);
+ if (nCellType == nPrevCellType &&
+ IsEqual(pStyleName, pPrevStyleName) &&
+ IsEqual(pCurrency, pPrevCurrency))
+ {
+ if (rRange.aStart.Row() == aPrevRange.aStart.Row())
+ {
+ if (rRange.aEnd.Row() == aPrevRange.aEnd.Row())
+ {
+ DBG_ASSERT(aPrevRange.aEnd.Col() + 1 == rRange.aStart.Col(), "something wents wrong");
+ aPrevRange.aEnd.SetCol(rRange.aEnd.Col());
+ }
+ else
+ bAddRange = sal_True;
+ }
+ else
+ {
+ if (rRange.aStart.Col() == aPrevRange.aStart.Col() &&
+ rRange.aEnd.Col() == aPrevRange.aEnd.Col())
+ {
+ DBG_ASSERT(aPrevRange.aEnd.Row() + 1 == rRange.aStart.Row(), "something wents wrong");
+ aPrevRange.aEnd.SetRow(rRange.aEnd.Row());
+ }
+ else
+ bAddRange = sal_True;
+ }
+ }
+ else
+ bAddRange = sal_True;
+ if (bAddRange)
+ {
+ AddRange();
+ aPrevRange = rRange;
+ }
+ }
+ else
+ {
+ aPrevRange = rRange;
+ ResetAttributes();
+ bPrevRangeAdded = false;
+ }
+}
+
+void ScMyStylesImportHelper::AddCell(const com::sun::star::table::CellAddress& rAddress)
+{
+ ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
+ ScRange aScRange( aScAddress, aScAddress );
+ AddRange(aScRange);
+}
+
+void ScMyStylesImportHelper::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ ScXMLImport::MutexGuard aGuard(rImport);
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->InsertRow(nRow, nTab, pDoc);
+ ++aItr;
+ }
+}
+
+void ScMyStylesImportHelper::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
+{
+ ScXMLImport::MutexGuard aGuard(rImport);
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->InsertCol(nCol, nTab, pDoc);
+ ++aItr;
+ }
+}
+
+void ScMyStylesImportHelper::EndTable()
+{
+ if (!bPrevRangeAdded)
+ {
+ AddRange();
+ bPrevRangeAdded = sal_True;
+ }
+ nMaxRanges = 0;
+}
+
+void ScMyStylesImportHelper::SetStylesToRanges()
+{
+ ScMyStylesSet::iterator aItr(aCellStyles.begin());
+ ScMyStylesSet::iterator aEndItr(aCellStyles.end());
+ while (aItr != aEndItr)
+ {
+ aItr->xRanges->SetStylesToRanges(&aItr->sStyleName, rImport);
+ ++aItr;
+ }
+ aColDefaultStyles.clear();
+ aCellStyles.clear();
+ nMaxRanges = 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.hxx b/sc/source/filter/xml/XMLStylesImportHelper.hxx
new file mode 100644
index 000000000000..b7f3e18906aa
--- /dev/null
+++ b/sc/source/filter/xml/XMLStylesImportHelper.hxx
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLESIMPORTHELPER_HXX
+#define SC_XMLSTYLESIMPORTHELPER_HXX
+
+#include "rangelst.hxx"
+#include "simplerangelist.hxx"
+#include <rtl/ustring.hxx>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <set>
+#include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+class ScXMLImport;
+
+struct ScMyStyleNumberFormat
+{
+ rtl::OUString sStyleName;
+ sal_Int32 nNumberFormat;
+
+ ScMyStyleNumberFormat() : nNumberFormat(-1) {}
+ ScMyStyleNumberFormat(const rtl::OUString& rStyleName) :
+ sStyleName(rStyleName), nNumberFormat(-1) {}
+ ScMyStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nFormat) :
+ sStyleName(rStyleName), nNumberFormat(nFormat) {}
+};
+
+struct LessStyleNumberFormat
+{
+ sal_Bool operator() (const ScMyStyleNumberFormat& rValue1, const ScMyStyleNumberFormat& rValue2) const
+ {
+ return rValue1.sStyleName < rValue2.sStyleName;
+ }
+};
+
+typedef std::set< ScMyStyleNumberFormat, LessStyleNumberFormat > ScMyStyleNumberFormatSet;
+
+class ScMyStyleNumberFormats
+{
+ ScMyStyleNumberFormatSet aSet;
+
+public:
+ void AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat);
+ sal_Int32 GetStyleNumberFormat(const rtl::OUString& rStyleName);
+};
+
+struct ScMyCurrencyStyle
+{
+ rtl::OUString sCurrency;
+ ::boost::shared_ptr<ScSimpleRangeList> mpRanges;
+
+ ScMyCurrencyStyle() :
+ mpRanges(new ScSimpleRangeList)
+ {}
+ ~ScMyCurrencyStyle() {}
+};
+
+struct LessCurrencyStyle
+{
+ sal_Bool operator() (const ScMyCurrencyStyle& rValue1, const ScMyCurrencyStyle& rValue2) const
+ {
+ return rValue1.sCurrency < rValue2.sCurrency;
+ }
+};
+
+typedef std::set<ScMyCurrencyStyle, LessCurrencyStyle> ScMyCurrencyStylesSet;
+
+class ScMyStyleRanges : public SvRefBase
+{
+ ::boost::shared_ptr<ScSimpleRangeList> mpTextList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpNumberList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpTimeList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpDateTimeList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpPercentList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpLogicalList;
+ ::boost::shared_ptr<ScSimpleRangeList> mpUndefinedList;
+ ScMyCurrencyStylesSet* pCurrencyList;
+
+ void SetStylesToRanges(const ::std::list<ScRange>& rList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport);
+ void SetStylesToRanges(ScRangeList* pList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport);
+ void SetStylesToRanges(ScRangeListRef xList,
+ const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+ const rtl::OUString* pCurrency, ScXMLImport& rImport);
+public:
+ ScMyStyleRanges();
+ ~ScMyStyleRanges();
+ void AddRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const sal_Int16 nType,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void AddCurrencyRange(const ScRange& rRange,
+ const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+ ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+ void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc);
+ void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc);
+ void SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport);
+};
+SV_DECL_IMPL_REF( ScMyStyleRanges );
+
+struct ScMyStyle
+{
+ rtl::OUString sStyleName;
+ ScMyStyleRangesRef xRanges;
+
+ ScMyStyle() : xRanges(new ScMyStyleRanges()) {}
+ ~ScMyStyle() {}
+};
+
+struct LessStyle
+{
+ sal_Bool operator() (const ScMyStyle& rValue1, const ScMyStyle& rValue2) const
+ {
+ return rValue1.sStyleName < rValue2.sStyleName;
+ }
+};
+
+typedef std::set<ScMyStyle, LessStyle> ScMyStylesSet;
+typedef std::vector<ScMyStylesSet::iterator> ScMyStyles;
+
+class ScMyStylesImportHelper
+{
+ ScMyStylesSet aCellStyles;
+ ScMyStyles aColDefaultStyles;
+ ScMyStylesSet::iterator aRowDefaultStyle;
+ ScXMLImport& rImport;
+ rtl::OUString* pStyleName;
+ rtl::OUString* pPrevStyleName;
+ rtl::OUString* pCurrency;
+ rtl::OUString* pPrevCurrency;
+ ScRange aPrevRange;
+ sal_uInt32 nMaxRanges;
+ sal_Int16 nCellType;
+ sal_Int16 nPrevCellType;
+ sal_Bool bPrevRangeAdded;
+
+ void ResetAttributes();
+ ScMyStylesSet::iterator GetIterator(const rtl::OUString* pStyleName);
+ void AddDefaultRange(const ScRange& rRange);
+ void AddSingleRange(const ScRange& rRange);
+ void AddRange();
+ sal_Bool IsEqual(const rtl::OUString* pFirst, const rtl::OUString* pSecond)
+ {
+ return ((pFirst && pSecond && pFirst->equals(*pSecond)) ||
+ (!pFirst && !pSecond) ||
+ (!pFirst && pSecond && !pSecond->getLength()) ||
+ (!pSecond && pFirst && !pFirst->getLength()));
+ }
+public:
+ ScMyStylesImportHelper(ScXMLImport& rImport);
+ ~ScMyStylesImportHelper();
+ void AddColumnStyle(const rtl::OUString& rStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat);
+ void SetRowStyle(const rtl::OUString& rStyleName);
+ void SetAttributes(rtl::OUString* pStyleName,
+ rtl::OUString* pCurrency, const sal_Int16 nCellType);
+ void AddRange(const ScRange& rRange);
+ void AddCell(const com::sun::star::table::CellAddress& rAddress);
+ void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc); // a row is inserted before nRow
+ void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc); // a col is inserted before nCol
+ void EndTable();
+ void SetStylesToRanges();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
new file mode 100644
index 000000000000..7e21651685e1
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx
@@ -0,0 +1,272 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/text/XText.hpp>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include "XMLTableHeaderFooterContext.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <comphelper/extract.hxx>
+
+#include "unonames.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace xmloff::token;
+
+using rtl::OUString;
+
+TYPEINIT1( XMLTableHeaderFooterContext, SvXMLImportContext );
+
+XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList,
+ const Reference < XPropertySet > & rPageStylePropSet,
+ sal_Bool bFooter, sal_Bool bLft ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xPropSet( rPageStylePropSet ),
+ sOn( bFooter ? OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_FTRON)) : OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_HDRON)) ),
+ sShareContent( bFooter ? OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_FTRSHARED)) : OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_HDRSHARED)) ),
+ sContent( bFooter ? OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTFTRCON)) : OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTHDRCON)) ),
+ sContentLeft( bFooter ? OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_LEFTFTRCONT)) : OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_LEFTHDRCONT)) ),
+ bDisplay( sal_True ),
+ bInsertContent( sal_True ),
+ bLeft( bLft ),
+ bContainsLeft(false),
+ bContainsRight(false),
+ bContainsCenter(false)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLName;
+ sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLName ));
+ const OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ // TODO: use a map here
+ if( XML_NAMESPACE_STYLE == nPrefix )
+ {
+ if( IsXMLToken(aLName, XML_DISPLAY ) )
+ bDisplay = IsXMLToken(rValue, XML_TRUE);
+ }
+ }
+ if( bLeft )
+ {
+ sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn )));
+
+ if( bOn && bDisplay )
+ {
+ if( ::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) )
+ // Don't share headers any longer
+ xPropSet->setPropertyValue( sShareContent, uno::makeAny(false) );
+ }
+ else
+ {
+ if( !::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) )
+ // share headers
+ xPropSet->setPropertyValue( sShareContent, uno::makeAny(sal_True) );
+ }
+ }
+ else
+ {
+ sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn )));
+ if ( bOn != bDisplay )
+ xPropSet->setPropertyValue( sOn, uno::makeAny(bDisplay) );
+ }
+ if (bLeft)
+ sCont = sContentLeft;
+ else
+ sCont = sContent;
+ xPropSet->getPropertyValue( sCont ) >>= xHeaderFooterContent;
+}
+
+XMLTableHeaderFooterContext::~XMLTableHeaderFooterContext()
+{
+}
+
+SvXMLImportContext *XMLTableHeaderFooterContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLocalName, XML_P))
+ {
+ if (!xTextCursor.is())
+ {
+ if( xHeaderFooterContent.is() )
+ {
+ uno::Reference < text::XText > xText(xHeaderFooterContent->getCenterText());
+ xText->setString(sEmpty);
+ xTextCursor.set(xText->createTextCursor());
+ xOldTextCursor.set(GetImport().GetTextImport()->GetCursor());
+ GetImport().GetTextImport()->SetCursor( xTextCursor );
+ bContainsCenter = sal_True;
+ }
+ }
+ pContext =
+ GetImport().GetTextImport()->CreateTextChildContext(GetImport(),
+ nPrefix,
+ rLocalName,
+ xAttrList);
+ }
+ else
+ {
+ if (nPrefix == XML_NAMESPACE_STYLE)
+ {
+ if (xHeaderFooterContent.is())
+ {
+ uno::Reference < text::XText > xText;
+ if (IsXMLToken(rLocalName, XML_REGION_LEFT ))
+ {
+ xText.set(xHeaderFooterContent->getLeftText());
+ bContainsLeft = sal_True;
+ }
+ else if (IsXMLToken(rLocalName, XML_REGION_CENTER ))
+ {
+ xText.set(xHeaderFooterContent->getCenterText());
+ bContainsCenter = sal_True;
+ }
+ else if (IsXMLToken(rLocalName, XML_REGION_RIGHT ))
+ {
+ xText.set(xHeaderFooterContent->getRightText());
+ bContainsRight = sal_True;
+ }
+ if (xText.is())
+ {
+ xText->setString(sEmpty);
+ //SvXMLImport aSvXMLImport( GetImport() );
+ uno::Reference < text::XTextCursor > xTempTextCursor(xText->createTextCursor());
+ pContext = new XMLHeaderFooterRegionContext( GetImport(), nPrefix, rLocalName, xAttrList, xTempTextCursor);
+ }
+ }
+ }
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void XMLTableHeaderFooterContext::EndElement()
+{
+ if( GetImport().GetTextImport()->GetCursor().is() )
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ GetImport().GetTextImport()->ResetCursor();
+ }
+ if (xOldTextCursor.is())
+ GetImport().GetTextImport()->SetCursor(xOldTextCursor);
+ if (xHeaderFooterContent.is())
+ {
+ if (!bContainsLeft)
+ xHeaderFooterContent->getLeftText()->setString(sEmpty);
+ if (!bContainsCenter)
+ xHeaderFooterContent->getCenterText()->setString(sEmpty);
+ if (!bContainsRight)
+ xHeaderFooterContent->getRightText()->setString(sEmpty);
+
+ xPropSet->setPropertyValue( sCont, uno::makeAny(xHeaderFooterContent) );
+ }
+}
+
+TYPEINIT1( XMLHeaderFooterRegionContext, SvXMLImportContext );
+
+XMLHeaderFooterRegionContext::XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<
+ xml::sax::XAttributeList > & /* xAttrList */,
+ uno::Reference< text::XTextCursor >& xCursor ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xTextCursor ( xCursor )
+{
+ xOldTextCursor.set(GetImport().GetTextImport()->GetCursor());
+ GetImport().GetTextImport()->SetCursor( xTextCursor );
+}
+
+XMLHeaderFooterRegionContext::~XMLHeaderFooterRegionContext()
+{
+}
+
+SvXMLImportContext *XMLHeaderFooterRegionContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLocalName, XML_P))
+ {
+ pContext =
+ GetImport().GetTextImport()->CreateTextChildContext(GetImport(),
+ nPrefix,
+ rLocalName,
+ xAttrList);
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void XMLHeaderFooterRegionContext::EndElement()
+{
+ if( GetImport().GetTextImport()->GetCursor().is() )
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ OUString sEmpty;
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ GetImport().GetTextImport()->ResetCursor();
+ }
+ if (xOldTextCursor.is())
+ GetImport().GetTextImport()->SetCursor(xOldTextCursor);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
new file mode 100644
index 000000000000..eecedc746b3e
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_
+#define SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_
+
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XTextCursor; }
+ namespace beans { class XPropertySet; }
+} } }
+
+class XMLTableHeaderFooterContext: public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xOldTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > xPropSet;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::sheet::XHeaderFooterContent > xHeaderFooterContent;
+
+ const ::rtl::OUString sOn;
+ const ::rtl::OUString sShareContent;
+ const ::rtl::OUString sContent;
+ const ::rtl::OUString sContentLeft;
+ const ::rtl::OUString sEmpty;
+ rtl::OUString sCont;
+
+ sal_Bool bDisplay;
+ sal_Bool bInsertContent;
+ sal_Bool bLeft;
+ sal_Bool bContainsLeft;
+ sal_Bool bContainsRight;
+ sal_Bool bContainsCenter;
+
+public:
+ TYPEINFO();
+
+ XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > & rPageStylePropSet,
+ sal_Bool bFooter, sal_Bool bLft );
+
+ virtual ~XMLTableHeaderFooterContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void EndElement();
+};
+
+class XMLHeaderFooterRegionContext: public SvXMLImportContext
+{
+private:
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor >& xTextCursor;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::text::XTextCursor > xOldTextCursor;
+
+public:
+ TYPEINFO();
+
+ XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ com::sun::star::uno::Reference< com::sun::star::text::XTextCursor >& xCursor );
+
+ virtual ~XMLHeaderFooterRegionContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void EndElement();
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.cxx b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
new file mode 100644
index 000000000000..4b145b9df1d3
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableMasterPageExport.cxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <tools/debug.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "XMLTableMasterPageExport.hxx"
+#include <comphelper/extract.hxx>
+
+#include "unonames.hxx"
+#include "xmlexprt.hxx"
+
+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 xmloff::token;
+
+XMLTableMasterPageExport::XMLTableMasterPageExport( ScXMLExport& rExp ) :
+ XMLTextMasterPageExport ( rExp )
+{
+}
+
+XMLTableMasterPageExport::~XMLTableMasterPageExport()
+{
+}
+
+void XMLTableMasterPageExport::exportHeaderFooterContent(
+ const Reference< XText >& rText,
+ sal_Bool bAutoStyles, sal_Bool bProgress )
+{
+ DBG_ASSERT( rText.is(), "There is the text" );
+
+ if( bAutoStyles )
+ GetExport().GetTextParagraphExport()
+ ->collectTextAutoStyles( rText, bProgress, false );
+ else
+ {
+ GetExport().GetTextParagraphExport()->exportTextDeclarations( rText );
+ GetExport().GetTextParagraphExport()->exportText( rText, bProgress, false );
+ }
+}
+
+void XMLTableMasterPageExport::exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter,
+ const XMLTokenEnum aName,
+ const sal_Bool bDisplay)
+{
+ if( xHeaderFooter.is() )
+ {
+ Reference < XText > xCenter(xHeaderFooter->getCenterText());
+ Reference < XText > xLeft(xHeaderFooter->getLeftText());
+ Reference < XText > xRight(xHeaderFooter->getRightText());
+ if (xCenter.is() && xLeft.is() && xRight.is())
+ {
+ rtl::OUString sCenter (xCenter->getString());
+ rtl::OUString sLeft (xLeft->getString());
+ rtl::OUString sRight (xRight->getString());
+
+ if( !bDisplay )
+ GetExport().AddAttribute( XML_NAMESPACE_STYLE,
+ XML_DISPLAY, XML_FALSE );
+ SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
+ aName, sal_True, sal_True );
+ if (sCenter.getLength() && !sLeft.getLength() && !sRight.getLength())
+ exportHeaderFooterContent( xCenter, false, false );
+ else
+ {
+ if (sLeft.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_LEFT, sal_True, sal_True );
+ exportHeaderFooterContent( xLeft, false, false );
+ }
+ if (sCenter.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_CENTER, sal_True, sal_True );
+ exportHeaderFooterContent( xCenter, false, false );
+ }
+ if (sRight.getLength())
+ {
+ SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE,
+ XML_REGION_RIGHT, sal_True, sal_True );
+ exportHeaderFooterContent( xRight, false, false );
+ }
+ }
+ }
+ }
+}
+
+void XMLTableMasterPageExport::exportMasterPageContent(
+ const Reference < XPropertySet > & rPropSet,
+ sal_Bool bAutoStyles )
+{
+ Reference < sheet::XHeaderFooterContent > xHeader(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTHDRCON ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xHeaderLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTHDRCONT ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xFooter(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTFTRCON ) ) ), uno::UNO_QUERY);
+
+ Reference < sheet::XHeaderFooterContent > xFooterLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTFTRCONT ) ) ), uno::UNO_QUERY);
+
+ if( bAutoStyles )
+ {
+ if( xHeader.is() )
+ {
+ exportHeaderFooterContent( xHeader->getCenterText(), sal_True, false );
+ exportHeaderFooterContent( xHeader->getLeftText(), sal_True, false );
+ exportHeaderFooterContent( xHeader->getRightText(), sal_True, false );
+ }
+ if( xHeaderLeft.is())
+ {
+ exportHeaderFooterContent( xHeaderLeft->getCenterText(), sal_True, false );
+ exportHeaderFooterContent( xHeaderLeft->getLeftText(), sal_True, false );
+ exportHeaderFooterContent( xHeaderLeft->getRightText(), sal_True, false );
+ }
+ if( xFooter.is() )
+ {
+ exportHeaderFooterContent( xFooter->getCenterText(), sal_True, false );
+ exportHeaderFooterContent( xFooter->getLeftText(), sal_True, false );
+ exportHeaderFooterContent( xFooter->getRightText(), sal_True, false );
+ }
+ if( xFooterLeft.is())
+ {
+ exportHeaderFooterContent( xFooterLeft->getCenterText(), sal_True, false );
+ exportHeaderFooterContent( xFooterLeft->getLeftText(), sal_True, false );
+ exportHeaderFooterContent( xFooterLeft->getRightText(), sal_True, false );
+ }
+ }
+ else
+ {
+ sal_Bool bHeader(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRON ) ) )));
+
+ exportHeaderFooter(xHeader, XML_HEADER, bHeader );
+
+ sal_Bool bLeftHeader(!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRSHARED ) ) )) && bHeader);
+
+ exportHeaderFooter( xHeaderLeft, XML_HEADER_LEFT, bLeftHeader );
+
+ sal_Bool bFooter(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRON ) ) )));
+
+ exportHeaderFooter( xFooter, XML_FOOTER, bFooter );
+
+ sal_Bool bLeftFooter = (!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRSHARED ) ) )) && bFooter);
+
+ exportHeaderFooter( xFooterLeft, XML_FOOTER_LEFT, bLeftFooter );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.hxx b/sc/source/filter/xml/XMLTableMasterPageExport.hxx
new file mode 100644
index 000000000000..33327ee3b90d
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableMasterPageExport.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLEMASTERPAGEEXPORT_HXX
+#define SC_XMLTABLEMASTERPAGEEXPORT_HXX
+
+#include <rtl/ustring.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/XMLTextMasterPageExport.hxx>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+
+#include "xmlexprt.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XText; }
+} } }
+
+class XMLTableMasterPageExport : public XMLTextMasterPageExport
+{
+ void exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter,
+ const xmloff::token::XMLTokenEnum aName,
+ const sal_Bool bDisplay);
+
+protected:
+ virtual void exportHeaderFooterContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::text::XText >& rText,
+ sal_Bool bAutoStyles, sal_Bool bProgress );
+
+ virtual void exportMasterPageContent(
+ const ::com::sun::star::uno::Reference <
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ sal_Bool bAutoStyles );
+
+public:
+ XMLTableMasterPageExport( ScXMLExport& rExp );
+ ~XMLTableMasterPageExport();
+};
+
+
+#endif // _XMLOFF_XMLTABLEMASTERPAGEEXPORT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
new file mode 100644
index 000000000000..27c9cb701a27
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include "XMLConverter.hxx"
+#include "drwlayer.hxx"
+#include "xmlannoi.hxx"
+#include "rangeutl.hxx"
+#include "userdat.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/svdobj.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#define SC_LAYERID "LayerID"
+
+using namespace ::com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+using rtl::OUString;
+
+XMLTableShapeImportHelper::XMLTableShapeImportHelper(
+ ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) :
+ XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ),
+ pAnnotationContext(NULL),
+ bOnTable(false)
+{
+}
+
+XMLTableShapeImportHelper::~XMLTableShapeImportHelper()
+{
+}
+
+void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const
+{
+ if (sType.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape"))))
+ nLayerID = SC_LAYER_CONTROLS;
+ if (nLayerID != -1)
+ {
+ uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ xShapeProp->setPropertyValue(OUString( RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ) ), uno::makeAny(nLayerID) );
+ }
+}
+
+void XMLTableShapeImportHelper::finishShape(
+ uno::Reference< drawing::XShape >& rShape,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList,
+ uno::Reference< drawing::XShapes >& rShapes )
+{
+ bool bNote = false;
+ XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
+ static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
+ ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
+ if (rShapes == rTables.GetCurrentXShapes())
+ {
+ if (!pAnnotationContext)
+ {
+ ScDrawObjData aAnchor;
+ aAnchor.maStart = ScAddress(aStartCell.Column, aStartCell.Row, aStartCell.Sheet);
+ awt::Point aStartPoint(rShape->getPosition());
+ aAnchor.maStartOffset = Point(aStartPoint.X, aStartPoint.Y);
+
+ sal_Int32 nEndX(-1);
+ sal_Int32 nEndY(-1);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ table::CellAddress aEndCell;
+ rtl::OUString* pRangeList(NULL);
+ sal_Int16 nLayerID(-1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(
+ static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName,
+ &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS))
+ {
+ sal_Int32 nOffset(0);
+ ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset);
+ aAnchor.maEnd = ScAddress(aEndCell.Column, aEndCell.Row, aEndCell.Sheet);
+ }
+ else if (IsXMLToken(aLocalName, XML_END_X))
+ {
+ static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndX, rValue);
+ aAnchor.maEndOffset.X() = nEndX;
+ }
+ else if (IsXMLToken(aLocalName, XML_END_Y))
+ {
+ static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndY, rValue);
+ aAnchor.maEndOffset.Y() = nEndY;
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
+ if (IsXMLToken(rValue, XML_TRUE))
+ nLayerID = SC_LAYER_BACK;
+ }
+ else if(nPrefix == XML_NAMESPACE_DRAW)
+ {
+ if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES))
+ pRangeList = new rtl::OUString(rValue);
+ }
+ }
+ SetLayer(rShape, nLayerID, rShape->getShapeType());
+
+ if (SvxShape* pShapeImp = SvxShape::getImplementation(rShape))
+ {
+ if (SdrObject *pSdrObj = pShapeImp->GetSdrObject())
+ {
+ if (!bOnTable)
+ ScDrawLayer::SetCellAnchored(*pSdrObj, aAnchor);
+ else
+ ScDrawLayer::SetPageAnchored(*pSdrObj);
+ }
+ }
+
+ if ( bOnTable && pRangeList )
+ {
+ // #i78086# If there are notification ranges, the ChartListener must be created
+ // also when anchored to the sheet
+ // -> call AddOLE with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
+
+ if (rTables.IsOLE(rShape))
+ rTables.AddOLE(rShape, *pRangeList);
+ }
+
+ delete pRangeList;
+ }
+ else // shape is annotation
+ {
+ // get the style names for stream copying
+ rtl::OUString aStyleName;
+ rtl::OUString aTextStyle;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_DRAW)
+ {
+ if (IsXMLToken(aLocalName, XML_STYLE_NAME))
+ aStyleName = xAttrList->getValueByIndex( i );
+ else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
+ aTextStyle = xAttrList->getValueByIndex( i );
+ }
+ }
+
+ pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
+ bNote = true;
+ }
+ }
+ else //this are grouped shapes which should also get the layerid
+ {
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ sal_Int16 nLayerID(-1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND))
+ if (IsXMLToken(rValue, XML_TRUE))
+ nLayerID = SC_LAYER_BACK;
+ }
+ }
+ SetLayer(rShape, nLayerID, rShape->getShapeType());
+ }
+
+ if (!bNote)
+ {
+ // any shape other than a note prevents copying the sheet
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( rTables.GetCurrentSheet() );
+ }
+
+ static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.hxx b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
new file mode 100644
index 000000000000..fb40daa82756
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPEIMPORTHELPER_HXX
+#define SC_XMLTABLESHAPEIMPORTHELPER_HXX
+
+#include <xmloff/shapeimport.hxx>
+#include <com/sun/star/table/CellAddress.hpp>
+
+class ScXMLImport;
+class ScXMLAnnotationContext;
+
+class XMLTableShapeImportHelper : public XMLShapeImportHelper
+{
+ ::com::sun::star::table::CellAddress aStartCell;
+ ScXMLAnnotationContext* pAnnotationContext;
+ sal_Bool bOnTable;
+
+public:
+
+ XMLTableShapeImportHelper( ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper=0 );
+ ~XMLTableShapeImportHelper();
+
+ void SetLayer(com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const;
+ virtual void finishShape(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList,
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes);
+
+
+ void SetCell (const ::com::sun::star::table::CellAddress& rAddress) { aStartCell = rAddress; }
+ void SetOnTable (const sal_Bool bTempOnTable) { bOnTable = bTempOnTable; }
+ void SetAnnotation(ScXMLAnnotationContext* pAnnotation) { pAnnotationContext = pAnnotation; }
+
+ ScXMLAnnotationContext* GetAnnotationContext() const { return pAnnotationContext; }
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapeResizer.cxx b/sc/source/filter/xml/XMLTableShapeResizer.cxx
new file mode 100644
index 000000000000..e5281f43cb88
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeResizer.cxx
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "XMLTableShapeResizer.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "xmlimprt.hxx"
+#include "chartlis.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+#include "reftokenhelper.hxx"
+#include <tools/debug.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <memory>
+#include <vector>
+
+using namespace ::com::sun::star;
+using ::std::auto_ptr;
+using ::std::vector;
+using ::rtl::OUString;
+
+ScMyOLEFixer::ScMyOLEFixer(ScXMLImport& rTempImport)
+ : rImport(rTempImport),
+ aShapes(),
+ pCollection(NULL)
+{
+}
+
+ScMyOLEFixer::~ScMyOLEFixer()
+{
+}
+
+sal_Bool ScMyOLEFixer::IsOLE(uno::Reference< drawing::XShape >& rShape)
+{
+ return rShape->getShapeType().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.OLE2Shape"));
+}
+
+void ScMyOLEFixer::CreateChartListener(ScDocument* pDoc,
+ const rtl::OUString& rName,
+ const rtl::OUString& rRangeList)
+{
+ // This is the minimum required.
+ if (!pDoc)
+ return;
+
+ if (!rRangeList.getLength())
+ {
+ pDoc->AddOLEObjectToCollection(rName);
+ return;
+ }
+
+ OUString aRangeStr;
+ ScRangeStringConverter::GetStringFromXMLRangeString(aRangeStr, rRangeList, pDoc);
+ if (!aRangeStr.getLength())
+ {
+ pDoc->AddOLEObjectToCollection(rName);
+ return;
+ }
+
+ if (!pCollection)
+ pCollection = pDoc->GetChartListenerCollection();
+
+ if (!pCollection)
+ return;
+
+ auto_ptr< vector<ScTokenRef> > pRefTokens(new vector<ScTokenRef>);
+ ScRefTokenHelper::compileRangeRepresentation(*pRefTokens, aRangeStr, pDoc);
+ if (!pRefTokens->empty())
+ {
+ ScChartListener* pCL(new ScChartListener(rName, pDoc, pRefTokens.release()));
+
+ //for loading binary files e.g.
+ //if we have the flat filter we need to set the dirty flag thus the visible charts get repainted
+ //otherwise the charts keep their first visual representation which was created at a moment where the calc itself was not loaded completly and is incorect therefor
+ if( (rImport.getImportFlags() & IMPORT_ALL) == IMPORT_ALL )
+ pCL->SetDirty( sal_True );
+ else
+ {
+ // #i104899# If a formula cell is already dirty, further changes aren't propagated.
+ // This can happen easily now that row heights aren't updated for all sheets.
+ pDoc->InterpretDirtyCells( *pCL->GetRangeList() );
+ }
+
+ pCollection->Insert( pCL );
+ pCL->StartListeningTo();
+ }
+}
+
+void ScMyOLEFixer::AddOLE(uno::Reference <drawing::XShape>& rShape,
+ const rtl::OUString &rRangeList)
+{
+ ScMyToFixupOLE aShape;
+ aShape.xShape.set(rShape);
+ aShape.sRangeList = rRangeList;
+ aShapes.push_back(aShape);
+}
+
+void ScMyOLEFixer::FixupOLEs()
+{
+ if (!aShapes.empty() && rImport.GetModel().is())
+ {
+ rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
+ ScMyToFixupOLEs::iterator aItr(aShapes.begin());
+ ScMyToFixupOLEs::iterator aEndItr(aShapes.end());
+ ScDocument* pDoc(rImport.GetDocument());
+
+ ScXMLImport::MutexGuard aGuard(rImport);
+
+ while (aItr != aEndItr)
+ {
+ // #i78086# also call CreateChartListener for invalid position (anchored to sheet)
+ if (!IsOLE(aItr->xShape))
+ OSL_FAIL("Only OLEs should be in here now");
+
+ if (IsOLE(aItr->xShape))
+ {
+ uno::Reference < beans::XPropertySet > xShapeProps ( aItr->xShape, uno::UNO_QUERY );
+ uno::Reference < beans::XPropertySetInfo > xShapeInfo(xShapeProps->getPropertySetInfo());
+
+ rtl::OUString sName;
+ if (pDoc && xShapeProps.is() && xShapeInfo.is() && xShapeInfo->hasPropertyByName(sPersistName) &&
+ (xShapeProps->getPropertyValue(sPersistName) >>= sName))
+ CreateChartListener(pDoc, sName, aItr->sRangeList);
+ }
+ aItr = aShapes.erase(aItr);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapeResizer.hxx b/sc/source/filter/xml/XMLTableShapeResizer.hxx
new file mode 100644
index 000000000000..fde729ef2e7c
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapeResizer.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPERESIZER_HXX
+#define SC_XMLTABLESHAPERESIZER_HXX
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <list>
+
+class ScXMLImport;
+class ScChartListenerCollection;
+class ScDocument;
+class Rectangle;
+
+struct ScMyToFixupOLE
+{
+ com::sun::star::uno::Reference <com::sun::star::drawing::XShape> xShape;
+ rtl::OUString sRangeList;
+};
+
+typedef std::list<ScMyToFixupOLE> ScMyToFixupOLEs;
+
+class ScMyOLEFixer
+{
+ ScXMLImport& rImport;
+ ScMyToFixupOLEs aShapes;
+ ScChartListenerCollection* pCollection;
+
+ void CreateChartListener(ScDocument* pDoc,
+ const rtl::OUString& rName,
+ const rtl::OUString& rRangeList);
+public:
+ ScMyOLEFixer(ScXMLImport& rImport);
+ ~ScMyOLEFixer();
+
+ static sal_Bool IsOLE(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape);
+ void AddOLE(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape,
+ const rtl::OUString &rRangeList);
+ void FixupOLEs();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapesContext.cxx b/sc/source/filter/xml/XMLTableShapesContext.cxx
new file mode 100644
index 000000000000..6a995fe9f052
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapesContext.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTableShapesContext.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+ScXMLTableShapesContext::ScXMLTableShapesContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+}
+
+ScXMLTableShapesContext::~ScXMLTableShapesContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableShapesContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (!pContext)
+ {
+ ScXMLImport& rXMLImport(GetScImport());
+ uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
+ if (xShapes.is())
+ {
+ XMLTableShapeImportHelper* pTableShapeImport((XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get());
+ pTableShapeImport->SetOnTable(sal_True);
+ pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList, xShapes);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableShapesContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableShapesContext.hxx b/sc/source/filter/xml/XMLTableShapesContext.hxx
new file mode 100644
index 000000000000..ba92335aae26
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableShapesContext.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESHAPESCONTEXT_HXX
+#define SC_XMLTABLESHAPESCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableShapesContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTableShapesContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLTableShapesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableSourceContext.cxx b/sc/source/filter/xml/XMLTableSourceContext.cxx
new file mode 100644
index 000000000000..303b4eb684c2
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableSourceContext.cxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTableSourceContext.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "xmlsubti.hxx"
+#include "tablink.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableSourceContext::ScXMLTableSourceContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sLink(),
+ sTableName(),
+ sFilterName(),
+ sFilterOptions(),
+ nRefresh(0),
+ nMode(sheet::SheetLinkMode_NORMAL)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ if(nPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ sLink = GetScImport().GetAbsoluteReference(sValue);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_NAME))
+ sTableName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_NAME))
+ sFilterName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS))
+ sFilterOptions = sValue;
+ else if (IsXMLToken(aLocalName, XML_MODE))
+ {
+ if (IsXMLToken(sValue, XML_COPY_RESULTS_ONLY))
+ nMode = sheet::SheetLinkMode_VALUE;
+ }
+ else if (IsXMLToken(aLocalName, XML_REFRESH_DELAY))
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ }
+ }
+}
+
+ScXMLTableSourceContext::~ScXMLTableSourceContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableSourceContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLTableSourceContext::EndElement()
+{
+ if (sLink.getLength())
+ {
+ uno::Reference <sheet::XSheetLinkable> xLinkable (GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (xLinkable.is() && pDoc)
+ {
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ if (pDoc->RenameTab( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()),
+ GetScImport().GetTables().GetCurrentSheetName(), false, sal_True))
+ {
+ String aFileString(sLink);
+ String aFilterString(sFilterName);
+ String aOptString(sFilterOptions);
+ String aSheetString(sTableName);
+
+ aFileString = ScGlobal::GetAbsDocName( aFileString, pDoc->GetDocumentShell() );
+ if ( !aFilterString.Len() )
+ ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, false, false );
+
+ sal_uInt8 nLinkMode = SC_LINK_NONE;
+ if ( nMode == sheet::SheetLinkMode_NORMAL )
+ nLinkMode = SC_LINK_NORMAL;
+ else if ( nMode == sheet::SheetLinkMode_VALUE )
+ nLinkMode = SC_LINK_VALUE;
+
+ pDoc->SetLink( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()),
+ nLinkMode, aFileString, aFilterString, aOptString,
+ aSheetString, nRefresh );
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTableSourceContext.hxx b/sc/source/filter/xml/XMLTableSourceContext.hxx
new file mode 100644
index 000000000000..8edc8551b121
--- /dev/null
+++ b/sc/source/filter/xml/XMLTableSourceContext.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTABLESOURCECONTEXT_HXX
+#define SC_XMLTABLESOURCECONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/sheet/SheetLinkMode.hpp>
+
+class ScXMLImport;
+
+class ScXMLTableSourceContext : public SvXMLImportContext
+{
+ rtl::OUString sLink;
+ rtl::OUString sTableName;
+ rtl::OUString sFilterName;
+ rtl::OUString sFilterOptions;
+ sal_Int32 nRefresh;
+ com::sun::star::sheet::SheetLinkMode nMode;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTableSourceContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLTableSourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTextPContext.cxx b/sc/source/filter/xml/XMLTextPContext.cxx
new file mode 100644
index 000000000000..8251da5dfa0b
--- /dev/null
+++ b/sc/source/filter/xml/XMLTextPContext.cxx
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLTextPContext.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/text/XTextCursor.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+class ScXMLTextTContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+public:
+ ScXMLTextTContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTextPContext* pTextPContext);
+
+ virtual ~ScXMLTextTContext();
+};
+
+
+ScXMLTextTContext::ScXMLTextTContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTextPContext* pTextPContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ if (pTextPContext)
+ {
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ rtl::OUString aLocalName;
+ sal_Int32 nCount(1);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex( i ), &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C))
+ nCount = sValue.toInt32();
+ }
+ pTextPContext->AddSpaces(nCount);
+ }
+}
+
+ScXMLTextTContext::~ScXMLTextTContext()
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLTextPContext::ScXMLTextPContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList,
+ ScXMLTableRowCellContext* pTempCellContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xAttrList(xTempAttrList),
+ pTextPContext(NULL),
+ pCellContext(pTempCellContext),
+ sLName(rLName),
+ sSimpleContent(),
+ pContentBuffer(NULL),
+ nPrefix(nPrfx),
+ bIsOwn(sal_True)
+{
+ // here are no attributes
+}
+
+ScXMLTextPContext::~ScXMLTextPContext()
+{
+ if (pTextPContext)
+ delete pTextPContext;
+ if (pContentBuffer)
+ delete pContentBuffer;
+}
+
+void ScXMLTextPContext::AddSpaces(sal_Int32 nSpaceCount)
+{
+ // use pContentBuffer
+ if ( !pContentBuffer )
+ pContentBuffer = new rtl::OUStringBuffer( sSimpleContent );
+
+ sal_Char* pChars = new sal_Char[nSpaceCount];
+ memset(pChars, ' ', nSpaceCount);
+ pContentBuffer->appendAscii(pChars, nSpaceCount);
+}
+
+SvXMLImportContext *ScXMLTextPContext::CreateChildContext( sal_uInt16 nTempPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList )
+{
+ SvXMLImportContext *pContext(NULL);
+ if (!pTextPContext &&
+ (nTempPrefix == XML_NAMESPACE_TEXT) &&
+ IsXMLToken(rLName, XML_S))
+ pContext = new ScXMLTextTContext( GetScImport(), nTempPrefix, rLName, xTempAttrList, this);
+ else
+ {
+ if (!pTextPContext)
+ {
+ rtl::OUString sSetString;
+ if ( pContentBuffer )
+ sSetString = pContentBuffer->makeStringAndClear();
+ else
+ sSetString = sSimpleContent;
+
+ sal_Unicode cNonSpace(0);
+
+ sal_Int32 nLength = sSetString.getLength();
+ if ( nLength > 0 )
+ {
+ sal_Unicode cLast = sSetString.getStr()[ nLength - 1 ];
+ if ( cLast != (sal_Unicode)' ' )
+ {
+ // #i53253# To keep XMLParaContext's whitespace handling in sync,
+ // if there's a non-space character at the end of the existing string,
+ // it has to be processed by XMLParaContext.
+
+ cNonSpace = cLast;
+ sSetString = sSetString.copy( 0, nLength - 1 ); // remove from the string for SetCursorOnTextImport
+ }
+ }
+
+ pCellContext->SetCursorOnTextImport( sSetString );
+
+ pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, sLName, xAttrList);
+
+ if ( cNonSpace != 0 )
+ {
+ // pass non-space character through XMLParaContext, so a following space isn't ignored
+ pTextPContext->Characters( rtl::OUString( cNonSpace ) );
+ }
+ }
+ if (pTextPContext)
+ pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetScImport(), nTempPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTextPContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!pTextPContext)
+ {
+ // For the first call to an empty context, copy (ref-counted) the OUString.
+ // The OUStringBuffer is used only if there is more complex content.
+
+ if ( !pContentBuffer && sSimpleContent.getLength() == 0 )
+ sSimpleContent = rChars;
+ else
+ {
+ if ( !pContentBuffer )
+ pContentBuffer = new rtl::OUStringBuffer( sSimpleContent );
+ pContentBuffer->append(rChars);
+ }
+ }
+ else
+ pTextPContext->Characters(rChars);
+}
+
+void ScXMLTextPContext::EndElement()
+{
+ if (!pTextPContext)
+ {
+ if ( pContentBuffer )
+ pCellContext->SetString(pContentBuffer->makeStringAndClear());
+ else
+ pCellContext->SetString(sSimpleContent);
+ }
+ else
+ {
+ pTextPContext->EndElement();
+ GetScImport().SetRemoveLastChar(sal_True);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTextPContext.hxx b/sc/source/filter/xml/XMLTextPContext.hxx
new file mode 100644
index 000000000000..20dda85322c3
--- /dev/null
+++ b/sc/source/filter/xml/XMLTextPContext.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTEXTPCONTEXT_HXX
+#define SC_XMLTEXTPCONTEXT_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+class ScXMLTableRowCellContext;
+
+class ScXMLTextPContext : public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList;
+ SvXMLImportContext* pTextPContext;
+ ScXMLTableRowCellContext* pCellContext;
+ rtl::OUString sLName;
+ rtl::OUString sSimpleContent; // copy of the first Character call's argument
+ rtl::OUStringBuffer* pContentBuffer; // used if there's more than one string
+ sal_uInt16 nPrefix;
+ sal_Bool bIsOwn;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLTextPContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLTableRowCellContext* pCellContext);
+
+ virtual ~ScXMLTextPContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+
+ void AddSpaces(sal_Int32 nSpaceCount);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
new file mode 100644
index 000000000000..be365f4b1041
--- /dev/null
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
@@ -0,0 +1,2008 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "XMLTrackedChangesContext.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "XMLConverter.hxx"
+#include "cell.hxx"
+#include "textuno.hxx"
+#include "editutil.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <svl/zforlist.hxx>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+
+using rtl::OUString;
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+using rtl::OUString;
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeInfoContext : public SvXMLImportContext
+{
+ ScMyActionInfo aInfo;
+ ::rtl::OUStringBuffer sAuthorBuffer;
+ ::rtl::OUStringBuffer sDateTimeBuffer;
+ ::rtl::OUStringBuffer sCommentBuffer;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ sal_uInt32 nParagraphCount;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLChangeInfoContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLBigRangeContext : public SvXMLImportContext
+{
+ ScBigRange& rBigRange;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLBigRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScBigRange& rBigRange);
+ virtual ~ScXMLBigRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLCellContentDeletionContext : public SvXMLImportContext
+{
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ rtl::OUString sInputString;
+ ScBigRange aBigRange;
+ double fValue;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBaseCell* pCell;
+ sal_uInt32 nID;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+ sal_Bool bBigRange;
+ sal_Bool bContainsCell;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCellContentDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLCellContentDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDependenceContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDependenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDependenceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDependingsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDependingsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDependingsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeDeletionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLChangeDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDeletionsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDeletionsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDeletionsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeCellContext;
+
+class ScXMLChangeTextPContext : public SvXMLImportContext
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList;
+ rtl::OUString sLName;
+ rtl::OUStringBuffer sText;
+ ScXMLChangeCellContext* pChangeCellContext;
+ SvXMLImportContext* pTextPContext;
+ sal_uInt16 nPrefix;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLChangeTextPContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeCellContext* pChangeCellContext);
+
+ virtual ~ScXMLChangeTextPContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLChangeCellContext : public SvXMLImportContext
+{
+ rtl::OUString sText;
+ rtl::OUString& rInputString;
+ ScBaseCell*& rOldCell;
+ ScEditEngineTextObj* pEditTextObj;
+ double& rDateTimeValue;
+ double fValue;
+ sal_uInt16& rType;
+ sal_Bool bEmpty;
+ sal_Bool bFirstParagraph;
+ sal_Bool bString;
+ sal_Bool bFormula;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLChangeCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScBaseCell*& rOldCell, rtl::OUString& sAddress,
+ rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp,
+ formula::FormulaGrammar::Grammar& rGrammar,
+ rtl::OUString& rInputString, double& fValue, sal_uInt16& nType,
+ sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows);
+ virtual ~ScXMLChangeCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void CreateTextPContext(sal_Bool bIsNewParagraph);
+ sal_Bool IsEditCell() { return pEditTextObj != 0; }
+ void SetText(const rtl::OUString& sTempText) { sText = sTempText; }
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLPreviousContext : public SvXMLImportContext
+{
+ rtl::OUString sFormulaAddress;
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ rtl::OUString sInputString;
+ double fValue;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBaseCell* pOldCell;
+ sal_uInt32 nID;
+ sal_Int32 nMatrixCols;
+ sal_Int32 nMatrixRows;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_uInt16 nType;
+ sal_uInt8 nMatrixFlag;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLPreviousContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLPreviousContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLContentChangeContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScBigRange aBigRange;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLContentChangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLContentChangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLInsertionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLInsertionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLInsertionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLInsertionCutOffContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLInsertionCutOffContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLInsertionCutOffContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLMovementCutOffContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLMovementCutOffContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLMovementCutOffContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLCutOffsContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLCutOffsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLCutOffsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLDeletionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLDeletionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLMovementContext : public SvXMLImportContext
+{
+ ScBigRange aSourceRange;
+ ScBigRange aTargetRange;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLMovementContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLMovementContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//-----------------------------------------------------------------------------
+
+class ScXMLRejectionContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLRejectionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLRejectionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//------------------------------------------------------------------
+
+ScXMLTrackedChangesContext::ScXMLTrackedChangesContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ rImport.LockSolarMutex();
+ pChangeTrackingImportHelper->SetChangeTrack(sal_True);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
+ {
+ if (sValue.getLength())
+ {
+ uno::Sequence<sal_Int8> aPass;
+ SvXMLUnitConverter::decodeBase64(aPass, sValue);
+ pChangeTrackingImportHelper->SetProtection(aPass);
+ }
+ }
+ }
+ }
+}
+
+ScXMLTrackedChangesContext::~ScXMLTrackedChangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLTrackedChangesContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CELL_CONTENT_CHANGE))
+ {
+ pContext = new ScXMLContentChangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_INSERTION))
+ {
+ pContext = new ScXMLInsertionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_DELETION))
+ {
+ pContext = new ScXMLDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_MOVEMENT))
+ {
+ pContext = new ScXMLMovementContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_REJECTION))
+ {
+ pContext = new ScXMLRejectionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLTrackedChangesContext::EndElement()
+{
+}
+
+ScXMLChangeInfoContext::ScXMLChangeInfoContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aInfo(),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ nParagraphCount(0)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_CHG_AUTHOR))
+ {
+ sAuthorBuffer = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_CHG_DATE_TIME))
+ {
+ sDateTimeBuffer = sValue;
+ }
+ }
+ }
+}
+
+ScXMLChangeInfoContext::~ScXMLChangeInfoContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeInfoContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if( XML_NAMESPACE_DC == nPrefix )
+ {
+ if( IsXMLToken( rLocalName, XML_CREATOR ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLocalName, xAttrList, sAuthorBuffer);
+ else if( IsXMLToken( rLocalName, XML_DATE ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLocalName, xAttrList, sDateTimeBuffer);
+ }
+ else if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P)) )
+ {
+ if(nParagraphCount)
+ sCommentBuffer.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLocalName, xAttrList, sCommentBuffer);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLChangeInfoContext::EndElement()
+{
+ aInfo.sUser = sAuthorBuffer.makeStringAndClear();
+ GetScImport().GetMM100UnitConverter().convertDateTime(aInfo.aDateTime, sDateTimeBuffer.makeStringAndClear());
+ aInfo.sComment = sCommentBuffer.makeStringAndClear();
+ pChangeTrackingImportHelper->SetActionInfo(aInfo);
+}
+
+ScXMLBigRangeContext::ScXMLBigRangeContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScBigRange& rTempBigRange ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ rBigRange(rTempBigRange)
+{
+ sal_Bool bColumn(false);
+ sal_Bool bRow(false);
+ sal_Bool bTable(false);
+ sal_Int32 nColumn(0);
+ sal_Int32 nRow(0);
+ sal_Int32 nTable(0);
+ sal_Int32 nStartColumn(0);
+ sal_Int32 nEndColumn(0);
+ sal_Int32 nStartRow(0);
+ sal_Int32 nEndRow(0);
+ sal_Int32 nStartTable(0);
+ sal_Int32 nEndTable(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_COLUMN))
+ {
+ SvXMLUnitConverter::convertNumber(nColumn, sValue);
+ bColumn = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_ROW))
+ {
+ SvXMLUnitConverter::convertNumber(nRow, sValue);
+ bRow = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ bTable = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_START_COLUMN))
+ SvXMLUnitConverter::convertNumber(nStartColumn, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_COLUMN))
+ SvXMLUnitConverter::convertNumber(nEndColumn, sValue);
+ else if (IsXMLToken(aLocalName, XML_START_ROW))
+ SvXMLUnitConverter::convertNumber(nStartRow, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_ROW))
+ SvXMLUnitConverter::convertNumber(nEndRow, sValue);
+ else if (IsXMLToken(aLocalName, XML_START_TABLE))
+ SvXMLUnitConverter::convertNumber(nStartTable, sValue);
+ else if (IsXMLToken(aLocalName, XML_END_TABLE))
+ SvXMLUnitConverter::convertNumber(nEndTable, sValue);
+ }
+ }
+ if (bColumn)
+ nStartColumn = nEndColumn = nColumn;
+ if (bRow)
+ nStartRow = nEndRow = nRow;
+ if (bTable)
+ nStartTable = nEndTable = nTable;
+ rBigRange.Set(nStartColumn, nStartRow, nStartTable,
+ nEndColumn, nEndRow, nEndTable);
+}
+
+ScXMLBigRangeContext::~ScXMLBigRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLBigRangeContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLBigRangeContext::EndElement()
+{
+}
+
+ScXMLCellContentDeletionContext::ScXMLCellContentDeletionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ pCell(NULL),
+ nID(0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE),
+ bBigRange(false),
+ bContainsCell(false)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+}
+
+ScXMLCellContentDeletionContext::~ScXMLCellContentDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLCellContentDeletionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL))
+ {
+ bContainsCell = sal_True;
+ pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
+ pCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
+ }
+ else if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
+ {
+ DBG_ASSERT(!nID, "a action with a ID should not contain a BigRange");
+ bBigRange = sal_True;
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLCellContentDeletionContext::EndElement()
+{
+ ScMyCellInfo* pCellInfo(new ScMyCellInfo(pCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType,
+ nMatrixFlag, nMatrixCols, nMatrixRows));
+ if (nID)
+ pChangeTrackingImportHelper->AddDeleted(nID, pCellInfo);
+ else
+ pChangeTrackingImportHelper->AddGenerated(pCellInfo, aBigRange);
+}
+
+ScXMLDependenceContext::ScXMLDependenceContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ pChangeTrackingImportHelper->AddDependence(nID);
+}
+
+ScXMLDependenceContext::~ScXMLDependenceContext()
+{
+}
+
+SvXMLImportContext *ScXMLDependenceContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLDependenceContext::EndElement()
+{
+}
+
+ScXMLDependingsContext::ScXMLDependingsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLDependingsContext::~ScXMLDependingsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDependingsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ // #i80033# read both old (dependence) and new (dependency) elements
+ if (IsXMLToken(rLocalName, XML_DEPENDENCE) || IsXMLToken(rLocalName, XML_DEPENDENCY))
+ pContext = new ScXMLDependenceContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDependingsContext::EndElement()
+{
+}
+
+ScXMLChangeDeletionContext::ScXMLChangeDeletionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ pChangeTrackingImportHelper->AddDeleted(nID);
+}
+
+ScXMLChangeDeletionContext::~ScXMLChangeDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeDeletionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLChangeDeletionContext::EndElement()
+{
+}
+
+ScXMLDeletionsContext::ScXMLDeletionsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLDeletionsContext::~ScXMLDeletionsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDeletionsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CHANGE_DELETION))
+ pContext = new ScXMLChangeDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_CELL_CONTENT_DELETION))
+ pContext = new ScXMLCellContentDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDeletionsContext::EndElement()
+{
+}
+
+ScXMLChangeTextPContext::ScXMLChangeTextPContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList,
+ ScXMLChangeCellContext* pTempChangeCellContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ xAttrList(xTempAttrList),
+ sLName(rLName),
+ sText(),
+ pChangeCellContext(pTempChangeCellContext),
+ pTextPContext(NULL),
+ nPrefix(nPrfx)
+{
+ // here are no attributes
+}
+
+ScXMLChangeTextPContext::~ScXMLChangeTextPContext()
+{
+ if (pTextPContext)
+ delete pTextPContext;
+}
+
+SvXMLImportContext *ScXMLChangeTextPContext::CreateChildContext( sal_uInt16 nTempPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLName, XML_S)) && !pTextPContext)
+ {
+ sal_Int32 nRepeat(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrfx(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ if ((nPrfx == XML_NAMESPACE_TEXT) && (IsXMLToken(aLocalName, XML_C)))
+ nRepeat = sValue.toInt32();
+ }
+ if (nRepeat)
+ for (sal_Int32 j = 0; j < nRepeat; ++j)
+ sText.append(static_cast<sal_Unicode>(' '));
+ else
+ sText.append(static_cast<sal_Unicode>(' '));
+ }
+ else
+ {
+ if (!pChangeCellContext->IsEditCell())
+ pChangeCellContext->CreateTextPContext(false);
+ sal_Bool bWasContext (sal_True);
+ if (!pTextPContext)
+ {
+ bWasContext = false;
+ pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, sLName, xAttrList);
+ }
+ if (pTextPContext)
+ {
+ if (!bWasContext)
+ pTextPContext->Characters(sText.makeStringAndClear());
+ pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLChangeTextPContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!pTextPContext)
+ sText.append(rChars);
+ else
+ pTextPContext->Characters(rChars);
+}
+
+void ScXMLChangeTextPContext::EndElement()
+{
+ if (!pTextPContext)
+ pChangeCellContext->SetText(sText.makeStringAndClear());
+}
+
+ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScBaseCell*& rTempOldCell, rtl::OUString& rAddress,
+ rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp,
+ formula::FormulaGrammar::Grammar& rGrammar,
+ rtl::OUString& rTempInputString, double& fDateTimeValue, sal_uInt16& nType,
+ sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ rInputString(rTempInputString),
+ rOldCell(rTempOldCell),
+ pEditTextObj(NULL),
+ rDateTimeValue(fDateTimeValue),
+ rType(nType),
+ bEmpty(sal_True),
+ bFirstParagraph(sal_True),
+ bString(sal_True),
+ bFormula(false)
+{
+ sal_Bool bIsMatrix(false);
+ sal_Bool bIsCoveredMatrix(false);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_FORMULA))
+ {
+ bEmpty = false;
+ GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, rGrammar, sValue );
+ bFormula = sal_True;
+ }
+ else if (IsXMLToken(aLocalName, XML_CELL_ADDRESS))
+ {
+ rAddress = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_MATRIX_COVERED))
+ {
+ bIsCoveredMatrix = IsXMLToken(sValue, XML_TRUE);
+ }
+ else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_COLUMNS_SPANNED))
+ {
+ bIsMatrix = sal_True;
+ SvXMLUnitConverter::convertNumber(nMatrixCols, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_ROWS_SPANNED))
+ {
+ bIsMatrix = sal_True;
+ SvXMLUnitConverter::convertNumber(nMatrixRows, sValue);
+ }
+ }
+ else if (nPrefix == XML_NAMESPACE_OFFICE)
+ {
+ if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_FLOAT))
+ bString = false;
+ else if (IsXMLToken(sValue, XML_DATE))
+ {
+ rType = NUMBERFORMAT_DATE;
+ bString = false;
+ }
+ else if (IsXMLToken(sValue, XML_TIME))
+ {
+ rType = NUMBERFORMAT_TIME;
+ bString = false;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_VALUE))
+ {
+ SvXMLUnitConverter::convertDouble(fValue, sValue);
+ bEmpty = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_DATE_VALUE))
+ {
+ bEmpty = false;
+ if (GetScImport().GetMM100UnitConverter().setNullDate(GetScImport().GetModel()))
+ GetScImport().GetMM100UnitConverter().convertDateTime(rDateTimeValue, sValue);
+ fValue = rDateTimeValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_TIME_VALUE))
+ {
+ bEmpty = false;
+ GetScImport().GetMM100UnitConverter().convertTime(rDateTimeValue, sValue);
+ fValue = rDateTimeValue;
+ }
+ }
+ }
+ if (bIsCoveredMatrix)
+ nMatrixFlag = MM_REFERENCE;
+ else if (bIsMatrix && nMatrixRows && nMatrixCols)
+ nMatrixFlag = MM_FORMULA;
+}
+
+ScXMLChangeCellContext::~ScXMLChangeCellContext()
+{
+}
+
+SvXMLImportContext *ScXMLChangeCellContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P)))
+ {
+ bEmpty = false;
+ if (bFirstParagraph)
+ {
+ pContext = new ScXMLChangeTextPContext(GetScImport(), nPrefix, rLocalName, xAttrList, this);
+ bFirstParagraph = false;
+ }
+ else
+ {
+ if (!pEditTextObj)
+ CreateTextPContext(sal_True);
+ pContext = GetScImport().GetTextImport()->CreateTextChildContext(
+ GetScImport(), nPrefix, rLocalName, xAttrList);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLChangeCellContext::CreateTextPContext(sal_Bool bIsNewParagraph)
+{
+ if (GetScImport().GetDocument())
+ {
+ pEditTextObj = new ScEditEngineTextObj();
+ pEditTextObj->acquire();
+ pEditTextObj->GetEditEngine()->SetEditTextObjectPool(GetScImport().GetDocument()->GetEditPool());
+ uno::Reference <text::XText> xText(pEditTextObj);
+ if (xText.is())
+ {
+ uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
+ if (bIsNewParagraph)
+ {
+ xText->setString(sText);
+ xTextCursor->gotoEnd(false);
+ uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
+ if (xTextRange.is())
+ xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, false);
+ }
+ GetScImport().GetTextImport()->SetCursor(xTextCursor);
+ }
+ }
+}
+
+void ScXMLChangeCellContext::EndElement()
+{
+ if (!bEmpty)
+ {
+ if (pEditTextObj)
+ {
+ if (GetImport().GetTextImport()->GetCursor().is())
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ OUString sEmpty;
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), sEmpty,
+ sal_True );
+ }
+ }
+ if (GetScImport().GetDocument())
+ rOldCell = new ScEditCell(pEditTextObj->CreateTextObject(), GetScImport().GetDocument(), GetScImport().GetDocument()->GetEditPool());
+ GetScImport().GetTextImport()->ResetCursor();
+ pEditTextObj->release();
+ }
+ else
+ {
+ if (!bFormula)
+ {
+ if (sText.getLength() && bString)
+ rOldCell = new ScStringCell(sText);
+ else
+ rOldCell = new ScValueCell(fValue);
+ if (rType == NUMBERFORMAT_DATE || rType == NUMBERFORMAT_TIME)
+ rInputString = sText;
+ }
+ }
+ }
+ else
+ rOldCell = NULL;
+}
+
+ScXMLPreviousContext::ScXMLPreviousContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
+ pOldCell(NULL),
+ nID(0),
+ nMatrixCols(0),
+ nMatrixRows(0),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nType(NUMBERFORMAT_ALL),
+ nMatrixFlag(MM_NONE)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+}
+
+ScXMLPreviousContext::~ScXMLPreviousContext()
+{
+}
+
+SvXMLImportContext *ScXMLPreviousContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL)))
+ pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
+ pOldCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLPreviousContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetPreviousChange(nID, new ScMyCellInfo(pOldCell, sFormulaAddress, sFormula, eGrammar, sInputString,
+ fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows));
+}
+
+ScXMLContentChangeContext::ScXMLContentChangeContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_CONTENT);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLContentChangeContext::~ScXMLContentChangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentChangeContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
+ {
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange);
+ }
+ else if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ {
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_PREVIOUS))
+ {
+ pContext = new ScXMLPreviousContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLContentChangeContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetBigRange(aBigRange);
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLInsertionContext::ScXMLInsertionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nCount(1);
+ sal_Int32 nTable(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+ ScChangeActionType nActionType(SC_CAT_INSERT_COLS);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_ROW))
+ nActionType = SC_CAT_INSERT_ROWS;
+ else if (IsXMLToken(sValue, XML_TABLE))
+ nActionType = SC_CAT_INSERT_TABS;
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_COUNT))
+ {
+ SvXMLUnitConverter::convertNumber(nCount, sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(nActionType);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+ pChangeTrackingImportHelper->SetPosition(nPosition, nCount, nTable);
+}
+
+ScXMLInsertionContext::~ScXMLInsertionContext()
+{
+}
+
+SvXMLImportContext *ScXMLInsertionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLInsertionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLInsertionCutOffContext::ScXMLInsertionCutOffContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int32 nPosition(0);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ }
+ }
+ pChangeTrackingImportHelper->SetInsertionCutOff(nID, nPosition);
+}
+
+ScXMLInsertionCutOffContext::~ScXMLInsertionCutOffContext()
+{
+}
+
+SvXMLImportContext *ScXMLInsertionCutOffContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLInsertionCutOffContext::EndElement()
+{
+}
+
+ScXMLMovementCutOffContext::ScXMLMovementCutOffContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nID(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nStartPosition(0);
+ sal_Int32 nEndPosition(0);
+ sal_Bool bPosition(false);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nID = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ bPosition = sal_True;
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_START_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nStartPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_END_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nEndPosition, sValue);
+ }
+ }
+ }
+ if (bPosition)
+ nStartPosition = nEndPosition = nPosition;
+ pChangeTrackingImportHelper->AddMoveCutOff(nID, nStartPosition, nEndPosition);
+}
+
+ScXMLMovementCutOffContext::~ScXMLMovementCutOffContext()
+{
+}
+
+SvXMLImportContext *ScXMLMovementCutOffContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+}
+
+void ScXMLMovementCutOffContext::EndElement()
+{
+}
+
+ScXMLCutOffsContext::ScXMLCutOffsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ // here are no attributes
+}
+
+ScXMLCutOffsContext::~ScXMLCutOffsContext()
+{
+}
+
+SvXMLImportContext *ScXMLCutOffsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_INSERTION_CUT_OFF))
+ pContext = new ScXMLInsertionCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_MOVEMENT_CUT_OFF))
+ pContext = new ScXMLMovementCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLCutOffsContext::EndElement()
+{
+}
+
+ScXMLDeletionContext::ScXMLDeletionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ sal_Int32 nPosition(0);
+ sal_Int32 nMultiSpanned(0);
+ sal_Int32 nTable(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+ ScChangeActionType nActionType(SC_CAT_DELETE_COLS);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_ROW))
+ {
+ nActionType = SC_CAT_DELETE_ROWS;
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ nActionType = SC_CAT_DELETE_TABS;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_POSITION))
+ {
+ SvXMLUnitConverter::convertNumber(nPosition, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_TABLE))
+ {
+ SvXMLUnitConverter::convertNumber(nTable, sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_MULTI_DELETION_SPANNED))
+ {
+ SvXMLUnitConverter::convertNumber(nMultiSpanned, sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(nActionType);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+ pChangeTrackingImportHelper->SetPosition(nPosition, 1, nTable);
+ pChangeTrackingImportHelper->SetMultiSpanned(static_cast<sal_Int16>(nMultiSpanned));
+}
+
+ScXMLDeletionContext::~ScXMLDeletionContext()
+{
+}
+
+SvXMLImportContext *ScXMLDeletionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_CUT_OFFS) || rLocalName.equalsAsciiL("cut_offs", 8))
+ pContext = new ScXMLCutOffsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else
+ {
+ OSL_FAIL("don't know this");
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLDeletionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLMovementContext::ScXMLMovementContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLMovementContext::~ScXMLMovementContext()
+{
+}
+
+SvXMLImportContext *ScXMLMovementContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_SOURCE_RANGE_ADDRESS))
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aSourceRange);
+ else if (IsXMLToken(rLocalName, XML_TARGET_RANGE_ADDRESS))
+ pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aTargetRange);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLMovementContext::EndElement()
+{
+ pChangeTrackingImportHelper->SetMoveRanges(aSourceRange, aTargetRange);
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+ScXMLRejectionContext::ScXMLRejectionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pChangeTrackingImportHelper(pTempChangeTrackingImportHelper)
+{
+ sal_uInt32 nActionNumber(0);
+ sal_uInt32 nRejectingNumber(0);
+ ScChangeActionState nActionState(SC_CAS_VIRGIN);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_ID))
+ {
+ nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE))
+ {
+ if (IsXMLToken(sValue, XML_ACCEPTED))
+ nActionState = SC_CAS_ACCEPTED;
+ else if (IsXMLToken(sValue, XML_REJECTED))
+ nActionState = SC_CAS_REJECTED;
+ }
+ else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID))
+ {
+ nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue);
+ }
+ }
+ }
+
+ pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE);
+ pChangeTrackingImportHelper->SetActionNumber(nActionNumber);
+ pChangeTrackingImportHelper->SetActionState(nActionState);
+ pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber);
+}
+
+ScXMLRejectionContext::~ScXMLRejectionContext()
+{
+}
+
+SvXMLImportContext *ScXMLRejectionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO)))
+ {
+ pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ else if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLocalName, XML_DEPENDENCIES))
+ pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ else if (IsXMLToken(rLocalName, XML_DELETIONS))
+ pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLRejectionContext::EndElement()
+{
+ pChangeTrackingImportHelper->EndChangeAction();
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.hxx b/sc/source/filter/xml/XMLTrackedChangesContext.hxx
new file mode 100644
index 000000000000..853f7a1484c6
--- /dev/null
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLTRACKEDCHANGESCONTEXT_HXX
+#define SC_XMLTRACKEDCHANGESCONTEXT_HXX
+
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "chgtrack.hxx"
+#include <xmloff/xmlictxt.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+class ScXMLChangeTrackingImportHelper;
+class ScEditEngineTextObj;
+
+class ScXMLTrackedChangesContext : public SvXMLImportContext
+{
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLTrackedChangesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper);
+ virtual ~ScXMLTrackedChangesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/cachedattraccess.cxx b/sc/source/filter/xml/cachedattraccess.cxx
new file mode 100644
index 000000000000..31a0f215dad2
--- /dev/null
+++ b/sc/source/filter/xml/cachedattraccess.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Kohei Yoshida <kyoshida@novell.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "cachedattraccess.hxx"
+#include "document.hxx"
+
+ScXMLCachedRowAttrAccess::Cache::Cache() :
+ mnTab(-1), mnRow1(-1), mnRow2(-1), mbValue(false) {}
+
+bool ScXMLCachedRowAttrAccess::Cache::hasCache(sal_Int32 nTab, sal_Int32 nRow) const
+{
+ return mnTab == nTab && mnRow1 <= nRow && nRow <= mnRow2;
+}
+
+ScXMLCachedRowAttrAccess::ScXMLCachedRowAttrAccess(ScDocument* pDoc) :
+ mpDoc(pDoc) {}
+
+bool ScXMLCachedRowAttrAccess::rowHidden(sal_Int32 nTab, sal_Int32 nRow)
+{
+ if (!maHidden.hasCache(nTab, nRow))
+ {
+ SCROW nRow1, nRow2;
+ maHidden.mbValue = mpDoc->RowHidden(
+ static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), &nRow1, &nRow2);
+ maHidden.mnRow1 = static_cast<sal_Int32>(nRow1);
+ maHidden.mnRow2 = static_cast<sal_Int32>(nRow2);
+ }
+ return maHidden.mbValue;
+}
+
+bool ScXMLCachedRowAttrAccess::rowFiltered(sal_Int32 nTab, sal_Int32 nRow)
+{
+ if (!maFiltered.hasCache(nTab, nRow))
+ {
+ SCROW nRow1, nRow2;
+ maFiltered.mbValue = mpDoc->RowFiltered(
+ static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), &nRow1, &nRow2);
+ maFiltered.mnRow1 = static_cast<sal_Int32>(nRow1);
+ maFiltered.mnRow2 = static_cast<sal_Int32>(nRow2);
+ }
+ return maFiltered.mbValue;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/cachedattraccess.hxx b/sc/source/filter/xml/cachedattraccess.hxx
new file mode 100644
index 000000000000..2c31d36ed596
--- /dev/null
+++ b/sc/source/filter/xml/cachedattraccess.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * [ Kohei Yoshida <kyoshida@novell.com> ]
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef __SC_FILTER_XML_CACHEDATTRACCESS_HXX__
+#define __SC_FILTER_XML_CACHEDATTRACCESS_HXX__
+
+#include "sal/types.h"
+
+class ScDocument;
+
+/**
+ * Wrapper for accessing hidden and filtered row attributes. It caches last
+ * accessed values for a current range, to avoid fetching values for every
+ * single row.
+ */
+class ScXMLCachedRowAttrAccess
+{
+ struct Cache
+ {
+ sal_Int32 mnTab;
+ sal_Int32 mnRow1;
+ sal_Int32 mnRow2;
+ bool mbValue;
+ Cache();
+ bool hasCache(sal_Int32 nTab, sal_Int32 nRow) const;
+ };
+
+public:
+ ScXMLCachedRowAttrAccess(ScDocument* pDoc);
+
+ bool rowHidden(sal_Int32 nTab, sal_Int32 nRow);
+ bool rowFiltered(sal_Int32 nTab, sal_Int32 nRow);
+private:
+ Cache maHidden;
+ Cache maFiltered;
+ ScDocument* mpDoc;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx
new file mode 100644
index 000000000000..226d145508b5
--- /dev/null
+++ b/sc/source/filter/xml/sheetdata.cxx
@@ -0,0 +1,285 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <xmloff/families.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/string.hxx>
+#include <tools/debug.hxx>
+
+#include "sheetdata.hxx"
+
+// -----------------------------------------------------------------------
+
+ScSheetSaveData::ScSheetSaveData() :
+ mnStartTab( -1 ),
+ mnStartOffset( -1 ),
+ maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ),
+ mbInSupportedSave( false )
+{
+}
+
+ScSheetSaveData::~ScSheetSaveData()
+{
+}
+
+void ScSheetSaveData::AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maCellStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maColumnStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maRowStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maTableStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos )
+{
+ // only consecutive duplicates (most common case) are filtered out here,
+ // the others are found when the styles are created
+
+ if ( rStyleName == maPreviousNote.maStyleName &&
+ rTextName == maPreviousNote.maTextStyle &&
+ rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
+ {
+ // already stored for the same sheet - ignore
+ return;
+ }
+
+ ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
+ maPreviousNote = aNewEntry;
+ maNoteStyles.push_back( aNewEntry );
+}
+
+void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
+ maNoteParaStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+ else
+ maNoteTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ maTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::BlockSheet( sal_Int32 nTab )
+{
+ if ( nTab >= (sal_Int32)maBlocked.size() )
+ maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
+
+ maBlocked[nTab] = true;
+}
+
+bool ScSheetSaveData::IsSheetBlocked( sal_Int32 nTab ) const
+{
+ if ( nTab < (sal_Int32)maBlocked.size() )
+ return maBlocked[nTab];
+ else
+ return false;
+}
+
+void ScSheetSaveData::AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maStreamEntries.size() )
+ maStreamEntries.resize( nTab + 1 );
+
+ maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset )
+{
+ DBG_ASSERT( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
+
+ mnStartTab = nTab;
+ mnStartOffset = nStartOffset;
+}
+
+void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
+{
+ if ( mnStartTab >= 0 )
+ {
+ AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
+ mnStartTab = -1;
+ mnStartOffset = -1;
+ }
+}
+
+void ScSheetSaveData::GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
+{
+ if ( nTab < (sal_Int32)maStreamEntries.size() )
+ {
+ const ScStreamEntry& rEntry = maStreamEntries[nTab];
+ rStartOffset = rEntry.mnStartOffset;
+ rEndOffset = rEntry.mnEndOffset;
+ }
+ else
+ rStartOffset = rEndOffset = -1;
+}
+
+bool ScSheetSaveData::HasStreamPos( sal_Int32 nTab ) const
+{
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ GetStreamPos( nTab, nStartOffset, nEndOffset );
+ return ( nStartOffset >= 0 && nEndOffset >= 0 );
+}
+
+void ScSheetSaveData::ResetSaveEntries()
+{
+ maSaveEntries.clear();
+}
+
+void ScSheetSaveData::AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maSaveEntries.size() )
+ maSaveEntries.resize( nTab + 1 );
+
+ maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::UseSaveEntries()
+{
+ maStreamEntries = maSaveEntries;
+}
+
+void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // the initial namespaces are just removed from the list of loaded namespaces,
+ // so only a boost::unordered_map of the prefixes is needed.
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ maInitialPrefixes.insert( aIter->first );
+ ++aIter;
+ }
+}
+
+void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ // ignore the initial namespaces
+ if ( maInitialPrefixes.find( aIter->first ) == maInitialPrefixes.end() )
+ {
+ const NameSpaceEntry& rEntry = *(aIter->second);
+ maLoadedNamespaces.push_back( ScLoadedNamespaceEntry( rEntry.sPrefix, rEntry.sName, rEntry.nKey ) );
+ }
+ ++aIter;
+ }
+}
+
+bool lcl_NameInHash( const NameSpaceHash& rNameHash, const rtl::OUString& rName )
+{
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ if ( aIter->second->sName == rName )
+ return true;
+
+ ++aIter;
+ }
+ return false; // not found
+}
+
+bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
+{
+ // Add the loaded namespaces to the name space map.
+
+ // first loop: only look for conflicts
+ // (if the loaded namespaces were added first, this might not be necessary)
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aIter = maLoadedNamespaces.begin();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aEnd = maLoadedNamespaces.end();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ {
+ if ( lcl_NameInHash( rNameHash, aIter->maName ) )
+ {
+ // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
+ // so this is also considered a conflict
+ return false;
+ }
+ }
+ else if ( aHashIter->second->sName != aIter->maName )
+ {
+ // same prefix, but different name: loaded namespaces can't be used
+ return false;
+ }
+ ++aIter;
+ }
+
+ // only if there were no conflicts, add the entries that aren't in the map already
+ // (the key is needed if the same namespace is added later within an element)
+ aIter = maLoadedNamespaces.begin();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ rNamespaces.Add( aIter->maPrefix, aIter->maName, aIter->mnKey );
+ ++aIter;
+ }
+
+ return true; // success
+}
+
+bool ScSheetSaveData::IsInSupportedSave() const
+{
+ return mbInSupportedSave;
+}
+
+void ScSheetSaveData::SetInSupportedSave( bool bSet )
+{
+ mbInSupportedSave = bSet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx
new file mode 100644
index 000000000000..f38f442ef8bb
--- /dev/null
+++ b/sc/source/filter/xml/xmlannoi.cxx
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlannoi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLAnnotationData::ScXMLAnnotationData() :
+ mbUseShapePos( false ),
+ mbShown( false )
+{
+}
+
+ScXMLAnnotationData::~ScXMLAnnotationData()
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLAnnotationData& rAnnotationData,
+ ScXMLTableRowCellContext* pTempCellContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ mrAnnotationData( rAnnotationData ),
+ nParagraphCount(0),
+ bHasTextP(false),
+ pCellContext(pTempCellContext),
+ pShapeContext(NULL)
+{
+ uno::Reference<drawing::XShapes> xLocalShapes (GetScImport().GetTables().GetCurrentXShapes());
+ if (xLocalShapes.is())
+ {
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ pTableShapeImport->SetAnnotation(this);
+ pShapeContext = GetScImport().GetShapeImport()->CreateGroupChildContext(
+ GetScImport(), nPrfx, rLName, xAttrList, xLocalShapes, sal_True);
+ }
+
+ pCellContext = pTempCellContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAnnotationAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR:
+ {
+ maAuthorBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE:
+ {
+ maCreateDateBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING:
+ {
+ maCreateDateStringBuffer = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY:
+ {
+ mrAnnotationData.mbShown = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_X:
+ {
+ mrAnnotationData.mbUseShapePos = true;
+ }
+ break;
+ case XML_TOK_TABLE_ANNOTATION_ATTR_Y:
+ {
+ mrAnnotationData.mbUseShapePos = true;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLAnnotationContext::~ScXMLAnnotationContext()
+{
+}
+
+void ScXMLAnnotationContext::StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList)
+{
+ if (pShapeContext)
+ pShapeContext->StartElement(xAttrList);
+}
+
+SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( XML_NAMESPACE_DC == nPrefix )
+ {
+ if( IsXMLToken( rLName, XML_CREATOR ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maAuthorBuffer);
+ else if( IsXMLToken( rLName, XML_DATE ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maCreateDateBuffer);
+ }
+ else if( XML_NAMESPACE_META == nPrefix )
+ {
+ if( IsXMLToken( rLName, XML_DATE_STRING ) )
+ pContext = new ScXMLContentContext(GetScImport(), nPrefix,
+ rLName, xAttrList, maCreateDateStringBuffer);
+ }
+
+ if( !pContext && pShapeContext )
+ pContext = pShapeContext->CreateChildContext(nPrefix, rLName, xAttrList);
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLAnnotationContext::Characters( const ::rtl::OUString& rChars )
+{
+ if (!bHasTextP)
+ maTextBuffer.append(rChars);
+}
+
+void ScXMLAnnotationContext::EndElement()
+{
+ if (pShapeContext)
+ {
+ pShapeContext->EndElement();
+ delete pShapeContext;
+ pShapeContext = NULL;
+ }
+
+ mrAnnotationData.maAuthor = maAuthorBuffer.makeStringAndClear();
+ mrAnnotationData.maCreateDate = maCreateDateBuffer.makeStringAndClear();
+ if (!mrAnnotationData.maCreateDate.getLength())
+ mrAnnotationData.maCreateDate = maCreateDateStringBuffer.makeStringAndClear();
+ mrAnnotationData.maSimpleText = maTextBuffer.makeStringAndClear();
+
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ pTableShapeImport->SetAnnotation(NULL);
+}
+
+void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes,
+ const rtl::OUString& rStyleName, const rtl::OUString& rTextStyle )
+{
+ mrAnnotationData.mxShape = rxShape;
+ mrAnnotationData.mxShapes = rxShapes;
+ mrAnnotationData.maStyleName = rStyleName;
+ mrAnnotationData.maTextStyle = rTextStyle;
+}
+
+void ScXMLAnnotationContext::AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection )
+{
+ mrAnnotationData.maContentStyles.push_back( ScXMLAnnotationStyleEntry( nFamily, rName, rSelection ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx
new file mode 100644
index 000000000000..d343a715955c
--- /dev/null
+++ b/sc/source/filter/xml/xmlannoi.hxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLANNOI_HXX
+#define SC_XMLANNOI_HXX
+
+#include <memory>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <editeng/editdata.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+class ScXMLImport;
+class ScXMLTableRowCellContext;
+
+struct ScXMLAnnotationStyleEntry
+{
+ sal_uInt16 mnFamily;
+ rtl::OUString maName;
+ ESelection maSelection;
+
+ ScXMLAnnotationStyleEntry( sal_uInt16 nFam, const rtl::OUString& rNam, const ESelection& rSel ) :
+ mnFamily( nFam ),
+ maName( rNam ),
+ maSelection( rSel )
+ {
+ }
+};
+
+struct ScXMLAnnotationData
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ mxShape;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ mxShapes;
+ ::rtl::OUString maAuthor;
+ ::rtl::OUString maCreateDate;
+ ::rtl::OUString maSimpleText;
+ ::rtl::OUString maStyleName;
+ ::rtl::OUString maTextStyle;
+ bool mbUseShapePos;
+ bool mbShown;
+ std::vector<ScXMLAnnotationStyleEntry> maContentStyles;
+
+ explicit ScXMLAnnotationData();
+ ~ScXMLAnnotationData();
+};
+
+class ScXMLAnnotationContext : public SvXMLImportContext
+{
+public:
+
+ ScXMLAnnotationContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLAnnotationData& rAnnotationData,
+ ScXMLTableRowCellContext* pCellContext);
+
+ virtual ~ScXMLAnnotationContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+
+ void SetShape(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::rtl::OUString& rStyleName, const ::rtl::OUString& rTextStyle );
+
+ void AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection );
+
+private:
+ ScXMLAnnotationData& mrAnnotationData;
+ rtl::OUStringBuffer maTextBuffer;
+ rtl::OUStringBuffer maAuthorBuffer;
+ rtl::OUStringBuffer maCreateDateBuffer;
+ rtl::OUStringBuffer maCreateDateStringBuffer;
+ sal_Int32 nParagraphCount;
+ sal_Bool bHasTextP;
+ ScXMLTableRowCellContext* pCellContext;
+ SvXMLImportContext* pShapeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
new file mode 100644
index 000000000000..86bd2f60fc1e
--- /dev/null
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -0,0 +1,312 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <cstdio>
+
+#include "document.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+
+#include "xmlbodyi.hxx"
+#include "xmltabi.hxx"
+#include "xmlnexpi.hxx"
+#include "xmldrani.hxx"
+#include "xmlimprt.hxx"
+#include "xmldpimp.hxx"
+#include "xmlcvali.hxx"
+#include "xmlstyli.hxx"
+#include "xmllabri.hxx"
+#include "XMLConsolidationContext.hxx"
+#include "XMLDDELinksContext.hxx"
+#include "XMLCalculationSettingsContext.hxx"
+#include "XMLTrackedChangesContext.hxx"
+#include "XMLEmptyContext.hxx"
+#include "scerrors.hxx"
+#include "tabprotection.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <sal/types.h>
+#include <tools/debug.hxx>
+
+#include <memory>
+
+using rtl::OUString;
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sPassword(),
+ meHash1(PASSHASH_SHA1),
+ meHash2(PASSHASH_UNSPECIFIED),
+ bProtected(false),
+ bHadCalculationSettings(false),
+ pChangeTrackingImportHelper(NULL)
+{
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF;
+ // no version => earlier than 1.2 => GRAM_PODF.
+ formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
+ OUString aVer( rImport.GetODFVersion());
+ sal_Int32 nLen = aVer.getLength();
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n",
+ (int)nLen, OUStringToOString( aVer, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ if (!nLen)
+ eGrammar = formula::FormulaGrammar::GRAM_PODF;
+ else
+ {
+ // In case there was a micro version, e.g. "1.2.3", this would
+ // still yield major.minor, but pParsedEnd (5th parameter, not
+ // passed here) would point before string end upon return.
+ double fVer = ::rtl::math::stringToDouble( aVer, '.', 0, NULL, NULL);
+ if (fVer < 1.2)
+ eGrammar = formula::FormulaGrammar::GRAM_PODF;
+ }
+ pDoc->SetStorageGrammar( eGrammar);
+ }
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_STRUCTURE_PROTECTED))
+ bProtected = IsXMLToken(sValue, XML_TRUE);
+ else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
+ sPassword = sValue;
+ else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM))
+ meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
+ else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2))
+ meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
+ }
+ }
+}
+
+ScXMLBodyContext::~ScXMLBodyContext()
+{
+}
+
+SvXMLImportContext *ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the next child element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap();
+// sal_Bool bOrdered = sal_False;
+// sal_Bool bHeading = sal_False;
+ switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ {
+// case XML_TOK_TEXT_H:
+// bHeading = sal_True;
+// case XML_TOK_TEXT_P:
+// pContext = new SwXMLParaContext( GetSwImport(),nPrefix, rLocalName,
+// xAttrList, bHeading );
+// break;
+// case XML_TOK_TEXT_ORDERED_LIST:
+// bOrdered = sal_True;
+// case XML_TOK_TEXT_UNORDERED_LIST:
+// pContext = new SwXMLListBlockContext( GetSwImport(),nPrefix, rLocalName,
+// xAttrList, bOrdered );
+// break;
+ case XML_TOK_BODY_TRACKED_CHANGES :
+ {
+ pChangeTrackingImportHelper = GetScImport().GetChangeTrackingImportHelper();
+ if (pChangeTrackingImportHelper)
+ pContext = new ScXMLTrackedChangesContext( GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
+ }
+ break;
+ case XML_TOK_BODY_CALCULATION_SETTINGS :
+ pContext = new ScXMLCalculationSettingsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ bHadCalculationSettings = sal_True;
+ break;
+ case XML_TOK_BODY_CONTENT_VALIDATIONS :
+ pContext = new ScXMLContentValidationsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ case XML_TOK_BODY_LABEL_RANGES:
+ pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ case XML_TOK_BODY_TABLE:
+ {
+ if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB)
+ {
+ GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW);
+ pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLocalName);
+ }
+ else
+ {
+ pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName,
+ xAttrList );
+ }
+ }
+ break;
+ case XML_TOK_BODY_NAMED_EXPRESSIONS:
+ pContext = new ScXMLNamedExpressionsContext (
+ GetScImport(), nPrefix, rLocalName, xAttrList,
+ new ScXMLNamedExpressionsContext::GlobalInserter(GetScImport()) );
+ break;
+ case XML_TOK_BODY_DATABASE_RANGES:
+ pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DATABASE_RANGE:
+ pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DATA_PILOT_TABLES:
+ pContext = new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_CONSOLIDATION:
+ pContext = new ScXMLConsolidationContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_BODY_DDE_LINKS:
+ pContext = new ScXMLDDELinksContext ( GetScImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+void ScXMLBodyContext::Characters( const OUString& )
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before any content (whitespace) within the spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+ // otherwise ignore
+}
+
+void ScXMLBodyContext::EndElement()
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the closing tag of spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
+ if ( pSheetData )
+ {
+ // store the loaded namespaces (for the office:spreadsheet element),
+ // so the prefixes in copied stream fragments remain valid
+ const SvXMLNamespaceMap& rNamespaces = GetImport().GetNamespaceMap();
+ pSheetData->StoreLoadedNamespaces( rNamespaces );
+ }
+
+ if (!bHadCalculationSettings)
+ {
+ // #111055#; set calculation settings defaults if there is no calculation settings element
+ SvXMLImportContext *pContext = new ScXMLCalculationSettingsContext( GetScImport(), XML_NAMESPACE_TABLE, GetXMLToken(XML_CALCULATION_SETTINGS), NULL );
+ pContext->EndElement();
+ }
+
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+
+ ScMyImpDetectiveOpArray* pDetOpArray = GetScImport().GetDetectiveOpArray();
+ ScDocument* pDoc = GetScImport().GetDocument();
+ ScMyImpDetectiveOp aDetOp;
+
+ if (pDoc && GetScImport().GetModel().is())
+ {
+ if (pDetOpArray)
+ {
+ pDetOpArray->Sort();
+ while( pDetOpArray->GetFirstOp( aDetOp ) )
+ {
+ ScDetOpData aOpData( aDetOp.aPosition, aDetOp.eOpType );
+ pDoc->AddDetectiveOperation( aOpData );
+ }
+ }
+
+ if (pChangeTrackingImportHelper)
+ pChangeTrackingImportHelper->CreateChangeTrack(GetScImport().GetDocument());
+
+ // #i37959# handle document protection after the sheet settings
+ if (bProtected)
+ {
+ ::std::auto_ptr<ScDocProtection> pProtection(new ScDocProtection);
+ pProtection->setProtected(true);
+
+ uno::Sequence<sal_Int8> aPass;
+ if (sPassword.getLength())
+ {
+ SvXMLUnitConverter::decodeBase64(aPass, sPassword);
+ pProtection->setPasswordHash(aPass, meHash1, meHash2);
+ }
+
+ pDoc->SetDocProtection(pProtection.get());
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlbodyi.hxx b/sc/source/filter/xml/xmlbodyi.hxx
new file mode 100644
index 000000000000..61db1ae58924
--- /dev/null
+++ b/sc/source/filter/xml/xmlbodyi.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLBODYI_HXX
+#define SC_XMLBODYI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include "tabprotection.hxx"
+
+class ScXMLImport;
+class ScXMLChangeTrackingImportHelper;
+
+class ScXMLBodyContext : public SvXMLImportContext
+{
+ rtl::OUString sPassword;
+ ScPasswordHash meHash1;
+ ScPasswordHash meHash2;
+ sal_Bool bProtected;
+ sal_Bool bHadCalculationSettings;
+
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLBodyContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual ~ScXMLBodyContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+ virtual void Characters( const ::rtl::OUString& rChars );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
new file mode 100644
index 000000000000..a7755b840bca
--- /dev/null
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -0,0 +1,1132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlcelli.hxx"
+#include "xmlimprt.hxx"
+#include "xmltabi.hxx"
+#include "xmlstyli.hxx"
+#include "xmlannoi.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "cellsuno.hxx"
+#include "docuno.hxx"
+#include "unonames.hxx"
+#include "postit.hxx"
+#include "sheetdata.hxx"
+
+#include "XMLTableShapeImportHelper.hxx"
+#include "XMLTextPContext.hxx"
+#include "XMLStylesImportHelper.hxx"
+
+#include "arealink.hxx"
+#include <sfx2/linkmgr.hxx>
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "scerrors.hxx"
+#include "editutil.hxx"
+#include "cell.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <svx/unoapi.hxx>
+#include <svl/languageoptions.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <tools/date.hxx>
+#include <i18npool/lang.h>
+#include <comphelper/extract.hxx>
+
+#define SC_CURRENCYSYMBOL "CurrencySymbol"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+using rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsCovered,
+ const sal_Int32 nTempRepeatedRows ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pContentValidationName(NULL),
+ pDetectiveObjVec(NULL),
+ pCellRangeSource(NULL),
+ fValue(0.0),
+ nMergedRows(1),
+ nMergedCols(1),
+ nRepeatedRows(nTempRepeatedRows),
+ nCellsRepeated(1),
+ rXMLImport((ScXMLImport&)rImport),
+ eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
+ nCellType(util::NumberFormat::TEXT),
+ bIsMerged(false),
+ bIsMatrix(false),
+ bHasSubTable(false),
+ bIsCovered(bTempIsCovered),
+ bIsEmpty(sal_True),
+ bHasTextImport(false),
+ bIsFirstTextImport(false),
+ bSolarMutexLocked(false),
+ bFormulaTextResult(false)
+{
+ rXMLImport.SetRemoveLastChar(false);
+ rXMLImport.GetTables().AddColumn(bTempIsCovered);
+ const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ rtl::OUString aLocalName;
+ rtl::OUString* pStyleName = NULL;
+ rtl::OUString* pCurrencySymbol = NULL;
+ const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex(i), &aLocalName);
+
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
+ pStyleName = new rtl::OUString(sValue);
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
+ DBG_ASSERT(!pContentValidationName, "here should be only one Validation Name");
+ pContentValidationName = new rtl::OUString(sValue);
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
+ bIsMerged = sal_True;
+ nMergedRows = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
+ bIsMerged = sal_True;
+ nMergedCols = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
+ bIsMatrix = sal_True;
+ nMatrixCols = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
+ bIsMatrix = sal_True;
+ nMatrixRows = sValue.toInt32();
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
+ nCellsRepeated = std::max( sValue.toInt32(), (sal_Int32) 1 );
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
+ nCellType = GetScImport().GetCellType(sValue);
+ bIsEmpty = false;
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
+ bIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
+ {
+ if (sValue.getLength() && rXMLImport.SetNullDateOnUnitConverter())
+ {
+ rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
+ bIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ rXMLImport.GetMM100UnitConverter().convertTime(fValue, sValue);
+ bIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ DBG_ASSERT(!pOUTextValue, "here should be only one string value");
+ pOUTextValue.reset(sValue);
+ bIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ if ( IsXMLToken(sValue, XML_TRUE) )
+ fValue = 1.0;
+ else if ( IsXMLToken(sValue, XML_FALSE) )
+ fValue = 0.0;
+ else
+ rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
+ bIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
+ {
+ if (sValue.getLength())
+ {
+ DBG_ASSERT(!pOUFormula, "here should be only one formula");
+ rtl::OUString aFormula, aFormulaNmsp;
+ rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
+ pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
+ pCurrencySymbol = new rtl::OUString(sValue);
+ break;
+ default:
+ ;
+ }
+ }
+ if (pOUFormula)
+ {
+ if (nCellType == util::NumberFormat::TEXT)
+ bFormulaTextResult = sal_True;
+ nCellType = util::NumberFormat::UNDEFINED;
+ }
+ rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
+}
+
+ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
+{
+ if (pContentValidationName)
+ delete pContentValidationName;
+ if (pDetectiveObjVec)
+ delete pDetectiveObjVec;
+ if (pCellRangeSource)
+ delete pCellRangeSource;
+}
+
+void ScXMLTableRowCellContext::LockSolarMutex()
+{
+ if (!bSolarMutexLocked)
+ {
+ GetScImport().LockSolarMutex();
+ bSolarMutexLocked = sal_True;
+ }
+}
+
+void ScXMLTableRowCellContext::UnlockSolarMutex()
+{
+ if (bSolarMutexLocked)
+ {
+ GetScImport().UnlockSolarMutex();
+ bSolarMutexLocked = false;
+ }
+}
+
+void ScXMLTableRowCellContext::SetCursorOnTextImport(const rtl::OUString& rOUTempText)
+{
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (CellExists(aCellPos))
+ {
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if (xCellRange.is())
+ {
+ xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
+ if (xBaseCell.is())
+ {
+ xLockable.set(xBaseCell, uno::UNO_QUERY);
+ if (xLockable.is())
+ xLockable->addActionLock();
+ uno::Reference<text::XText> xText(xBaseCell, uno::UNO_QUERY);
+ if (xText.is())
+ {
+ uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
+ if (xTextCursor.is())
+ {
+ xTextCursor->setString(rOUTempText);
+ xTextCursor->gotoEnd(false);
+ rXMLImport.GetTextImport()->SetCursor(xTextCursor);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE("this method should only be called for a existing cell");
+ }
+}
+
+SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap();
+ sal_Bool bTextP(false);
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROW_CELL_P:
+ {
+ bIsEmpty = false;
+ bTextP = sal_True;
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) &&
+ !rXMLImport.GetTables().IsPartOfMatrix(aCellPos.Column, aCellPos.Row))
+ {
+ if (!bHasTextImport)
+ {
+ bIsFirstTextImport = sal_True;
+ bHasTextImport = sal_True;
+ pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
+ }
+ else
+ {
+ // com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (CellExists(aCellPos))
+ {
+ if (bIsFirstTextImport && !rXMLImport.GetRemoveLastChar())
+ {
+ if (pOUTextContent)
+ {
+ SetCursorOnTextImport(*pOUTextContent);
+ pOUTextContent.reset();
+ }
+ else
+ SetCursorOnTextImport(rtl::OUString());
+ rXMLImport.SetRemoveLastChar(sal_True);
+ uno::Reference < text::XTextCursor > xTextCursor(rXMLImport.GetTextImport()->GetCursor());
+ if (xTextCursor.is())
+ {
+ uno::Reference < text::XText > xText (xTextCursor->getText());
+ uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
+ if (xText.is() && xTextRange.is())
+ xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, false);
+ }
+ }
+ pContext = rXMLImport.GetTextImport()->CreateTextChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList);
+ bIsFirstTextImport = false;
+ }
+ }
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_TABLE:
+ {
+ const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ rtl::OUString aLocalName;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ sal_uInt16 nAttrPrefix = rXMLImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex( i ), &aLocalName );
+ if ( nAttrPrefix == XML_NAMESPACE_TABLE
+ && IsXMLToken(aLocalName, XML_IS_SUB_TABLE))
+ {
+ bHasSubTable = IsXMLToken(xAttrList->getValueByIndex( i ), XML_TRUE);
+ }
+ }
+ DBG_ASSERT(bHasSubTable, "it should be a subtable");
+ pContext = new ScXMLTableContext( rXMLImport , nPrefix,
+ rLName, xAttrList,
+ sal_True, nMergedCols);
+ nMergedCols = 1;
+ bIsMerged = false;
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
+ {
+ bIsEmpty = false;
+ DBG_ASSERT( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
+ mxAnnotationData.reset( new ScXMLAnnotationData );
+ pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
+ xAttrList, *mxAnnotationData, this);
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
+ {
+ bIsEmpty = false;
+ if (!pDetectiveObjVec)
+ pDetectiveObjVec = new ScMyImpDetectiveObjVec();
+ pContext = new ScXMLDetectiveContext(
+ rXMLImport, nPrefix, rLName, pDetectiveObjVec );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE:
+ {
+ bIsEmpty = false;
+ if (!pCellRangeSource)
+ pCellRangeSource = new ScMyImpCellRangeSource();
+ pContext = new ScXMLCellRangeSourceContext(
+ rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource );
+ }
+ break;
+ }
+
+ if (!pContext && !bTextP)
+ {
+ com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
+ if (xShapes.is())
+ {
+ if (aCellPos.Column > MAXCOL)
+ aCellPos.Column = MAXCOL;
+ if (aCellPos.Row > MAXROW)
+ aCellPos.Row = MAXROW;
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get();
+ pTableShapeImport->SetOnTable(false);
+ pTableShapeImport->SetCell(aCellPos);
+ pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
+ rXMLImport, nPrefix, rLName, xAttrList, xShapes);
+ if (pContext)
+ {
+ bIsEmpty = false;
+ rXMLImport.ProgressBarIncrement(false);
+ }
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+sal_Bool ScXMLTableRowCellContext::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
+ table::CellRangeAddress& aCellAddress) const
+{
+ table::CellAddress aCell; // don't need to set the sheet, because every sheet can contain the same count of cells.
+ aCell.Column = nCol;
+ aCell.Row = nRow;
+ if (CellExists(aCell))
+ {
+ uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
+ uno::Reference<sheet::XSpreadsheet> xTable (xMergeSheetCellRange->getSpreadsheet());
+ uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor (xTable->createCursorByRange(xMergeSheetCellRange));
+ if (xMergeSheetCursor.is())
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
+ if (xMergeCellAddress.is())
+ {
+ aCellAddress = xMergeCellAddress->getRangeAddress();
+ if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
+ aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
+ return false;
+ else
+ return sal_True;
+ }
+ }
+ }
+ return false;
+}
+
+void ScXMLTableRowCellContext::DoMerge(const com::sun::star::table::CellAddress& aCellPos,
+ const sal_Int32 nCols, const sal_Int32 nRows)
+{
+ if (CellExists(aCellPos))
+ {
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if ( xCellRange.is() )
+ {
+ // Stored merge range may actually be of a larger extend than what
+ // we support, in which case getCellRangeByPosition() throws
+ // IndexOutOfBoundsException. Do nothing then.
+ try
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCellRange, aCellPos.Column, aCellPos.Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(false);
+ }
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn + nCols, aCellAddress.EndRow + nRows), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ }
+ catch ( lang::IndexOutOfBoundsException & )
+ {
+ DBG_ERRORFILE("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support");
+ }
+ }
+ }
+}
+
+void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet)
+{
+ if (pContentValidationName)
+ {
+ ScMyImportValidation aValidation;
+ aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
+ if (rXMLImport.GetValidation(*pContentValidationName, aValidation))
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML))), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (aValidation.sErrorMessage.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)), uno::makeAny(aValidation.sErrorMessage));
+ if (aValidation.sErrorTitle.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)), uno::makeAny(aValidation.sErrorTitle));
+ if (aValidation.sImputMessage.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)), uno::makeAny(aValidation.sImputMessage));
+ if (aValidation.sImputTitle.getLength())
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)), uno::makeAny(aValidation.sImputTitle));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)), uno::makeAny(aValidation.bShowErrorMessage));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)), uno::makeAny(aValidation.bShowImputMessage));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), uno::makeAny(aValidation.aValidationType));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)), uno::makeAny(aValidation.bIgnoreBlanks));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)), uno::makeAny(aValidation.nShowList));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)), uno::makeAny(aValidation.aAlertStyle));
+ uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
+ if (xCondition.is())
+ {
+ xCondition->setFormula1(aValidation.sFormula1);
+ xCondition->setFormula2(aValidation.sFormula2);
+ xCondition->setOperator(aValidation.aOperator);
+ // source position must be set as string, because it may
+ // refer to a sheet that hasn't been loaded yet.
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR)), uno::makeAny(aValidation.sBaseCellAddress));
+ // Transport grammar and formula namespace
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP1)), uno::makeAny(aValidation.sFormulaNmsp1));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP2)), uno::makeAny(aValidation.sFormulaNmsp2));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR1)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar1)));
+ xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR2)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar2)));
+ }
+ }
+ xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet));
+
+ // For now, any sheet with validity is blocked from stream-copying.
+ // Later, the validation names could be stored along with the style names.
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
+ }
+ }
+}
+
+void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCellRange>& xCellRange,
+ const table::CellAddress& aCellAddress)
+{
+ if (CellExists(aCellAddress) && pContentValidationName && pContentValidationName->getLength())
+ {
+ sal_Int32 nBottom = aCellAddress.Row + nRepeatedRows - 1;
+ sal_Int32 nRight = aCellAddress.Column + nCellsRepeated - 1;
+ if (nBottom > MAXROW)
+ nBottom = MAXROW;
+ if (nRight > MAXCOL)
+ nRight = MAXCOL;
+ uno::Reference <beans::XPropertySet> xProperties (xCellRange->getCellRangeByPosition(aCellAddress.Column, aCellAddress.Row,
+ nRight, nBottom), uno::UNO_QUERY);
+ if (xProperties.is())
+ SetContentValidation(xProperties);
+ }
+}
+
+void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCell>& xCell)
+{
+ if (pContentValidationName && pContentValidationName->getLength())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xCell, uno::UNO_QUERY);
+ if (xProperties.is())
+ SetContentValidation(xProperties);
+ }
+}
+
+void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress)
+{
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if( !pDoc || !mxAnnotationData.get() )
+ return;
+
+ LockSolarMutex();
+
+ ScAddress aPos;
+ ScUnoConversion::FillScAddress( aPos, aCellAddress );
+ ScPostIt* pNote = 0;
+
+ uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
+ uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
+ sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
+
+ DBG_ASSERT( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
+ "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
+ if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
+ {
+ DBG_ASSERT( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
+ SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
+ DBG_ASSERT( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
+
+ /* Try to reuse the drawing object already created (but only if the
+ note is visible, and the object is a caption object). */
+ if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
+ {
+ if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+ {
+ OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
+ // create the cell note with the caption object
+ pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, aPos, *pCaption, true );
+ // forget pointer to object (do not create note again below)
+ pObject = 0;
+ }
+ }
+
+ // drawing object has not been used to create a note -> use shape data
+ if( pObject )
+ {
+ // rescue settings from drawing object before the shape is removed
+ ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
+ ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
+ if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
+ xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
+ Rectangle aCaptionRect;
+ if( mxAnnotationData->mbUseShapePos )
+ aCaptionRect = pObject->GetLogicRect();
+ // remove the shape from the drawing page, this invalidates pObject
+ mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
+ pObject = 0;
+ // update current number of existing objects
+ if( xShapesIA.is() )
+ nOldShapeCount = xShapesIA->getCount();
+
+ // an outliner object is required (empty note captions not allowed)
+ if( xOutlinerObj.get() )
+ {
+ // create cell note with all data from drawing object
+ pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, aPos,
+ xItemSet.release(), xOutlinerObj.release(),
+ aCaptionRect, mxAnnotationData->mbShown, false );
+ }
+ }
+ }
+ else if( mxAnnotationData->maSimpleText.getLength() > 0 )
+ {
+ // create note from simple text
+ pNote = ScNoteUtil::CreateNoteFromString( *pDoc, aPos,
+ mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
+ }
+
+ // set author and date
+ if( pNote )
+ {
+ double fDate;
+ rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
+ SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
+ sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
+ String aDate;
+ Color* pColor = 0;
+ Color** ppColor = &pColor;
+ pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
+ pNote->SetDate( aDate );
+ pNote->SetAuthor( mxAnnotationData->maAuthor );
+ }
+
+ // register a shape that has been newly created in the ScNoteUtil functions
+ if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
+ {
+ uno::Reference< drawing::XShape > xShape;
+ rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
+ }
+
+ // store the style names for stream copying
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, aPos );
+
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
+ while (aIter != aEnd)
+ {
+ pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, aPos, aIter->maSelection );
+ ++aIter;
+ }
+}
+
+// core implementation
+void ScXMLTableRowCellContext::SetDetectiveObj( const table::CellAddress& rPosition )
+{
+ if( CellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() )
+ {
+ LockSolarMutex();
+ ScDetectiveFunc aDetFunc( rXMLImport.GetDocument(), rPosition.Sheet );
+ uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
+ ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin());
+ ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end());
+ while(aItr != aEndItr)
+ {
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rPosition );
+ aDetFunc.InsertObject( aItr->eObjType, aScAddress, aItr->aSourceRange, aItr->bHasError );
+ if (xShapesIndex.is())
+ {
+ sal_Int32 nShapes = xShapesIndex->getCount();
+ uno::Reference < drawing::XShape > xShape;
+ rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
+ }
+ ++aItr;
+ }
+ }
+}
+
+// core implementation
+void ScXMLTableRowCellContext::SetCellRangeSource( const table::CellAddress& rPosition )
+{
+ if( CellExists(rPosition) && pCellRangeSource && pCellRangeSource->sSourceStr.getLength() &&
+ pCellRangeSource->sFilterName.getLength() && pCellRangeSource->sURL.getLength() )
+ {
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if (pDoc)
+ {
+ LockSolarMutex();
+ ScRange aDestRange( static_cast<SCCOL>(rPosition.Column), static_cast<SCROW>(rPosition.Row), rPosition.Sheet,
+ static_cast<SCCOL>(rPosition.Column + pCellRangeSource->nColumns - 1),
+ static_cast<SCROW>(rPosition.Row + pCellRangeSource->nRows - 1), rPosition.Sheet );
+ String sFilterName( pCellRangeSource->sFilterName );
+ String sSourceStr( pCellRangeSource->sSourceStr );
+ ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
+ sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr );
+ }
+ }
+}
+
+bool lcl_IsEmptyOrNote( ScDocument* pDoc, const table::CellAddress& rCurrentPos )
+{
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rCurrentPos );
+ ScBaseCell* pCell = pDoc->GetCell( aScAddress );
+ return ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE );
+}
+
+void ScXMLTableRowCellContext::EndElement()
+{
+ if (!bHasSubTable)
+ {
+ if (bHasTextImport && rXMLImport.GetRemoveLastChar())
+ {
+ if (rXMLImport.GetTextImport()->GetCursor().is())
+ {
+ //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
+ if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
+ {
+ GetImport().GetTextImport()->GetText()->insertString(
+ GetImport().GetTextImport()->GetCursorAsRange(), rtl::OUString(),
+ sal_True );
+ }
+ rXMLImport.GetTextImport()->ResetCursor();
+ }
+ }
+ table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
+ if (aCellPos.Column > 0 && nRepeatedRows > 1)
+ aCellPos.Row -= (nRepeatedRows - 1);
+ uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
+ if (xCellRange.is())
+ {
+ if (bIsMerged)
+ DoMerge(aCellPos, nMergedCols - 1, nMergedRows - 1);
+ if ( !pOUFormula )
+ {
+ ::boost::optional< rtl::OUString > pOUText;
+
+ if(nCellType == util::NumberFormat::TEXT)
+ {
+ if (xLockable.is())
+ xLockable->removeActionLock();
+
+ // #i61702# The formatted text content of xBaseCell / xLockable is invalidated,
+ // so it can't be used after calling removeActionLock (getString always uses the document).
+
+ if (CellExists(aCellPos) && ((nCellsRepeated > 1) || (nRepeatedRows > 1)))
+ {
+ if (!xBaseCell.is())
+ {
+ try
+ {
+ xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ DBG_ERRORFILE("It seems here are to many columns or rows");
+ }
+ }
+ uno::Reference <text::XText> xTempText (xBaseCell, uno::UNO_QUERY);
+ if (xTempText.is())
+ {
+ pOUText.reset(xTempText->getString());
+ }
+ }
+ if ( (!pOUTextContent && !pOUText && !pOUTextValue)
+ && ( (pOUTextContent && !pOUTextContent->getLength()) || !pOUTextContent )
+ && ( (pOUText && !pOUText->getLength()) || !pOUText )
+ && ( (pOUTextValue && !pOUTextValue->getLength()) || !pOUTextValue ))
+ bIsEmpty = sal_True;
+ }
+ sal_Bool bWasEmpty = bIsEmpty;
+// uno::Reference <table::XCell> xCell;
+ table::CellAddress aCurrentPos( aCellPos );
+ if ((pContentValidationName && pContentValidationName->getLength()) ||
+ mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource)
+ bIsEmpty = false;
+
+ ScMyTables& rTables = rXMLImport.GetTables();
+ for (sal_Int32 i = 0; i < nCellsRepeated; ++i)
+ {
+ aCurrentPos.Column = aCellPos.Column + i;
+ if (i > 0)
+ rTables.AddColumn(false);
+ if (!bIsEmpty)
+ {
+ for (sal_Int32 j = 0; j < nRepeatedRows; ++j)
+ {
+ aCurrentPos.Row = aCellPos.Row + j;
+ if ((aCurrentPos.Column == 0) && (j > 0))
+ {
+ rTables.AddRow();
+ rTables.AddColumn(false);
+ }
+ if (CellExists(aCurrentPos))
+ {
+ // test - bypass the API
+ // if (xBaseCell.is() && (aCurrentPos == aCellPos))
+ // xCell.set(xBaseCell);
+ // else
+ // {
+ // try
+ // {
+ // xCell.set(xCellRange->getCellByPosition(aCurrentPos.Column, aCurrentPos.Row));
+ // }
+ // catch (lang::IndexOutOfBoundsException&)
+ // {
+ // DBG_ERRORFILE("It seems here are to many columns or rows");
+ // }
+ // }
+
+ // test - bypass the API
+ // if ((!(bIsCovered) || (xCell->getType() == table::CellContentType_EMPTY)))
+ if ((!(bIsCovered) || lcl_IsEmptyOrNote( rXMLImport.GetDocument(), aCurrentPos )))
+ {
+ switch (nCellType)
+ {
+ case util::NumberFormat::TEXT:
+ {
+ sal_Bool bDoIncrement = sal_True;
+ if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
+ {
+ LockSolarMutex();
+ // test - bypass the API
+ // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
+ // if (pCellObj)
+ // {
+ // if(pOUTextValue && pOUTextValue->getLength())
+ // pCellObj->SetFormulaResultString(*pOUTextValue);
+ // else if (pOUTextContent && pOUTextContent->getLength())
+ // pCellObj->SetFormulaResultString(*pOUTextContent);
+ // else if ( i > 0 && pOUText && pOUText->getLength() )
+ // {
+ // pCellObj->SetFormulaResultString(*pOUText);
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
+ bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA );
+ if ( bDoIncrement )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pOUTextValue && pOUTextValue->getLength())
+ pFCell->SetHybridString( *pOUTextValue );
+ else if (pOUTextContent && pOUTextContent->getLength())
+ pFCell->SetHybridString( *pOUTextContent );
+ else if ( i > 0 && pOUText && pOUText->getLength() )
+ pFCell->SetHybridString( *pOUText );
+ else
+ bDoIncrement = false;
+ }
+ }
+ else
+ {
+ // test - bypass the API
+ // uno::Reference <text::XText> xText (xCell, uno::UNO_QUERY);
+ // if (xText.is())
+ // {
+ // if(pOUTextValue && pOUTextValue->getLength())
+ // xText->setString(*pOUTextValue);
+ // else if (pOUTextContent && pOUTextContent->getLength())
+ // xText->setString(*pOUTextContent);
+ // else if ( i > 0 && pOUText && pOUText->getLength() )
+ // {
+ // xText->setString(*pOUText);
+ // }
+ // else
+ // bDoIncrement = sal_False;
+ // }
+ LockSolarMutex();
+ ScBaseCell* pNewCell = NULL;
+ ScDocument* pDoc = rXMLImport.GetDocument();
+ if (pOUTextValue && pOUTextValue->getLength())
+ pNewCell = ScBaseCell::CreateTextCell( *pOUTextValue, pDoc );
+ else if (pOUTextContent && pOUTextContent->getLength())
+ pNewCell = ScBaseCell::CreateTextCell( *pOUTextContent, pDoc );
+ else if ( i > 0 && pOUText && pOUText->getLength() )
+ pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc );
+
+ bDoIncrement = pNewCell != NULL;
+ if ( bDoIncrement )
+ {
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ pDoc->PutCell( aScAddress, pNewCell );
+ }
+ }
+ // #i56027# This is about setting simple text, not edit cells,
+ // so ProgressBarIncrement must be called with bEditCell = FALSE.
+ // Formatted text that is put into the cell by the child context
+ // is handled below (bIsEmpty is sal_True then).
+ if (bDoIncrement || bHasTextImport)
+ rXMLImport.ProgressBarIncrement(false);
+ }
+ break;
+ case util::NumberFormat::NUMBER:
+ case util::NumberFormat::PERCENT:
+ case util::NumberFormat::CURRENCY:
+ case util::NumberFormat::TIME:
+ case util::NumberFormat::DATETIME:
+ case util::NumberFormat::LOGICAL:
+ {
+ if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
+ {
+ LockSolarMutex();
+ // test - bypass the API
+ // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
+ // if (pCellObj)
+ // pCellObj->SetFormulaResultDouble(fValue);
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
+ ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ static_cast<ScFormulaCell*>(pCell)->SetHybridDouble( fValue );
+ }
+ else
+ {
+ // test - bypass the API
+ // xCell->setValue(fValue);
+ LockSolarMutex();
+
+ // #i62435# Initialize the value cell's script type
+ // if the default style's number format is latin-only.
+ // If the cell uses a different format, the script type
+ // will be reset when the style is applied.
+
+ ScBaseCell* pNewCell = new ScValueCell(fValue);
+ if ( rXMLImport.IsLatinDefaultStyle() )
+ pNewCell->SetScriptType( SCRIPTTYPE_LATIN );
+ rXMLImport.GetDocument()->PutCell(
+ sal::static_int_cast<SCCOL>( aCurrentPos.Column ),
+ sal::static_int_cast<SCROW>( aCurrentPos.Row ),
+ sal::static_int_cast<SCTAB>( aCurrentPos.Sheet ),
+ pNewCell );
+ }
+ rXMLImport.ProgressBarIncrement(false);
+ }
+ break;
+ default:
+ {
+ OSL_FAIL("no cell type given");
+ }
+ break;
+ }
+ }
+
+ SetAnnotation(aCurrentPos);
+ SetDetectiveObj( aCurrentPos );
+ SetCellRangeSource( aCurrentPos );
+ }
+ else
+ {
+ if (!bWasEmpty || mxAnnotationData.get())
+ {
+ if (aCurrentPos.Row > MAXROW)
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
+ else
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
+ }
+ }
+ }
+ }
+ else
+ {
+ // #i56027# If the child context put formatted text into the cell,
+ // bIsEmpty is sal_True and ProgressBarIncrement has to be called
+ // with bEditCell = TRUE.
+ if (bHasTextImport)
+ rXMLImport.ProgressBarIncrement(sal_True);
+ if ((i == 0) && (aCellPos.Column == 0))
+ for (sal_Int32 j = 1; j < nRepeatedRows; ++j)
+ {
+ rTables.AddRow();
+ rTables.AddColumn(false);
+ }
+ }
+ }
+ if (nCellsRepeated > 1 || nRepeatedRows > 1)
+ {
+ SetCellProperties(xCellRange, aCellPos); // set now only the validation for the complete range with the given cell as start cell
+ //SetType(xCellRange, aCellPos);
+ SCCOL nStartCol(aCellPos.Column < MAXCOL ? static_cast<SCCOL>(aCellPos.Column) : MAXCOL);
+ SCROW nStartRow(aCellPos.Row < MAXROW ? static_cast<SCROW>(aCellPos.Row) : MAXROW);
+ SCCOL nEndCol(aCellPos.Column + nCellsRepeated - 1 < MAXCOL ? static_cast<SCCOL>(aCellPos.Column + nCellsRepeated - 1) : MAXCOL);
+ SCROW nEndRow(aCellPos.Row + nRepeatedRows - 1 < MAXROW ? static_cast<SCROW>(aCellPos.Row + nRepeatedRows - 1) : MAXROW);
+ ScRange aScRange( nStartCol, nStartRow, aCellPos.Sheet,
+ nEndCol, nEndRow, aCellPos.Sheet );
+ rXMLImport.GetStylesImportHelper()->AddRange(aScRange);
+ }
+ else if (CellExists(aCellPos))
+ {
+ rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
+
+ // test - bypass the API
+ // SetCellProperties(xCell); // set now only the validation
+ SetCellProperties(xCellRange, aCellPos);
+
+ //SetType(xTempCell);
+ }
+ }
+ else // if ( !pOUFormula )
+ {
+ if (CellExists(aCellPos))
+ {
+ uno::Reference <table::XCell> xCell;
+ try
+ {
+ xCell.set(xCellRange->getCellByPosition(aCellPos.Column , aCellPos.Row));
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ DBG_ERRORFILE("It seems here are to many columns or rows");
+ }
+ if (xCell.is())
+ {
+ SetCellProperties(xCell); // set now only the validation
+ DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
+ rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
+ if (!bIsMatrix)
+ {
+ LockSolarMutex();
+ ScCellObj* pCellObj =
+ static_cast<ScCellObj*>(ScCellRangesBase::getImplementation(
+ xCell));
+ if (pCellObj)
+ {
+ pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar);
+ if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength())
+ pCellObj->SetFormulaResultString( *pOUTextValue);
+ else
+ pCellObj->SetFormulaResultDouble( fValue);
+ }
+ }
+ else
+ {
+ if (nMatrixCols > 0 && nMatrixRows > 0)
+ {
+ rXMLImport.GetTables().AddMatrixRange(
+ aCellPos.Column, aCellPos.Row,
+ aCellPos.Column + nMatrixCols - 1,
+ aCellPos.Row + nMatrixRows - 1,
+ pOUFormula->first, pOUFormula->second, eGrammar);
+ }
+ }
+ SetAnnotation( aCellPos );
+ SetDetectiveObj( aCellPos );
+ SetCellRangeSource( aCellPos );
+ rXMLImport.ProgressBarIncrement(false);
+ }
+ }
+ else
+ {
+ if (aCellPos.Row > MAXROW)
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
+ else
+ rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
+ }
+
+ } // if ( !pOUFormula )
+ }
+ UnlockSolarMutex();
+ }
+ bIsMerged = false;
+ bHasSubTable = false;
+ nMergedCols = 1;
+ nMergedRows = 1;
+ nCellsRepeated = 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
new file mode 100644
index 000000000000..53387ebc5c14
--- /dev/null
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCELLI_HXX
+#define SC_XMLCELLI_HXX
+
+#include <memory>
+#include "XMLDetectiveContext.hxx"
+#include "XMLCellRangeSourceContext.hxx"
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/XCell.hpp>
+#include <tools/time.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+
+#include "formula/grammar.hxx"
+#include <boost/optional.hpp>
+
+class ScXMLImport;
+struct ScXMLAnnotationData;
+
+class ScXMLTableRowCellContext : public SvXMLImportContext
+{
+ typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > FormulaWithNamespace;
+ com::sun::star::uno::Reference<com::sun::star::table::XCell> xBaseCell;
+ com::sun::star::uno::Reference<com::sun::star::document::XActionLockable> xLockable;
+ ::boost::optional< rtl::OUString > pOUTextValue;
+ ::boost::optional< rtl::OUString > pOUTextContent;
+ ::boost::optional< FormulaWithNamespace > pOUFormula;
+ rtl::OUString* pContentValidationName;
+ ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData;
+ ScMyImpDetectiveObjVec* pDetectiveObjVec;
+ ScMyImpCellRangeSource* pCellRangeSource;
+ double fValue;
+ sal_Int32 nMergedRows, nMergedCols;
+ sal_Int32 nMatrixRows, nMatrixCols;
+ sal_Int32 nRepeatedRows;
+ sal_Int32 nCellsRepeated;
+ ScXMLImport& rXMLImport;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_Int16 nCellType;
+ sal_Bool bIsMerged;
+ sal_Bool bIsMatrix;
+ sal_Bool bHasSubTable;
+ sal_Bool bIsCovered;
+ sal_Bool bIsEmpty;
+ sal_Bool bHasTextImport;
+ sal_Bool bIsFirstTextImport;
+ sal_Bool bSolarMutexLocked;
+ sal_Bool bFormulaTextResult;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ sal_Int16 GetCellType(const rtl::OUString& sOUValue) const;
+
+ sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange,
+ const sal_Int32 nCol, const sal_Int32 nRow,
+ com::sun::star::table::CellRangeAddress& aCellAddress) const;
+ void DoMerge(const com::sun::star::table::CellAddress& aCellPos,
+ const sal_Int32 nCols, const sal_Int32 nRows);
+
+ void SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet);
+ void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCellRange>& xCellRange,
+ const com::sun::star::table::CellAddress& aCellAddress);
+ void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell);
+
+ void LockSolarMutex();
+ void UnlockSolarMutex();
+
+ sal_Bool CellExists(const com::sun::star::table::CellAddress& aCellPos) const
+ {
+ return (aCellPos.Column <= MAXCOL && aCellPos.Row <= MAXROW);
+ }
+
+public:
+
+ ScXMLTableRowCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bIsCovered, const sal_Int32 nRepeatedRows );
+
+ virtual ~ScXMLTableRowCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ inline void SetString(const rtl::OUString& rOUTempText) { pOUTextContent.reset(rOUTempText); }
+ void SetCursorOnTextImport(const rtl::OUString& rOUTempText);
+
+ void SetAnnotation(const ::com::sun::star::table::CellAddress& rPosition );
+ void SetDetectiveObj( const ::com::sun::star::table::CellAddress& rPosition );
+ void SetCellRangeSource( const ::com::sun::star::table::CellAddress& rPosition );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcoli.cxx b/sc/source/filter/xml/xmlcoli.cxx
new file mode 100644
index 000000000000..9029d5a63a0d
--- /dev/null
+++ b/sc/source/filter/xml/xmlcoli.cxx
@@ -0,0 +1,312 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include "xmlcoli.hxx"
+#include "xmlimprt.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "sheetdata.hxx"
+#include "unonames.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableColContext::ScXMLTableColContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sVisibility(GetXMLToken(XML_VISIBLE))
+{
+ nColCount = 1;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableColAttrTokenMap();
+
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_COL_ATTR_REPEATED:
+ {
+ nColCount = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_STYLE_NAME:
+ {
+ sStyleName = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_VISIBILITY:
+ {
+ sVisibility = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME:
+ {
+ sCellStyleName = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLTableColContext::~ScXMLTableColContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableColContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableColContext::EndElement()
+{
+ ScXMLImport& rXMLImport = GetScImport();
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColumn();
+ uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
+ if(xSheet.is())
+ {
+ sal_Int32 nLastColumn(nCurrentColumn + nColCount - 1);
+ if (nLastColumn > MAXCOL)
+ nLastColumn = MAXCOL;
+ if (nCurrentColumn > MAXCOL)
+ nCurrentColumn = MAXCOL;
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xColumnProperties(xColumnRowRange->getColumns(), uno::UNO_QUERY);
+ if (xColumnProperties.is())
+ {
+ if (sStyleName.getLength())
+ {
+ XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rXMLImport.GetAutoStyles();
+ if ( pStyles )
+ {
+ XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_COLUMN, sStyleName, sal_True);
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xColumnProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddColumnStyle( sStyleName, ScAddress( (SCCOL)nCurrentColumn, 0, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
+ }
+ }
+ rtl::OUString sVisible(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLVIS));
+ sal_Bool bValue(sal_True);
+ if (!IsXMLToken(sVisibility, XML_VISIBLE))
+ bValue = false;
+ xColumnProperties->setPropertyValue(sVisible, uno::makeAny(bValue));
+ }
+ }
+ }
+
+ // #i57915# ScXMLImport::SetStyleToRange can't handle empty style names.
+ // The default for a column if there is no attribute is the style "Default" (programmatic API name).
+ if ( !sCellStyleName.getLength() )
+ sCellStyleName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Default" ));
+
+ GetScImport().GetTables().AddColCount(nColCount);
+ GetScImport().GetTables().AddColStyle(nColCount, sCellStyleName);
+}
+
+ScXMLTableColsContext::ScXMLTableColsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempHeader, const sal_Bool bTempGroup) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nHeaderStartCol(0),
+ nHeaderEndCol(0),
+ nGroupStartCol(0),
+ nGroupEndCol(0),
+ bHeader(bTempHeader),
+ bGroup(bTempGroup),
+ bGroupDisplay(sal_True)
+{
+ // don't have any attributes
+ if (bHeader)
+ nHeaderStartCol = rImport.GetTables().GetCurrentColumn();
+ else if (bGroup)
+ {
+ nGroupStartCol = rImport.GetTables().GetCurrentColumn();
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DISPLAY))
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bGroupDisplay = false;
+ }
+ }
+ }
+}
+
+ScXMLTableColsContext::~ScXMLTableColsContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableColsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetTableColsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_COLS_COL_GROUP:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, sal_True );
+ break;
+ case XML_TOK_TABLE_COLS_HEADER_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, false );
+ break;
+ case XML_TOK_TABLE_COLS_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, false );
+ break;
+ case XML_TOK_TABLE_COLS_COL:
+ pContext = new ScXMLTableColContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableColsContext::EndElement()
+{
+ ScXMLImport& rXMLImport = GetScImport();
+ if (bHeader)
+ {
+ nHeaderEndCol = rXMLImport.GetTables().GetCurrentColumn();
+ nHeaderEndCol--;
+ if (nHeaderStartCol <= nHeaderEndCol)
+ {
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ if (!xPrintAreas->getPrintTitleColumns())
+ {
+ xPrintAreas->setPrintTitleColumns(sal_True);
+ table::CellRangeAddress aColumnHeaderRange;
+ aColumnHeaderRange.StartColumn = nHeaderStartCol;
+ aColumnHeaderRange.EndColumn = nHeaderEndCol;
+ xPrintAreas->setTitleColumns(aColumnHeaderRange);
+ }
+ else
+ {
+ table::CellRangeAddress aColumnHeaderRange(xPrintAreas->getTitleColumns());
+ aColumnHeaderRange.EndColumn = nHeaderEndCol;
+ xPrintAreas->setTitleColumns(aColumnHeaderRange);
+ }
+ }
+ }
+ }
+ else if (bGroup)
+ {
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ nGroupEndCol = rXMLImport.GetTables().GetCurrentColumn();
+ nGroupEndCol--;
+ if (nGroupStartCol <= nGroupEndCol)
+ {
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True);
+ ScOutlineArray* pColArray = pOutlineTable ? pOutlineTable->GetColArray() : NULL;
+ if (pColArray)
+ {
+ sal_Bool bResized;
+ pColArray->Insert(static_cast<SCCOL>(nGroupStartCol), static_cast<SCCOL>(nGroupEndCol), bResized, !bGroupDisplay, sal_True);
+ }
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcoli.hxx b/sc/source/filter/xml/xmlcoli.hxx
new file mode 100644
index 000000000000..6c958bc673bd
--- /dev/null
+++ b/sc/source/filter/xml/xmlcoli.hxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCOLI_HXX
+#define SC_XMLCOLI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableColContext : public SvXMLImportContext
+{
+ sal_Int32 nColCount;
+ rtl::OUString sStyleName;
+ rtl::OUString sVisibility;
+ rtl::OUString sCellStyleName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableColContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableColContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLTableColsContext : public SvXMLImportContext
+{
+ sal_Int32 nHeaderStartCol;
+ sal_Int32 nHeaderEndCol;
+ sal_Int32 nGroupStartCol;
+ sal_Int32 nGroupEndCol;
+ sal_Bool bHeader;
+ sal_Bool bGroup;
+ sal_Bool bGroupDisplay;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableColsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bHeader, const sal_Bool bGroup);
+
+ virtual ~ScXMLTableColsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlconti.cxx b/sc/source/filter/xml/xmlconti.cxx
new file mode 100644
index 000000000000..2b752f7aec83
--- /dev/null
+++ b/sc/source/filter/xml/xmlconti.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlconti.hxx"
+#include "xmlimprt.hxx"
+#include "global.hxx"
+#include "document.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLContentContext::ScXMLContentContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ rtl::OUStringBuffer& sTempValue) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sOUText(),
+ sValue(sTempValue)
+{
+}
+
+ScXMLContentContext::~ScXMLContentContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_S))
+ {
+ sal_Int32 nRepeat(0);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ const rtl::OUString& sAttrValue(xAttrList->getValueByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrfx = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ if ((nPrfx == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C))
+ nRepeat = sAttrValue.toInt32();
+ }
+ if (nRepeat)
+ for (sal_Int32 j = 0; j < nRepeat; ++j)
+ sOUText.append(static_cast<sal_Unicode>(' '));
+ else
+ sOUText.append(static_cast<sal_Unicode>(' '));
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLContentContext::Characters( const ::rtl::OUString& rChars )
+{
+ sOUText.append(rChars);
+}
+
+void ScXMLContentContext::EndElement()
+{
+ sValue.append(sOUText);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlconti.hxx b/sc/source/filter/xml/xmlconti.hxx
new file mode 100644
index 000000000000..d350f0f2f89e
--- /dev/null
+++ b/sc/source/filter/xml/xmlconti.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCONTI_HXX
+#define SC_XMLCONTI_HXX
+
+#include <xmloff/xmlimp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+
+class ScXMLContentContext : public SvXMLImportContext
+{
+ rtl::OUStringBuffer sOUText;
+ rtl::OUStringBuffer& sValue;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLContentContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ rtl::OUStringBuffer& sValue);
+
+ virtual ~ScXMLContentContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters( const ::rtl::OUString& rChars );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcvali.cxx b/sc/source/filter/xml/xmlcvali.cxx
new file mode 100644
index 000000000000..25d16d999fb0
--- /dev/null
+++ b/sc/source/filter/xml/xmlcvali.cxx
@@ -0,0 +1,699 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlcvali.hxx"
+#include "xmlimprt.hxx"
+#include "xmlconti.hxx"
+#include "document.hxx"
+#include "XMLConverter.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/XMLEventsImportContext.hxx>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <tools/debug.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
+
+class ScXMLContentValidationContext : public SvXMLImportContext
+{
+ rtl::OUString sName;
+ rtl::OUString sHelpTitle;
+ rtl::OUString sHelpMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sErrorMessageType;
+ rtl::OUString sBaseCellAddress;
+ rtl::OUString sCondition;
+ sal_Int16 nShowList;
+ sal_Bool bAllowEmptyCell;
+ sal_Bool bDisplayHelp;
+ sal_Bool bDisplayError;
+
+ SvXMLImportContextRef xEventContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ com::sun::star::sheet::ValidationAlertStyle GetAlertStyle() const;
+ void SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const;
+ void GetCondition( ScMyImportValidation& rValidation ) const;
+
+public:
+
+ ScXMLContentValidationContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLContentValidationContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay);
+ void SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const rtl::OUString& sMessageType, const sal_Bool bDisplay);
+ void SetErrorMacro(const sal_Bool bExecute);
+};
+
+class ScXMLHelpMessageContext : public SvXMLImportContext
+{
+ rtl::OUString sTitle;
+ rtl::OUStringBuffer sMessage;
+ sal_Int32 nParagraphCount;
+ sal_Bool bDisplay;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLHelpMessageContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLHelpMessageContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLErrorMessageContext : public SvXMLImportContext
+{
+ rtl::OUString sTitle;
+ rtl::OUStringBuffer sMessage;
+ rtl::OUString sMessageType;
+ sal_Int32 nParagraphCount;
+ sal_Bool bDisplay;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLErrorMessageContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLErrorMessageContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLErrorMacroContext : public SvXMLImportContext
+{
+ rtl::OUString sName;
+ sal_Bool bExecute;
+
+ ScXMLContentValidationContext* pValidationContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLErrorMacroContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pValidationContext);
+
+ virtual ~ScXMLErrorMacroContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual void EndElement();
+};
+
+//------------------------------------------------------------------
+
+ScXMLContentValidationsContext::ScXMLContentValidationsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // here are no attributes
+}
+
+ScXMLContentValidationsContext::~ScXMLContentValidationsContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentValidationsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION:
+ pContext = new ScXMLContentValidationContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLContentValidationsContext::EndElement()
+{
+}
+
+ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nShowList(sheet::TableValidationVisibility::UNSORTED),
+ bAllowEmptyCell(sal_True),
+ bDisplayHelp(false),
+ bDisplayError(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_CONDITION:
+ sCondition = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS:
+ sBaseCellAddress = sValue;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL:
+ if (IsXMLToken(sValue, XML_FALSE))
+ bAllowEmptyCell = false;
+ break;
+ case XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST:
+ {
+ if (IsXMLToken(sValue, XML_NO))
+ {
+ nShowList = sheet::TableValidationVisibility::INVISIBLE;
+ }
+ else if (IsXMLToken(sValue, XML_UNSORTED))
+ {
+ nShowList = sheet::TableValidationVisibility::UNSORTED;
+ }
+ else if (IsXMLToken(sValue, XML_SORTED_ASCENDING))
+ {
+ nShowList = sheet::TableValidationVisibility::SORTEDASCENDING;
+ }
+ }
+ break;
+ }
+ }
+}
+
+ScXMLContentValidationContext::~ScXMLContentValidationContext()
+{
+}
+
+SvXMLImportContext *ScXMLContentValidationContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE:
+ pContext = new ScXMLHelpMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE:
+ pContext = new ScXMLErrorMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO:
+ pContext = new ScXMLErrorMacroContext( GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS:
+ pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName );
+ xEventContext = pContext;
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+sheet::ValidationAlertStyle ScXMLContentValidationContext::GetAlertStyle() const
+{
+ if (IsXMLToken(sErrorMessageType, XML_MACRO))
+ return sheet::ValidationAlertStyle_MACRO;
+ if (IsXMLToken(sErrorMessageType, XML_STOP))
+ return sheet::ValidationAlertStyle_STOP;
+ if (IsXMLToken(sErrorMessageType, XML_WARNING))
+ return sheet::ValidationAlertStyle_WARNING;
+ if (IsXMLToken(sErrorMessageType, XML_INFORMATION))
+ return sheet::ValidationAlertStyle_INFO;
+ // default for unknown
+ return sheet::ValidationAlertStyle_STOP;
+}
+
+void ScXMLContentValidationContext::SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const
+{
+ reGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
+ {
+ // the entire attribute contains a namespace: internal namespace not allowed
+ rFormula = rCondition;
+ rFormulaNmsp = rGlobNmsp;
+ reGrammar = eGlobGrammar;
+ }
+ else
+ {
+ // the attribute does not contain a namespace: try to find a namespace of an external grammar
+ GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, reGrammar, rCondition, true );
+ if( reGrammar != FormulaGrammar::GRAM_EXTERNAL )
+ reGrammar = eGlobGrammar;
+ }
+}
+
+void ScXMLContentValidationContext::GetCondition( ScMyImportValidation& rValidation ) const
+{
+ rValidation.aValidationType = sheet::ValidationType_ANY; // default if no condition is given
+ rValidation.aOperator = sheet::ConditionOperator_NONE;
+
+ if( sCondition.getLength() > 0 )
+ {
+ // extract leading namespace from condition string
+ OUString aCondition, aConditionNmsp;
+ FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sCondition );
+ bool bHasNmsp = aCondition.getLength() < sCondition.getLength();
+
+ // parse a condition from the attribute string
+ ScXMLConditionParseResult aParseResult;
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+ /* Check the result. A valid value in aParseResult.meToken implies
+ that the other members of aParseResult are filled with valid data
+ for that token. */
+ bool bSecondaryPart = false;
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_TEXTLENGTH: // condition is 'cell-content-text-length()<operator><expression>'
+ case XML_COND_TEXTLENGTH_ISBETWEEN: // condition is 'cell-content-text-length-is-between(<expression1>,<expression2>)'
+ case XML_COND_TEXTLENGTH_ISNOTBETWEEN: // condition is 'cell-content-text-length-is-not-between(<expression1>,<expression2>)'
+ case XML_COND_ISINLIST: // condition is 'cell-content-is-in-list(<expression>)'
+ rValidation.aValidationType = aParseResult.meValidation;
+ rValidation.aOperator = aParseResult.meOperator;
+ break;
+
+ case XML_COND_ISWHOLENUMBER: // condition is 'cell-content-is-whole-number() and <condition>'
+ case XML_COND_ISDECIMALNUMBER: // condition is 'cell-content-is-decimal-number() and <condition>'
+ case XML_COND_ISDATE: // condition is 'cell-content-is-date() and <condition>'
+ case XML_COND_ISTIME: // condition is 'cell-content-is-time() and <condition>'
+ rValidation.aValidationType = aParseResult.meValidation;
+ bSecondaryPart = true;
+ break;
+
+ default:; // unacceptable or unknown condition
+ }
+
+ /* Parse the following 'and <condition>' part of some conditions. This
+ updates the members of aParseResult that will contain the operands
+ and comparison operator then. */
+ if( bSecondaryPart )
+ {
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+ if( aParseResult.meToken == XML_COND_AND )
+ {
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_CELLCONTENT: // condition is 'and cell-content()<operator><expression>'
+ case XML_COND_ISBETWEEN: // condition is 'and cell-content-is-between(<expression1>,<expression2>)'
+ case XML_COND_ISNOTBETWEEN: // condition is 'and cell-content-is-not-between(<expression1>,<expression2>)'
+ rValidation.aOperator = aParseResult.meOperator;
+ break;
+ default:; // unacceptable or unknown condition
+ }
+ }
+ }
+
+ // a validation type (date, integer) without a condition isn't possible
+ if( rValidation.aOperator == sheet::ConditionOperator_NONE )
+ rValidation.aValidationType = sheet::ValidationType_ANY;
+
+ // parse the formulas
+ if( rValidation.aValidationType != sheet::ValidationType_ANY )
+ {
+ SetFormula( rValidation.sFormula1, rValidation.sFormulaNmsp1, rValidation.eGrammar1,
+ aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+ SetFormula( rValidation.sFormula2, rValidation.sFormulaNmsp2, rValidation.eGrammar2,
+ aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+ }
+ }
+}
+
+void ScXMLContentValidationContext::EndElement()
+{
+ // #i36650# event-listeners element moved up one level
+ if (xEventContext.Is())
+ {
+ rtl::OUString sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError"));
+ XMLEventsImportContext* pEvents =
+ (XMLEventsImportContext*)&xEventContext;
+ uno::Sequence<beans::PropertyValue> aValues;
+ pEvents->GetEventSequence( sOnError, aValues );
+
+ sal_Int32 nLength = aValues.getLength();
+ for( sal_Int32 i = 0; i < nLength; i++ )
+ {
+ // #i47525# must allow "MacroName" or "Script"
+ if ( aValues[i].Name.equalsAsciiL( "MacroName", sizeof("MacroName")-1 ) ||
+ aValues[i].Name.equalsAsciiL( "Script", sizeof("Script")-1 ) )
+ {
+ aValues[i].Value >>= sErrorTitle;
+ break;
+ }
+ }
+ }
+
+ ScMyImportValidation aValidation;
+ aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
+ aValidation.sName = sName;
+ aValidation.sBaseCellAddress = sBaseCellAddress;
+ aValidation.sImputTitle = sHelpTitle;
+ aValidation.sImputMessage = sHelpMessage;
+ aValidation.sErrorTitle = sErrorTitle;
+ aValidation.sErrorMessage = sErrorMessage;
+ GetCondition( aValidation );
+ aValidation.aAlertStyle = GetAlertStyle();
+ aValidation.bShowErrorMessage = bDisplayError;
+ aValidation.bShowImputMessage = bDisplayHelp;
+ aValidation.bIgnoreBlanks = bAllowEmptyCell;
+ aValidation.nShowList = nShowList;
+ GetScImport().AddValidation(aValidation);
+}
+
+void ScXMLContentValidationContext::SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay)
+{
+ sHelpTitle = sTitle;
+ sHelpMessage = sMessage;
+ bDisplayHelp = bDisplay;
+}
+
+void ScXMLContentValidationContext::SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage,
+ const rtl::OUString& sMessageType, const sal_Bool bDisplay)
+{
+ sErrorTitle = sTitle;
+ sErrorMessage = sMessage;
+ sErrorMessageType = sMessageType;
+ bDisplayError = bDisplay;
+}
+
+void ScXMLContentValidationContext::SetErrorMacro(const sal_Bool bExecute)
+{
+ sErrorMessageType = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("macro"));
+ bDisplayError = bExecute;
+}
+
+ScXMLHelpMessageContext::ScXMLHelpMessageContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sTitle(),
+ sMessage(),
+ nParagraphCount(0),
+ bDisplay(false)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationHelpMessageAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_HELP_MESSAGE_ATTR_TITLE:
+ sTitle = sValue;
+ break;
+ case XML_TOK_HELP_MESSAGE_ATTR_DISPLAY:
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLHelpMessageContext::~ScXMLHelpMessageContext()
+{
+}
+
+SvXMLImportContext *ScXMLHelpMessageContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_P:
+ {
+ if(nParagraphCount)
+ sMessage.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLHelpMessageContext::EndElement()
+{
+ pValidationContext->SetHelpMessage(sTitle, sMessage.makeStringAndClear(), bDisplay);
+}
+
+ScXMLErrorMessageContext::ScXMLErrorMessageContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sTitle(),
+ sMessage(),
+ sMessageType(),
+ nParagraphCount(0),
+ bDisplay(false)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMessageAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_ERROR_MESSAGE_ATTR_TITLE:
+ sTitle = sValue;
+ break;
+ case XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE:
+ sMessageType = sValue;
+ break;
+ case XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY:
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLErrorMessageContext::~ScXMLErrorMessageContext()
+{
+}
+
+SvXMLImportContext *ScXMLErrorMessageContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_P:
+ {
+ if(nParagraphCount)
+ sMessage.append(static_cast<sal_Unicode>('\n'));
+ ++nParagraphCount;
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLErrorMessageContext::EndElement()
+{
+ pValidationContext->SetErrorMessage(sTitle, sMessage.makeStringAndClear(), sMessageType, bDisplay);
+}
+
+ScXMLErrorMacroContext::ScXMLErrorMacroContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLContentValidationContext* pTempValidationContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sName(),
+ bExecute(false)
+{
+ pValidationContext = pTempValidationContext;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMacroAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_ERROR_MACRO_ATTR_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_ERROR_MACRO_ATTR_EXECUTE:
+ bExecute = IsXMLToken(sValue, XML_TRUE);
+ break;
+ }
+ }
+}
+
+ScXMLErrorMacroContext::~ScXMLErrorMacroContext()
+{
+}
+
+SvXMLImportContext *ScXMLErrorMacroContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = NULL;
+
+ if ((nPrefix == XML_NAMESPACE_SCRIPT) && IsXMLToken(rLName, XML_EVENTS))
+ {
+ pContext = new XMLEventsImportContext(GetImport(), nPrefix, rLName);
+ }
+ if (!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLErrorMacroContext::EndElement()
+{
+ pValidationContext->SetErrorMacro( bExecute );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcvali.hxx b/sc/source/filter/xml/xmlcvali.hxx
new file mode 100644
index 000000000000..b2c433c4696e
--- /dev/null
+++ b/sc/source/filter/xml/xmlcvali.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLCVALI_HXX
+#define SC_XMLCVALI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <rtl/ustrbuf.hxx>
+
+class ScXMLImport;
+
+class ScXMLContentValidationsContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLContentValidationsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLContentValidationsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx
new file mode 100644
index 000000000000..210a6f5dc7ee
--- /dev/null
+++ b/sc/source/filter/xml/xmldpimp.cxx
@@ -0,0 +1,1851 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmldpimp.hxx"
+#include "xmlimprt.hxx"
+#include "xmlfilti.hxx"
+#include "xmlsorti.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "dpshttab.hxx"
+#include "dpsdbtab.hxx"
+#include "attrib.hxx"
+#include "XMLConverter.hxx"
+#include "dpgroup.hxx"
+#include "dpdimsave.hxx"
+#include "rangeutl.hxx"
+#include "dpoutputgeometry.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
+using ::rtl::OUString;
+
+using rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLDataPilotTablesContext::ScXMLDataPilotTablesContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // has no Attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDataPilotTablesContext::~ScXMLDataPilotTablesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDataPilotTablesContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTablesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE :
+ {
+ pContext = new ScXMLDataPilotTableContext( GetScImport(), nPrefix,
+ rLName, xAttrList);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotTablesContext::EndElement()
+{
+}
+
+ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() :
+ mbVisible(true) {}
+
+ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDoc(GetScImport().GetDocument()),
+ pDPObject(NULL),
+ pDPSave(NULL),
+ pDPDimSaveData(NULL),
+ sDataPilotTableName(),
+ sApplicationData(),
+ sGrandTotal(GetXMLToken(XML_BOTH)),
+ mnRowFieldCount(0),
+ mnColFieldCount(0),
+ mnPageFieldCount(0),
+ mnDataFieldCount(0),
+ bIsNative(sal_True),
+ bIgnoreEmptyRows(false),
+ bIdentifyCategories(false),
+ bTargetRangeAddress(false),
+ bSourceCellRange(false),
+ bShowFilter(sal_True),
+ bDrillDown(sal_True),
+ bHeaderGridLayout(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_NAME :
+ {
+ sDataPilotTableName = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA :
+ {
+ sApplicationData = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL :
+ {
+ sGrandTotal = sValue;
+ if (IsXMLToken(sValue, XML_BOTH))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = true;
+ }
+ else if (IsXMLToken(sValue, XML_ROW))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = false;
+ }
+ else if (IsXMLToken(sValue, XML_COLUMN))
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = true;
+ }
+ else
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = false;
+ }
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS :
+ {
+ bIgnoreEmptyRows = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES :
+ {
+ bIdentifyCategories = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ bTargetRangeAddress = ScRangeStringConverter::GetRangeFromString( aTargetRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS :
+ {
+ sButtons = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON :
+ {
+ bShowFilter = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN :
+ {
+ bDrillDown = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ATTR_HEADER_GRID_LAYOUT :
+ {
+ bHeaderGridLayout = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+
+ pDPObject = new ScDPObject(pDoc);
+ pDPSave = new ScDPSaveData();
+}
+
+ScXMLDataPilotTableContext::~ScXMLDataPilotTableContext()
+{
+ delete pDPDimSaveData;
+}
+
+SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL :
+ {
+ pContext = new ScXMLDPSourceSQLContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = SQL;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE :
+ {
+ pContext = new ScXMLDPSourceTableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = TABLE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY :
+ {
+ pContext = new ScXMLDPSourceQueryContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = QUERY;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE :
+ {
+ pContext = new ScXMLSourceServiceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = SERVICE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL:
+ {
+ pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE :
+ {
+ pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ nSourceType = CELLRANGE;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD :
+ pContext = new ScXMLDataPilotFieldContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotTableContext::SetButtons()
+{
+ ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF);
+ aGeometry.setColumnFieldCount(mnColFieldCount);
+ aGeometry.setRowFieldCount(mnRowFieldCount);
+ aGeometry.setPageFieldCount(mnPageFieldCount);
+ aGeometry.setDataFieldCount(mnDataFieldCount);
+
+ OUString sAddress;
+ sal_Int32 nOffset = 0;
+ while( nOffset >= 0 )
+ {
+ ScRangeStringConverter::GetTokenByOffset( sAddress, sButtons, nOffset );
+ if( nOffset >= 0 )
+ {
+ ScAddress aScAddress;
+ sal_Int32 nAddrOffset(0);
+ if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset ))
+ {
+ ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress);
+
+ sal_Int16 nMFlag = SC_MF_BUTTON;
+ if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row)
+ nMFlag |= SC_MF_BUTTON_POPUP;
+
+ // Use the cell's string value to see if this field contains a
+ // hidden member. Isn't there a better way? GetString() is
+ // quite expensive...
+ String aCellStr;
+ pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr);
+ if (maHiddenMemberFields.count(aCellStr))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag);
+ }
+ }
+ }
+
+ if ( pDPObject )
+ pDPObject->RefreshAfterLoad();
+}
+
+void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember)
+{
+ if (pDPSave)
+ {
+ // if a dimension with that name has already been inserted,
+ // mark the new one as duplicate
+ if ( !pDim->IsDataLayout() &&
+ pDPSave->GetExistingDimensionByName(pDim->GetName()) )
+ pDim->SetDupFlag( sal_True );
+
+ if (!pDim->IsDataLayout())
+ {
+ switch (pDim->GetOrientation())
+ {
+ case sheet::DataPilotFieldOrientation_ROW:
+ ++mnRowFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ ++mnColFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ ++mnPageFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ ++mnDataFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ default:
+ ;
+ }
+
+ if (bHasHiddenMember)
+ {
+ // the layout name takes priority over the original name,
+ // since this data is used against cell values.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maHiddenMemberFields.insert(*pLayoutName);
+ else
+ maHiddenMemberFields.insert(pDim->GetName());
+ }
+ }
+ pDPSave->AddDimension(pDim);
+ }
+}
+
+void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim)
+{
+ if (!pDPDimSaveData)
+ pDPDimSaveData = new ScDPDimensionSaveData();
+ pDPDimSaveData->AddNumGroupDimension(aNumGroupDim);
+}
+
+void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveGroupDimension& aGroupDim)
+{
+ if (!pDPDimSaveData)
+ pDPDimSaveData = new ScDPDimensionSaveData();
+ pDPDimSaveData->AddGroupDimension(aGroupDim);
+}
+
+void ScXMLDataPilotTableContext::EndElement()
+{
+ if (!bTargetRangeAddress)
+ return;
+
+ pDPObject->SetName(sDataPilotTableName);
+ pDPObject->SetTag(sApplicationData);
+ pDPObject->SetOutRange(aTargetRangeAddress);
+ pDPObject->SetHeaderLayout(bHeaderGridLayout);
+ switch (nSourceType)
+ {
+ case SQL :
+ {
+ ScImportSourceDesc aImportDesc(pDoc);
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_SQL;
+ aImportDesc.bNative = bIsNative;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case TABLE :
+ {
+ ScImportSourceDesc aImportDesc(pDoc);
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_TABLE;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case QUERY :
+ {
+ ScImportSourceDesc aImportDesc(pDoc);
+ aImportDesc.aDBName = sDatabaseName;
+ aImportDesc.aObject = sSourceObject;
+ aImportDesc.nType = sheet::DataImportMode_QUERY;
+ pDPObject->SetImportDesc(aImportDesc);
+ }
+ break;
+ case SERVICE :
+ {
+ ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject,
+ sServiceUsername, sServicePassword);
+ pDPObject->SetServiceData(aServiceDesk);
+ }
+ break;
+ case CELLRANGE :
+ {
+ if (bSourceCellRange)
+ {
+ ScSheetSourceDesc aSheetDesc(pDoc);
+ if (sSourceRangeName.getLength())
+ // Range name takes precedence.
+ aSheetDesc.SetRangeName(sSourceRangeName);
+ else
+ aSheetDesc.SetSourceRange(aSourceCellRangeAddress);
+ aSheetDesc.SetQueryParam(aSourceQueryParam);
+ pDPObject->SetSheetDesc(aSheetDesc);
+ }
+ }
+ break;
+ }
+
+ pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
+ pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
+ if (maRowGrandTotal.maDisplayName.getLength())
+ // TODO: Right now, we only support one grand total name for both
+ // column and row totals. Take the value from the row total for
+ // now.
+ pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName);
+
+ pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows);
+ pDPSave->SetRepeatIfEmpty(bIdentifyCategories);
+ pDPSave->SetFilterButton(bShowFilter);
+ pDPSave->SetDrillDown(bDrillDown);
+ if (pDPDimSaveData)
+ pDPSave->SetDimensionData(pDPDimSaveData);
+ pDPObject->SetSaveData(*pDPSave);
+ if (pDoc)
+ {
+ ScDPCollection* pDPCollection = pDoc->GetDPCollection();
+
+ // #i94570# Names have to be unique, or the tables can't be accessed by API.
+ if ( pDPCollection->GetByName(pDPObject->GetName()) )
+ pDPObject->SetName( String() ); // ignore the invalid name, create a new name in AfterXMLLoading
+
+ pDPObject->SetAlive(sal_True);
+ pDPCollection->InsertNewTable(pDPObject);
+ }
+ SetButtons();
+}
+
+void ScXMLDataPilotTableContext::SetGrandTotal(
+ XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
+{
+ switch (eOrientation)
+ {
+ case XML_BOTH:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_ROW:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_COLUMN:
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ default:
+ ;
+ }
+}
+
+ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT :
+ {
+ pDataPilotTable->SetNative(!IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceSQLContext::~ScXMLDPSourceSQLContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceSQLContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceSQLContext::EndElement()
+{
+}
+
+ScXMLDPSourceTableContext::ScXMLDPSourceTableContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceTableContext::~ScXMLDPSourceTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceTableContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceTableContext::EndElement()
+{
+}
+
+ScXMLDPSourceQueryContext::ScXMLDPSourceQueryContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME :
+ {
+ pDataPilotTable->SetDatabaseName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME :
+ {
+ pDataPilotTable->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPSourceQueryContext::~ScXMLDPSourceQueryContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPSourceQueryContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPSourceQueryContext::EndElement()
+{
+}
+
+ScXMLSourceServiceContext::ScXMLSourceServiceContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceServiceAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SERVICE_ATTR_NAME :
+ {
+ pDataPilotTable->SetServiceName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME :
+ {
+ pDataPilotTable->SetServiceSourceName(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME :
+ {
+ pDataPilotTable->SetServiceSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME :
+ {
+ pDataPilotTable->SetServiceUsername(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD :
+ {
+ pDataPilotTable->SetServicePassword(sValue);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSourceServiceContext::~ScXMLSourceServiceContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceServiceContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceServiceContext::EndElement()
+{
+}
+
+ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport()
+{
+ return static_cast<ScXMLImport&>(GetImport());
+}
+
+ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, const Reference<XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mpTableContext(pTableContext),
+ meOrientation(NONE),
+ mbVisible(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex(i);
+ const OUString& rAttrValue = xAttrList->getValueByIndex(i);
+
+ OUString aLocalName;
+ sal_uInt16 nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
+ switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
+ {
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY:
+ mbVisible = IsXMLToken(rAttrValue, XML_TRUE);
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION:
+ if (IsXMLToken(rAttrValue, XML_BOTH))
+ meOrientation = BOTH;
+ else if (IsXMLToken(rAttrValue, XML_ROW))
+ meOrientation = ROW;
+ else if (IsXMLToken(rAttrValue, XML_COLUMN))
+ meOrientation = COLUMN;
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT:
+ maDisplayName = rAttrValue;
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext()
+{
+}
+
+SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext(
+ sal_uInt16 /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return NULL;
+}
+
+void ScXMLDataPilotGrandTotalContext::EndElement()
+{
+ XMLTokenEnum eOrient = XML_NONE;
+ switch (meOrientation)
+ {
+ case BOTH:
+ eOrient = XML_BOTH;
+ break;
+ case ROW:
+ eOrient = XML_ROW;
+ break;
+ case COLUMN:
+ eOrient = XML_COLUMN;
+ break;
+ default:
+ ;
+ }
+ mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName);
+}
+
+ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceCellRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS :
+ {
+ ScRange aSourceRangeAddress;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aSourceRangeAddress, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ pDataPilotTable->SetSourceCellRangeAddress(aSourceRangeAddress);
+ }
+ break;
+ case XML_TOK_SOURCE_CELL_RANGE_ATTR_NAME:
+ pDataPilotTable->SetSourceRangeName(sValue);
+ break;
+ }
+ }
+}
+
+ScXMLSourceCellRangeContext::~ScXMLSourceCellRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceCellRangeContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableSourceCellRangeElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER :
+ pContext = new ScXMLDPFilterContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotTable);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceCellRangeContext::EndElement()
+{
+}
+
+ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTable) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTable),
+ pDim(NULL),
+ fStart(0.0),
+ fEnd(0.0),
+ fStep(0.0),
+ nUsedHierarchy(1),
+ nGroupPart(0),
+ bSelectedPage(false),
+ bIsGroupField(false),
+ bDateValue(false),
+ bAutoStart(false),
+ bAutoEnd(false),
+ mbHasHiddenMember(false)
+{
+ sal_Bool bHasName(false);
+ sal_Bool bDataLayout(false);
+ OUString aDisplayName;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME :
+ {
+ sName = sValue;
+ bHasName = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT:
+ {
+ aDisplayName = sValue;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD :
+ {
+ bDataLayout = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION :
+ {
+ nFunction = (sal_Int16) ScXMLConverter::GetFunctionFromString( sValue );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION :
+ {
+ nOrientation = (sal_Int16) ScXMLConverter::GetOrientationFromString( sValue );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE :
+ {
+ sSelectedPage = sValue;
+ bSelectedPage = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY :
+ {
+ nUsedHierarchy = sValue.toInt32();
+ }
+ break;
+ }
+ }
+ if (bHasName)
+ {
+ pDim = new ScDPSaveDimension(String(sName), bDataLayout);
+ if (aDisplayName.getLength())
+ pDim->SetLayoutName(aDisplayName);
+ }
+}
+
+ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotFieldElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL :
+ pContext = new ScXMLDataPilotLevelContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE :
+ pContext = new ScXMLDataPilotFieldReferenceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS :
+ pContext = new ScXMLDataPilotGroupsContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember)
+{
+ if (pDim)
+ pDim->AddMember(pMember);
+
+ if (!pMember->GetIsVisible())
+ // This member is hidden.
+ mbHasHiddenMember = true;
+}
+
+void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName)
+{
+ if (pDim)
+ pDim->SetSubtotalName(rName);
+}
+
+void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName)
+{
+ ScXMLDataPilotGroup aGroup;
+ aGroup.aMembers = rMembers;
+ aGroup.aName = rName;
+ aGroups.push_back(aGroup);
+}
+
+void ScXMLDataPilotFieldContext::EndElement()
+{
+ if (pDim)
+ {
+ pDim->SetUsedHierarchy(nUsedHierarchy);
+ pDim->SetFunction(nFunction);
+ pDim->SetOrientation(nOrientation);
+ if (bSelectedPage)
+ {
+ pDim->SetCurrentPage(&sSelectedPage);
+ }
+ pDataPilotTable->AddDimension(pDim, mbHasHiddenMember);
+ if (bIsGroupField)
+ {
+ ScDPNumGroupInfo aInfo;
+ aInfo.Enable = sal_True;
+ aInfo.DateValues = bDateValue;
+ aInfo.AutoStart = bAutoStart;
+ aInfo.AutoEnd = bAutoEnd;
+ aInfo.Start = fStart;
+ aInfo.End = fEnd;
+ aInfo.Step = fStep;
+ if (sGroupSource.getLength())
+ {
+ ScDPSaveGroupDimension aGroupDim(sGroupSource, sName);
+ if (nGroupPart)
+ aGroupDim.SetDateInfo(aInfo, nGroupPart);
+ else
+ {
+ ::std::vector<ScXMLDataPilotGroup>::const_iterator aItr(aGroups.begin());
+ ::std::vector<ScXMLDataPilotGroup>::const_iterator aEndItr(aGroups.end());
+ while (aItr != aEndItr)
+ {
+ ScDPSaveGroupItem aItem(aItr->aName);
+ ::std::vector<rtl::OUString>::const_iterator aMembersItr(aItr->aMembers.begin());
+ ::std::vector<rtl::OUString>::const_iterator aMembersEndItr(aItr->aMembers.end());
+ while (aMembersItr != aMembersEndItr)
+ {
+ aItem.AddElement(*aMembersItr);
+ ++aMembersItr;
+ }
+ ++aItr;
+ aGroupDim.AddGroupItem(aItem);
+ }
+ }
+ pDataPilotTable->AddGroupDim(aGroupDim);
+ }
+ else //NumGroup
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim(sName, aInfo);
+ if (nGroupPart)
+ aNumGroupDim.SetDateInfo(aInfo, nGroupPart);
+ pDataPilotTable->AddGroupDim(aNumGroupDim);
+ }
+ }
+ }
+}
+
+ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldReference aReference;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_NONE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::NONE;
+ else if (IsXMLToken(sValue, XML_MEMBER_DIFFERENCE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE;
+ else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE_DIFFERENCE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE;
+ else if (IsXMLToken(sValue, XML_RUNNING_TOTAL))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::RUNNING_TOTAL;
+ else if (IsXMLToken(sValue, XML_ROW_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_COLUMN_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_TOTAL_PERCENTAGE))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE;
+ else if (IsXMLToken(sValue, XML_INDEX))
+ aReference.ReferenceType = sheet::DataPilotFieldReferenceType::INDEX;
+ }
+ else if (IsXMLToken(aLocalName, XML_FIELD_NAME))
+ {
+ aReference.ReferenceField = sValue;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_TYPE))
+ {
+ if (IsXMLToken(sValue, XML_NAMED))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NAMED;
+ else if (IsXMLToken(sValue, XML_PREVIOUS))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::PREVIOUS;
+ else if (IsXMLToken(sValue, XML_NEXT))
+ aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NEXT;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_NAME))
+ {
+ aReference.ReferenceItemName = sValue;
+ }
+ }
+ }
+ pDataPilotField->SetFieldReference(aReference);
+}
+
+ScXMLDataPilotFieldReferenceContext::~ScXMLDataPilotFieldReferenceContext()
+{
+}
+
+ScXMLDataPilotLevelContext::ScXMLDataPilotLevelContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotLevelAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY :
+ {
+ pDataPilotField->SetShowEmpty(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotLevelContext::~ScXMLDataPilotLevelContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotLevelContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotLevelElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS :
+ pContext = new ScXMLDataPilotSubTotalsContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS :
+ pContext = new ScXMLDataPilotMembersContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO :
+ pContext = new ScXMLDataPilotDisplayInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO :
+ pContext = new ScXMLDataPilotSortInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO :
+ pContext = new ScXMLDataPilotLayoutInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotLevelContext::EndElement()
+{
+}
+
+ScXMLDataPilotDisplayInfoContext::ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldAutoShowInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ENABLED))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aInfo.IsEnabled = sal_True;
+ else
+ aInfo.IsEnabled = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_DISPLAY_MEMBER_MODE))
+ {
+ if (IsXMLToken(sValue, XML_FROM_TOP))
+ aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_TOP;
+ else if (IsXMLToken(sValue, XML_FROM_BOTTOM))
+ aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM;
+ }
+ else if (IsXMLToken(aLocalName, XML_MEMBER_COUNT))
+ {
+ aInfo.ItemCount = sValue.toInt32();
+ }
+ else if (IsXMLToken(aLocalName, XML_DATA_FIELD))
+ {
+ aInfo.DataField = sValue;
+ }
+ }
+ }
+ pDataPilotField->SetAutoShowInfo(aInfo);
+}
+
+ScXMLDataPilotDisplayInfoContext::~ScXMLDataPilotDisplayInfoContext()
+{
+}
+
+ScXMLDataPilotSortInfoContext::ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldSortInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ORDER))
+ {
+ if (IsXMLToken(sValue, XML_ASCENDING))
+ aInfo.IsAscending = sal_True;
+ else if (IsXMLToken(sValue, XML_DESCENDING))
+ aInfo.IsAscending = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_SORT_MODE))
+ {
+ if (IsXMLToken(sValue, XML_NONE))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::NONE;
+ else if (IsXMLToken(sValue, XML_MANUAL))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ else if (IsXMLToken(sValue, XML_NAME))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::NAME;
+ else if (IsXMLToken(sValue, XML_DATA))
+ aInfo.Mode = sheet::DataPilotFieldSortMode::DATA;
+ }
+ else if (IsXMLToken(aLocalName, XML_DATA_FIELD))
+ aInfo.Field = sValue;
+ }
+ }
+ pDataPilotField->SetSortInfo(aInfo);
+}
+
+ScXMLDataPilotSortInfoContext::~ScXMLDataPilotSortInfoContext()
+{
+}
+
+ScXMLDataPilotLayoutInfoContext::ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sheet::DataPilotFieldLayoutInfo aInfo;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue(xAttrList->getValueByIndex( i ));
+
+ if ( nPrefix == XML_NAMESPACE_TABLE )
+ {
+ if (IsXMLToken(aLocalName, XML_ADD_EMPTY_LINES))
+ {
+ if (IsXMLToken(sValue, XML_TRUE))
+ aInfo.AddEmptyLines = sal_True;
+ else
+ aInfo.AddEmptyLines = false;
+ }
+ else if (IsXMLToken(aLocalName, XML_LAYOUT_MODE))
+ {
+ if (IsXMLToken(sValue, XML_TABULAR_LAYOUT))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT;
+ else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_TOP))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP;
+ else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_BOTTOM))
+ aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
+ }
+ }
+ }
+ pDataPilotField->SetLayoutInfo(aInfo);}
+
+ScXMLDataPilotLayoutInfoContext::~ScXMLDataPilotLayoutInfoContext()
+{
+}
+
+ScXMLDataPilotSubTotalsContext::ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField),
+ nFunctionCount(0),
+ pFunctions(NULL)
+{
+
+ // has no attributes
+}
+
+ScXMLDataPilotSubTotalsContext::~ScXMLDataPilotSubTotalsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotSubTotalsElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL :
+ pContext = new ScXMLDataPilotSubTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotSubTotalsContext::EndElement()
+{
+ pDataPilotField->SetSubTotals(pFunctions, nFunctionCount);
+ if (maDisplayName.getLength())
+ pDataPilotField->SetSubTotalName(maDisplayName);
+}
+
+void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
+{
+ if (nFunctionCount)
+ {
+ ++nFunctionCount;
+ sal_uInt16* pTemp = new sal_uInt16[nFunctionCount];
+ for (sal_Int16 i = 0; i < nFunctionCount - 1; ++i)
+ pTemp[i] = pFunctions[i];
+ pTemp[nFunctionCount - 1] = nFunction;
+ delete[] pFunctions;
+ pFunctions = pTemp;
+ }
+ else
+ {
+ nFunctionCount = 1;
+ pFunctions = new sal_uInt16[nFunctionCount];
+ pFunctions[0] = nFunction;
+ }
+}
+
+void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName)
+{
+ maDisplayName = rName;
+}
+
+ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotSubTotalsContext* pTempDataPilotSubTotals) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotSubTotals(pTempDataPilotSubTotals)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotSubTotalAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION :
+ {
+ pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>(
+ ScXMLConverter::GetFunctionFromString( sValue ) ) );
+ }
+ break;
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT:
+ pDataPilotSubTotals->SetDisplayName(sValue);
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotSubTotalContext::~ScXMLDataPilotSubTotalContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotSubTotalContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotSubTotalContext::EndElement()
+{
+}
+
+ScXMLDataPilotMembersContext::ScXMLDataPilotMembersContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ // has no attributes
+}
+
+ScXMLDataPilotMembersContext::~ScXMLDataPilotMembersContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotMembersContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotMembersElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER :
+ pContext = new ScXMLDataPilotMemberContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotMembersContext::EndElement()
+{
+}
+
+ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField),
+ bDisplay( sal_True ),
+ bDisplayDetails( sal_True ),
+ bHasName( false )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotMemberAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME :
+ {
+ sName = sValue;
+ bHasName = sal_True;
+ }
+ break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT:
+ {
+ maDisplayName = sValue;
+ }
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY :
+ {
+ bDisplay = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS :
+ {
+ bDisplayDetails = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDataPilotMemberContext::~ScXMLDataPilotMemberContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotMemberContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotMemberContext::EndElement()
+{
+ if (bHasName) // #i53407# don't check sName, empty name is allowed
+ {
+ ScDPSaveMember* pMember = new ScDPSaveMember(String(sName));
+ if (maDisplayName.getLength())
+ pMember->SetLayoutName(maDisplayName);
+ pMember->SetIsVisible(bDisplay);
+ pMember->SetShowDetails(bDisplayDetails);
+ pDataPilotField->AddMember(pMember);
+ }
+}
+
+ScXMLDataPilotGroupsContext::ScXMLDataPilotGroupsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ rtl::OUString sGroupSource;
+ double fStart(0.0);
+ double fEnd(0.0);
+ double fStep(0.0);
+ sal_Int32 nGroupPart(0);
+ sal_Bool bDateValue(false);
+ sal_Bool bAutoStart(sal_True);
+ sal_Bool bAutoEnd(sal_True);
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ (void)nPrefix; //! compare below!
+
+ if (IsXMLToken(aLocalName, XML_SOURCE_FIELD_NAME))
+ sGroupSource = sValue;
+ else if (IsXMLToken(aLocalName, XML_DATE_START))
+ {
+ bDateValue = sal_True;
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoStart = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDateTime(fStart, sValue);
+ bAutoStart = false;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_DATE_END))
+ {
+ bDateValue = sal_True;
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoEnd = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDateTime(fEnd, sValue);
+ bAutoEnd = false;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_START))
+ {
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoStart = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fStart, sValue);
+ bAutoStart = false;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_END))
+ {
+ if (IsXMLToken(sValue, XML_AUTO))
+ bAutoEnd = sal_True;
+ else
+ {
+ GetScImport().GetMM100UnitConverter().convertDouble(fEnd, sValue);
+ bAutoEnd = false;
+ }
+ }
+ else if (IsXMLToken(aLocalName, XML_STEP))
+ GetScImport().GetMM100UnitConverter().convertDouble(fStep, sValue);
+ else if (IsXMLToken(aLocalName, XML_GROUPED_BY))
+ {
+ if (IsXMLToken(sValue, XML_SECONDS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS;
+ else if (IsXMLToken(sValue, XML_MINUTES))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES;
+ else if (IsXMLToken(sValue, XML_HOURS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::HOURS;
+ else if (IsXMLToken(sValue, XML_DAYS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS;
+ else if (IsXMLToken(sValue, XML_MONTHS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS;
+ else if (IsXMLToken(sValue, XML_QUARTERS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS;
+ else if (IsXMLToken(sValue, XML_YEARS))
+ nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::YEARS;
+ }
+ }
+ pDataPilotField->SetGrouping(sGroupSource, fStart, fEnd, fStep, nGroupPart, bDateValue, bAutoStart, bAutoEnd);
+}
+
+ScXMLDataPilotGroupsContext::~ScXMLDataPilotGroupsContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_DATA_PILOT_GROUP))
+ pContext = new ScXMLDataPilotGroupContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupsContext::EndElement()
+{
+}
+
+ScXMLDataPilotGroupContext::ScXMLDataPilotGroupContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pTempDataPilotField) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotField(pTempDataPilotField)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NAME))
+ sName = sValue;
+ }
+ }
+}
+
+ScXMLDataPilotGroupContext::~ScXMLDataPilotGroupContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(rLName, XML_DATA_PILOT_MEMBER))
+ pContext = new ScXMLDataPilotGroupMemberContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupContext::EndElement()
+{
+ pDataPilotField->AddGroup(aMembers, sName);
+}
+
+ScXMLDataPilotGroupMemberContext::ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotGroupContext* pTempDataPilotGroup) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotGroup(pTempDataPilotGroup)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_NAME))
+ sName = sValue;
+ }
+ }
+}
+
+ScXMLDataPilotGroupMemberContext::~ScXMLDataPilotGroupMemberContext()
+{
+}
+
+SvXMLImportContext *ScXMLDataPilotGroupMemberContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDataPilotGroupMemberContext::EndElement()
+{
+ if (sName.getLength())
+ pDataPilotGroup->AddMember(sName);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx
new file mode 100644
index 000000000000..3ea89be0b68c
--- /dev/null
+++ b/sc/source/filter/xml/xmldpimp.hxx
@@ -0,0 +1,698 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLDPIMP_HXX
+#define SC_XMLDPIMP_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+
+#include "global.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "queryparam.hxx"
+
+#include <boost/unordered_set.hpp>
+
+class ScXMLImport;
+class ScDPSaveNumGroupDimension;
+class ScDPSaveGroupDimension;
+
+enum ScMySourceType
+{
+ SQL,
+ TABLE,
+ QUERY,
+ SERVICE,
+ CELLRANGE
+};
+
+class ScXMLDataPilotTablesContext : public SvXMLImportContext
+{
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotTablesContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDataPilotTablesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotTableContext : public SvXMLImportContext
+{
+ typedef ::boost::unordered_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet;
+ StringSet maHiddenMemberFields;
+
+ struct GrandTotalItem
+ {
+ ::rtl::OUString maDisplayName;
+ bool mbVisible;
+ GrandTotalItem();
+ };
+ ScDocument* pDoc;
+ ScDPObject* pDPObject;
+ ScDPSaveData* pDPSave;
+ ScDPDimensionSaveData* pDPDimSaveData;
+ GrandTotalItem maRowGrandTotal;
+ GrandTotalItem maColGrandTotal;
+ rtl::OUString sDataPilotTableName;
+ rtl::OUString sApplicationData;
+ rtl::OUString sGrandTotal;
+ rtl::OUString sDatabaseName;
+ rtl::OUString sSourceObject;
+ rtl::OUString sServiceName;
+ rtl::OUString sServiceSourceName;
+ rtl::OUString sServiceSourceObject;
+ rtl::OUString sServiceUsername;
+ rtl::OUString sServicePassword;
+ rtl::OUString sButtons;
+ rtl::OUString sSourceRangeName;
+ ScRange aSourceCellRangeAddress;
+ ScRange aTargetRangeAddress;
+ ScRange aFilterSourceRange;
+ ScAddress aFilterOutputPosition;
+ ScQueryParam aSourceQueryParam;
+ ScMySourceType nSourceType;
+ sal_uInt32 mnRowFieldCount;
+ sal_uInt32 mnColFieldCount;
+ sal_uInt32 mnPageFieldCount;
+ sal_uInt32 mnDataFieldCount;
+ sal_Bool bIsNative;
+ sal_Bool bIgnoreEmptyRows;
+ sal_Bool bIdentifyCategories;
+ sal_Bool bUseRegularExpression;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bFilterCopyOutputData;
+ sal_Bool bTargetRangeAddress;
+ sal_Bool bSourceCellRange;
+ sal_Bool bShowFilter;
+ sal_Bool bDrillDown;
+ sal_Bool bHeaderGridLayout;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDataPilotTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName);
+ void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; }
+ void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; }
+ void SetNative(const sal_Bool bValue) { bIsNative = bValue; }
+ void SetServiceName(const rtl::OUString& sValue) { sServiceName = sValue; }
+ void SetServiceSourceName(const rtl::OUString& sValue) { sServiceSourceName = sValue; }
+ void SetServiceSourceObject(const rtl::OUString& sValue) { sServiceSourceObject = sValue; }
+ void SetServiceUsername(const rtl::OUString& sValue) { sServiceUsername = sValue; }
+ void SetServicePassword(const rtl::OUString& sValue) { sServicePassword = sValue; }
+ void SetSourceRangeName(const rtl::OUString& sValue) { sSourceRangeName = sValue; bSourceCellRange = true; }
+ void SetSourceCellRangeAddress(const ScRange& aValue) { aSourceCellRangeAddress = aValue; bSourceCellRange = sal_True; }
+ void SetSourceQueryParam(const ScQueryParam& aValue) { aSourceQueryParam = aValue; }
+// void SetFilterUseRegularExpressions(const sal_Bool bValue) { aSourceQueryParam.bRegExp = bValue; }
+ void SetFilterOutputPosition(const ScAddress& aValue) { aFilterOutputPosition = aValue; }
+ void SetFilterCopyOutputData(const sal_Bool bValue) { bFilterCopyOutputData = bValue; }
+ void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; }
+// void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; }
+// void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; }
+ void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember);
+ void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim);
+ void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim);
+ void SetButtons();
+};
+
+class ScXMLDPSourceSQLContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceSQLContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceSQLContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPSourceTableContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPSourceQueryContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPSourceQueryContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDPSourceQueryContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceServiceContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceServiceContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLSourceServiceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext
+{
+ enum Orientation { COLUMN, ROW, BOTH, NONE };
+
+ ScXMLImport& GetScImport();
+
+ ScXMLDataPilotTableContext* mpTableContext;
+ ::rtl::OUString maDisplayName;
+ Orientation meOrientation;
+ bool mbVisible;
+
+public:
+ ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext );
+
+ virtual ~ScXMLDataPilotGrandTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceCellRangeContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceCellRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLSourceCellRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScXMLDataPilotGroup
+{
+ ::std::vector<rtl::OUString> aMembers;
+ rtl::OUString aName;
+};
+
+class ScXMLDataPilotFieldContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+ ScDPSaveDimension* pDim;
+
+ ::std::vector<ScXMLDataPilotGroup> aGroups;
+ rtl::OUString sGroupSource;
+ rtl::OUString sSelectedPage;
+ rtl::OUString sName;
+ double fStart;
+ double fEnd;
+ double fStep;
+ sal_Int32 nUsedHierarchy;
+ sal_Int32 nGroupPart;
+ sal_Int16 nFunction;
+ sal_Int16 nOrientation;
+ sal_Bool bShowEmpty:1;
+ sal_Bool bSelectedPage:1;
+ sal_Bool bIsGroupField:1;
+ sal_Bool bDateValue:1;
+ sal_Bool bAutoStart:1;
+ sal_Bool bAutoEnd:1;
+ bool mbHasHiddenMember:1;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pDataPilotTable);
+
+ virtual ~ScXMLDataPilotFieldContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); }
+ void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); }
+ void AddMember(ScDPSaveMember* pMember);
+ void SetSubTotalName(const ::rtl::OUString& rName);
+ void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); }
+ void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); }
+ void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); }
+ void SetLayoutInfo(const com::sun::star::sheet::DataPilotFieldLayoutInfo& aInfo) { if (pDim) pDim->SetLayoutInfo(&aInfo); }
+ void SetGrouping(const rtl::OUString& rGroupSource, const double& rStart, const double& rEnd, const double& rStep,
+ sal_Int32 nPart, sal_Bool bDate, sal_Bool bAutoSt, sal_Bool bAutoE)
+ {
+ bIsGroupField = sal_True;
+ sGroupSource = rGroupSource;
+ fStart = rStart;
+ fEnd = rEnd;
+ fStep = rStep;
+ nGroupPart = nPart;
+ bDateValue = bDate;
+ bAutoStart = bAutoSt;
+ bAutoEnd = bAutoE;
+ }
+ void AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName);
+};
+
+class ScXMLDataPilotFieldReferenceContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldReference aReference;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotFieldReferenceContext();
+};
+
+class ScXMLDataPilotLevelContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotLevelContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotLevelContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotDisplayInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldAutoShowInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotDisplayInfoContext();
+};
+
+class ScXMLDataPilotSortInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldSortInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotSortInfoContext();
+};
+
+class ScXMLDataPilotLayoutInfoContext : public SvXMLImportContext
+{
+// com::sun::star::sheet::DataPilotFieldLayoutInfo aInfo;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotLayoutInfoContext();
+};
+
+class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ sal_Int16 nFunctionCount;
+ sal_uInt16* pFunctions;
+ ::rtl::OUString maDisplayName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotFieldContext* GetDataPilotField() { return pDataPilotField; }
+
+ ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotSubTotalsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+ void AddFunction(sal_Int16 nFunction);
+ void SetDisplayName(const ::rtl::OUString& rName);
+};
+
+class ScXMLDataPilotSubTotalContext : public SvXMLImportContext
+{
+ ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotSubTotalContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals);
+
+ virtual ~ScXMLDataPilotSubTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotMembersContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotMembersContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotMembersContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotMemberContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ rtl::OUString sName;
+ rtl::OUString maDisplayName;
+ sal_Bool bDisplay;
+ sal_Bool bDisplayDetails;
+ sal_Bool bHasName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotMemberContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotMemberContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGroupsContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotGroupsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDataPilotGroupContext : public SvXMLImportContext
+{
+ ScXMLDataPilotFieldContext* pDataPilotField;
+
+ rtl::OUString sName;
+ ::std::vector<rtl::OUString> aMembers;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotFieldContext* pDataPilotField);
+
+ virtual ~ScXMLDataPilotGroupContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddMember(const rtl::OUString& sMember) { aMembers.push_back(sMember); }
+};
+
+class ScXMLDataPilotGroupMemberContext : public SvXMLImportContext
+{
+ ScXMLDataPilotGroupContext* pDataPilotGroup;
+
+ rtl::OUString sName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotGroupContext* pDataPilotGroup);
+
+ virtual ~ScXMLDataPilotGroupMemberContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
new file mode 100644
index 000000000000..17238ace3167
--- /dev/null
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -0,0 +1,1216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmldrani.hxx"
+#include "xmlimprt.hxx"
+#include "xmlfilti.hxx"
+#include "xmlsorti.hxx"
+#include "document.hxx"
+#include "globstr.hrc"
+#include "globalnames.hxx"
+#include "docuno.hxx"
+#include "dbcolect.hxx"
+#include "datauno.hxx"
+#include "attrib.hxx"
+#include "unonames.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/xml/sax/XLocator.hpp>
+
+#include <memory>
+
+#define SC_ENABLEUSERSORTLIST "EnableUserSortList"
+#define SC_USERSORTLISTINDEX "UserSortListIndex"
+#define SC_USERLIST "UserList"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ // has no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLDatabaseRangesContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATABASE_RANGE :
+ {
+ pContext = new ScXMLDatabaseRangeContext( GetScImport(), nPrefix,
+ rLName, xAttrList);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDatabaseRangesContext::EndElement()
+{
+}
+
+ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sDatabaseRangeName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)),
+ aSortSequence(),
+ eOrientation(table::TableOrientation_ROWS),
+ nRefresh(0),
+ nSubTotalsUserListIndex(0),
+ bContainsSort(false),
+ bContainsSubTotal(false),
+ bNative(sal_True),
+ bIsSelection(false),
+ bKeepFormats(false),
+ bMoveCells(false),
+ bStripData(false),
+ bContainsHeader(sal_True),
+ bAutoFilter(false),
+ bSubTotalsBindFormatsToContent(false),
+ bSubTotalsIsCaseSensitive(false),
+ bSubTotalsInsertPageBreaks(false),
+ bSubTotalsSortGroups(false),
+ bSubTotalsEnabledUserList(false),
+ bSubTotalsAscending(sal_True),
+ bFilterCopyOutputData(false),
+ bFilterIsCaseSensitive(false),
+ bFilterSkipDuplicates(false),
+ bFilterUseRegularExpressions(false),
+ bFilterConditionSourceRange(false),
+ meRangeType(GlobalNamed)
+{
+ nSourceType = sheet::DataImportMode_NONE;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_DATABASE_RANGE_ATTR_NAME :
+ {
+ sDatabaseRangeName = sValue;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION :
+ {
+ bIsSelection = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES :
+ {
+ bKeepFormats = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE :
+ {
+ bMoveCells = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA :
+ {
+ bStripData = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION :
+ {
+ if (IsXMLToken(sValue, XML_COLUMN))
+ eOrientation = table::TableOrientation_COLUMNS;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER :
+ {
+ bContainsHeader = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS :
+ {
+ bAutoFilter = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ sRangeAddress = sValue;
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY :
+ {
+ double fTime;
+ if( SvXMLUnitConverter::convertTime( fTime, sValue ) )
+ nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 );
+ }
+ break;
+ }
+ }
+
+ if (sDatabaseRangeName.matchAsciiL(STR_DB_LOCAL_NONAME, strlen(STR_DB_LOCAL_NONAME)))
+ meRangeType = SheetAnonymous;
+ else if (sDatabaseRangeName.matchAsciiL(STR_DB_GLOBAL_NONAME, strlen(STR_DB_GLOBAL_NONAME)))
+ meRangeType = GlobalAnonymous;
+}
+
+ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLDatabaseRangeContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_DATABASE_RANGE_SOURCE_SQL :
+ {
+ pContext = new ScXMLSourceSQLContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SOURCE_TABLE :
+ {
+ pContext = new ScXMLSourceTableContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SOURCE_QUERY :
+ {
+ pContext = new ScXMLSourceQueryContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER :
+ {
+ pContext = new ScXMLFilterContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_SORT :
+ {
+ bContainsSort = sal_True;
+ pContext = new ScXMLSortContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES :
+ {
+ bContainsSubTotal = sal_True;
+ pContext = new ScXMLSubTotalRulesContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
+{
+ ScDocument* pDoc = GetScImport().GetDocument();
+
+ sal_Int32 nOffset = 0;
+ ScRange aRange;
+ if (!ScRangeStringConverter::GetRangeFromString(aRange, sRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset))
+ return NULL;
+
+ ::std::auto_ptr<ScDBData> pData(
+ new ScDBData(rName, aRange.aStart.Tab(), aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row()));
+
+ pData->SetAutoFilter(bAutoFilter);
+ pData->SetKeepFmt(bKeepFormats);
+ pData->SetDoSize(bMoveCells);
+ pData->SetStripData(bStripData);
+
+ {
+ ScImportParam aParam;
+ aParam.bNative = bNative;
+ aParam.aDBName = sDatabaseName.isEmpty() ? sConnectionRessource : sDatabaseName;
+ aParam.aStatement = sSourceObject;
+ sheet::DataImportMode eMode = static_cast<sheet::DataImportMode>(nSourceType);
+ switch (eMode)
+ {
+ case sheet::DataImportMode_NONE:
+ aParam.bImport = false;
+ break;
+ case sheet::DataImportMode_SQL:
+ aParam.bImport = true;
+ aParam.bSql = true;
+ break;
+ case sheet::DataImportMode_TABLE:
+ aParam.bImport = true;
+ aParam.bSql = false;
+ aParam.nType = ScDbTable;
+ break;
+ case sheet::DataImportMode_QUERY:
+ aParam.bImport = true;
+ aParam.bSql = false;
+ aParam.nType = ScDbQuery;
+ break;
+ default:
+ OSL_FAIL("Unknown data import mode");
+ aParam.bImport = false;
+ }
+ pData->SetImportParam(aParam);
+ }
+
+ {
+ ScQueryParam aParam;
+ pData->GetQueryParam(aParam);
+ aParam.bByRow = (eOrientation == table::TableOrientation_ROWS);
+ aParam.bHasHeader = bContainsHeader;
+ aParam.bInplace = !bFilterCopyOutputData;
+ aParam.bCaseSens = bFilterIsCaseSensitive;
+ aParam.bDuplicate = !bFilterSkipDuplicates;
+ aParam.bRegExp = bFilterUseRegularExpressions;
+ aParam.nDestTab = aFilterOutputPosition.Sheet;
+ aParam.nDestCol = aFilterOutputPosition.Column;
+ aParam.nDestRow = aFilterOutputPosition.Row;
+ ScFilterDescriptorBase::fillQueryParam(aParam, pDoc, aFilterFields);
+
+ // Convert from relative to absolute column IDs for the fields. Calc
+ // core expects the field positions to be absolute column IDs.
+ SCCOLROW nStartPos = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+ for (size_t i = 0; i < MAXQUERY; ++i)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (!rEntry.bDoQuery)
+ break;
+ rEntry.nField += nStartPos;
+ }
+
+ pData->SetQueryParam(aParam);
+ }
+
+ if (bFilterConditionSourceRange)
+ {
+ ScRange aAdvSource;
+ ScUnoConversion::FillScRange(aAdvSource, aFilterConditionSourceRangeAddress);
+ pData->SetAdvancedQuerySource(&aAdvSource);
+ }
+
+ if (bContainsSort)
+ {
+ size_t nOldSize = aSortSequence.getLength();
+ aSortSequence.realloc(nOldSize + 1);
+ beans::PropertyValue aProperty;
+ aProperty.Name = OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT));
+ aProperty.Value <<= eOrientation;
+ aSortSequence[nOldSize] = aProperty;
+ ScSortParam aParam;
+ ScSortDescriptor::FillSortParam(aParam, aSortSequence);
+
+ SCCOLROW nStartPos = aParam.bByRow ? aRange.aStart.Col() : aRange.aStart.Row();
+ for (size_t i = 0; i < MAXSORT; ++i)
+ {
+ if (!aParam.bDoSort[i])
+ break;
+ aParam.nField[i] += nStartPos;
+ }
+
+ pData->SetSortParam(aParam);
+ }
+
+ if (bContainsSubTotal)
+ {
+ ScSubTotalParam aParam;
+ aParam.bIncludePattern = bSubTotalsBindFormatsToContent;
+ aParam.bUserDef = bSubTotalsEnabledUserList;
+ aParam.nUserIndex = nSubTotalsUserListIndex;
+ aParam.bPagebreak = bSubTotalsInsertPageBreaks;
+ aParam.bCaseSens = bSubTotalsIsCaseSensitive;
+ aParam.bDoSort = bSubTotalsSortGroups;
+ aParam.bAscending = bSubTotalsAscending;
+ aParam.bUserDef = bSubTotalsEnabledUserList;
+ aParam.nUserIndex = nSubTotalsUserListIndex;
+ std::vector <ScSubTotalRule>::iterator itr = aSubTotalRules.begin(), itrEnd = aSubTotalRules.end();
+ for (size_t nPos = 0; itr != itrEnd; ++itr, ++nPos)
+ {
+ if (nPos >= MAXSUBTOTAL)
+ break;
+
+ const uno::Sequence<sheet::SubTotalColumn>& rColumns = itr->aSubTotalColumns;
+ sal_Int32 nColCount = rColumns.getLength();
+ sal_Int16 nGroupColumn = itr->nSubTotalRuleGroupFieldNumber;
+ aParam.bGroupActive[nPos] = true;
+ aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+
+ SCCOL nCount = static_cast<SCCOL>(nColCount);
+ aParam.nSubTotals[nPos] = nCount;
+ if (nCount != 0)
+ {
+ aParam.pSubTotals[nPos] = new SCCOL[nCount];
+ aParam.pFunctions[nPos] = new ScSubTotalFunc[nCount];
+
+ const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
+ for (SCCOL i = 0; i < nCount; ++i)
+ {
+ aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
+ aParam.pFunctions[nPos][i] =
+ ScDataUnoConversion::GeneralToSubTotal( pAry[i].Function );
+ }
+ }
+ else
+ {
+ aParam.pSubTotals[nPos] = NULL;
+ aParam.pFunctions[nPos] = NULL;
+ }
+ }
+
+ pData->SetSubTotalParam(aParam);
+ }
+
+ if (pData->HasImportParam() && !pData->HasImportSelection())
+ {
+ pData->SetRefreshDelay(nRefresh);
+ pData->SetRefreshHandler(pDoc->GetDBCollection()->GetRefreshHandler());
+ pData->SetRefreshControl(pDoc->GetRefreshTimerControlAddress());
+ }
+
+ return pData.release();
+}
+
+void ScXMLDatabaseRangeContext::EndElement()
+{
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (!pDoc)
+ return;
+
+ if (meRangeType == SheetAnonymous)
+ {
+ OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
+ ::std::auto_ptr<ScDBData> pData(ConvertToDBData(aName));
+
+ if (pData.get())
+ {
+ ScRange aRange;
+ pData->GetArea(aRange);
+ if (pData->HasAutoFilter())
+ {
+ // Set autofilter flags so that the buttons get displayed.
+ pDoc->ApplyFlagsTab(
+ aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), SC_MF_AUTO);
+ }
+
+ pDoc->SetAnonymousDBData(aRange.aStart.Tab(), pData.release());
+ }
+ return;
+ }
+ else if (meRangeType == GlobalAnonymous)
+ {
+ OUString aName(RTL_CONSTASCII_USTRINGPARAM(STR_DB_GLOBAL_NONAME));
+ ::std::auto_ptr<ScDBData> pData(ConvertToDBData(aName));
+
+ if (pData.get())
+ {
+ if (pData->HasAutoFilter())
+ {
+ // Set autofilter flags so that the buttons get displayed.
+ ScRange aRange;
+ pData->GetArea(aRange);
+ pDoc->ApplyFlagsTab(
+ aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), SC_MF_AUTO);
+ pDoc->SetAnonymousDBData(aRange.aStart.Tab(), pData.release());
+ }
+ else
+ pDoc->GetDBCollection()->insertAnonRange(pData.release());
+ }
+ return;
+ }
+
+ if (GetScImport().GetModel().is())
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet( GetScImport().GetModel(), uno::UNO_QUERY );
+ if (xPropertySet.is())
+ {
+ uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY);
+ if (xDatabaseRanges.is())
+ {
+ table::CellRangeAddress aCellRangeAddress;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aCellRangeAddress, sRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ sal_Bool bInsert(sal_True);
+ try
+ {
+ xDatabaseRanges->addNewByName(sDatabaseRangeName, aCellRangeAddress);
+ }
+ catch ( uno::RuntimeException& rRuntimeException )
+ {
+ bInsert = false;
+ rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("DatabaseRange "));
+ sErrorMessage += sDatabaseRangeName;
+ sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" could not be created with the range "));
+ sErrorMessage += sRangeAddress;
+ uno::Sequence<rtl::OUString> aSeq(1);
+ aSeq[0] = sErrorMessage;
+ uno::Reference<xml::sax::XLocator> xLocator;
+ GetScImport().SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rRuntimeException.Message, xLocator);
+ }
+ if (bInsert)
+ {
+ uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY);
+ if (xDatabaseRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY);
+ if (xDatabaseRangePropertySet.is())
+ {
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)), uno::makeAny(bKeepFormats));
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)), uno::makeAny(bMoveCells));
+ xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)), uno::makeAny(bStripData));
+ }
+ uno::Sequence <beans::PropertyValue> aImportDescriptor(xDatabaseRange->getImportDescriptor());
+ sal_Int32 nImportProperties = aImportDescriptor.getLength();
+ for (sal_Int16 i = 0; i < nImportProperties; ++i)
+ {
+ if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME)))
+ {
+ if (sDatabaseName.getLength())
+ {
+ aImportDescriptor[i].Value <<= sDatabaseName;
+ }
+ else
+ {
+ aImportDescriptor[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES));
+ aImportDescriptor[i].Value <<= sConnectionRessource;
+ }
+ }
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ)))
+ aImportDescriptor[i].Value <<= sSourceObject;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE)))
+ aImportDescriptor[i].Value <<= nSourceType;
+ else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE)))
+ aImportDescriptor[i].Value <<= bNative;
+ }
+ ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+ sal_uInt16 nIndex;
+ pDBCollection->SearchName(sDatabaseRangeName, nIndex);
+ ScDBData* pDBData = (*pDBCollection)[nIndex];
+ pDBData->SetImportSelection(bIsSelection);
+ pDBData->SetAutoFilter(bAutoFilter);
+ if (bAutoFilter)
+ pDoc->ApplyFlagsTab( static_cast<SCCOL>(aCellRangeAddress.StartColumn), static_cast<SCROW>(aCellRangeAddress.StartRow),
+ static_cast<SCCOL>(aCellRangeAddress.EndColumn), static_cast<SCROW>(aCellRangeAddress.StartRow),
+ aCellRangeAddress.Sheet, SC_MF_AUTO );
+ ScImportParam aImportParam;
+ ScImportDescriptor::FillImportParam(aImportParam, aImportDescriptor);
+ pDBData->SetImportParam(aImportParam);
+ if (bContainsSort)
+ {
+ sal_uInt32 nOldSize(aSortSequence.getLength());
+ aSortSequence.realloc(nOldSize + 1);
+ beans::PropertyValue aProperty;
+ aProperty.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT));
+ aProperty.Value <<= eOrientation;
+ aSortSequence[nOldSize] = aProperty;
+ ScSortParam aSortParam;
+ ScSortDescriptor::FillSortParam(aSortParam, aSortSequence);
+
+ //#98317#; until now the Fields are relative to the left top edge of the range, but the
+ // core wants to have the absolute position (column/row)
+ SCCOLROW nFieldStart = aSortParam.bByRow ? static_cast<SCCOLROW>(aCellRangeAddress.StartColumn) : static_cast<SCCOLROW>(aCellRangeAddress.StartRow);
+ for (sal_uInt16 i = 0; i < MAXSORT; ++i)
+ {
+ if (aSortParam.bDoSort[i])
+ aSortParam.nField[i] += nFieldStart;
+ }
+
+ pDBData->SetSortParam(aSortParam);
+ }
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if (xSheetFilterDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xFilterPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
+ if (xFilterPropertySet.is())
+ {
+ sal_Bool bOrientation(table::TableOrientation_COLUMNS == eOrientation);
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)), uno::makeAny(bOrientation));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)), uno::makeAny(bContainsHeader));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)), uno::makeAny(bFilterCopyOutputData));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bFilterIsCaseSensitive));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)), uno::makeAny(bFilterSkipDuplicates));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX)), uno::makeAny(bFilterUseRegularExpressions));
+ xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS)), uno::makeAny(aFilterOutputPosition));
+ }
+ xSheetFilterDescriptor->setFilterFields2(aFilterFields);
+ if (bFilterConditionSourceRange)
+ {
+ ScRange aAdvSource;
+ ScUnoConversion::FillScRange( aAdvSource, aFilterConditionSourceRangeAddress );
+ pDBData->SetAdvancedQuerySource(&aAdvSource);
+ }
+ }
+ if (bContainsSubTotal)
+ {
+ uno::Reference <sheet::XSubTotalDescriptor> xSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor());
+ if (xSubTotalDescriptor.is())
+ {
+ uno::Reference <beans::XPropertySet> xSubTotalPropertySet (xSubTotalDescriptor, uno::UNO_QUERY);
+ if( xSubTotalPropertySet.is())
+ {
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)), uno::makeAny(bSubTotalsBindFormatsToContent));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST)), uno::makeAny(bSubTotalsEnabledUserList));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX)), uno::makeAny(nSubTotalsUserListIndex));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)), uno::makeAny(bSubTotalsInsertPageBreaks));
+ xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bSubTotalsIsCaseSensitive));
+ }
+ ScSubTotalParam aSubTotalParam;
+ aSubTotalParam.bDoSort = bSubTotalsSortGroups;
+ aSubTotalParam.bAscending = bSubTotalsAscending;
+ aSubTotalParam.bUserDef = bSubTotalsEnabledUserList;
+ aSubTotalParam.nUserIndex = nSubTotalsUserListIndex;
+ pDBData->SetSubTotalParam(aSubTotalParam);
+ std::vector < ScSubTotalRule >::iterator aItr(aSubTotalRules.begin());
+ while (!aSubTotalRules.empty())
+ {
+ xSubTotalDescriptor->addNew(aItr->aSubTotalColumns, aItr->nSubTotalRuleGroupFieldNumber);
+ aItr = aSubTotalRules.erase(aItr);
+ }
+ }
+ }
+ if ( pDBData->HasImportParam() && !pDBData->HasImportSelection() )
+ {
+ pDBData->SetRefreshDelay( nRefresh );
+ pDBData->SetRefreshHandler( pDBCollection->GetRefreshHandler() );
+ pDBData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT :
+ {
+ pDatabaseRangeContext->SetNative(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL);
+}
+
+ScXMLSourceSQLContext::~ScXMLSourceSQLContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceSQLContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceSQLContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE);
+}
+
+ScXMLSourceTableContext::~ScXMLSourceTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceTableContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceTableContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME :
+ {
+ sDBName = sValue;
+ }
+ break;
+ case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME :
+ {
+ pDatabaseRangeContext->SetSourceObject(sValue);
+ }
+ break;
+ }
+ }
+ pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY);
+}
+
+ScXMLSourceQueryContext::~ScXMLSourceQueryContext()
+{
+}
+
+SvXMLImportContext *ScXMLSourceQueryContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if ( nPrefix == XML_NAMESPACE_FORM )
+ {
+ if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0))
+ {
+ pContext = new ScXMLConResContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSourceQueryContext::EndElement()
+{
+ if (sDBName.getLength())
+ pDatabaseRangeContext->SetDatabaseName(sDBName);
+}
+
+ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext( pTempDatabaseRangeContext )
+{
+ rtl::OUString sConRes;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ rtl::OUString sValue = xAttrList->getValueByIndex( i );
+
+ if (nPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ sConRes = sValue;
+ }
+ }
+ if (sConRes.getLength())
+ pDatabaseRangeContext->SetConnectionRessource(sConRes);
+}
+
+ScXMLConResContext::~ScXMLConResContext()
+{
+}
+
+SvXMLImportContext *ScXMLConResContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLConResContext::EndElement()
+{
+}
+
+ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT :
+ {
+ pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE :
+ {
+ pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE :
+ {
+ pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(sValue, XML_TRUE));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalRulesContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULES_SORT_GROUPS :
+ {
+ pContext = new ScXMLSortGroupsContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ break;
+ case XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE :
+ {
+ pContext = new ScXMLSubTotalRuleContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pDatabaseRangeContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalRulesContext::EndElement()
+{
+}
+
+ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ pDatabaseRangeContext->SetSubTotalsSortGroups(sal_True);
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSortGroupsAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE :
+ {
+ if (sValue.getLength() > 8)
+ {
+ rtl::OUString sTemp = sValue.copy(0, 8);
+ if (sTemp.compareToAscii(SC_USERLIST) == 0)
+ {
+ pDatabaseRangeContext->SetSubTotalsEnabledUserList(sal_True);
+ sTemp = sValue.copy(8);
+ pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(sTemp.toInt32()));
+ }
+ else
+ {
+ //if (IsXMLToken(sValue, XML_AUTOMATIC))
+ //aSortField.FieldType = util::SortFieldType_AUTOMATIC;
+ // is not supported by StarOffice
+ }
+ }
+ else
+ {
+ //if (IsXMLToken(sValue, XML_TEXT))
+ //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
+ // is not supported by StarOffice
+ //else if (IsXMLToken(sValue, XML_NUMBER))
+ //aSortField.FieldType = util::SortFieldType_NUMERIC;
+ // is not supported by StarOffice
+ }
+ }
+ break;
+ case XML_TOK_SORT_GROUPS_ATTR_ORDER :
+ {
+ if (IsXMLToken(sValue, XML_ASCENDING))
+ pDatabaseRangeContext->SetSubTotalsAscending(sal_True);
+ else
+ pDatabaseRangeContext->SetSubTotalsAscending(false);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSortGroupsContext::~ScXMLSortGroupsContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortGroupsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSortGroupsContext::EndElement()
+{
+}
+
+ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER :
+ {
+ aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(sValue.toInt32());
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalRuleContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleElemTokenMap();
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD :
+ {
+ pContext = new ScXMLSubTotalFieldContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalRuleContext::EndElement()
+{
+ if (pDatabaseRangeContext)
+ pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule);
+}
+
+ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pSubTotalRuleContext(pTempSubTotalRuleContext)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRuleSubTotalFieldAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER :
+ {
+ sFieldNumber = sValue;
+ }
+ break;
+ case XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION :
+ {
+ sFunction = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext()
+{
+}
+
+SvXMLImportContext *ScXMLSubTotalFieldContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSubTotalFieldContext::EndElement()
+{
+ sheet::SubTotalColumn aSubTotalColumn;
+ aSubTotalColumn.Column = sFieldNumber.toInt32();
+ aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction );
+ pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx
new file mode 100644
index 000000000000..10d1c77d79c0
--- /dev/null
+++ b/sc/source/filter/xml/xmldrani.hxx
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLDRANI_HXX
+#define SC_XMLDRANI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+
+class ScDBData;
+class ScXMLImport;
+
+class ScXMLDatabaseRangesContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDatabaseRangesContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDatabaseRangesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+struct ScSubTotalRule
+{
+ sal_Int16 nSubTotalRuleGroupFieldNumber;
+ com::sun::star::uno::Sequence <com::sun::star::sheet::SubTotalColumn> aSubTotalColumns;
+};
+
+class ScXMLDatabaseRangeContext : public SvXMLImportContext
+{
+ enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous };
+
+ rtl::OUString sDatabaseRangeName;
+ rtl::OUString sConnectionRessource;
+ rtl::OUString sRangeAddress;
+ rtl::OUString sDatabaseName;
+ rtl::OUString sSourceObject;
+ com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortSequence;
+ com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields;
+ std::vector < ScSubTotalRule > aSubTotalRules;
+ com::sun::star::table::CellAddress aFilterOutputPosition;
+ com::sun::star::table::CellRangeAddress aFilterConditionSourceRangeAddress;
+ com::sun::star::sheet::DataImportMode nSourceType;
+ com::sun::star::table::TableOrientation eOrientation;
+ sal_Int32 nRefresh;
+ sal_Int16 nSubTotalsUserListIndex;
+ sal_Int16 nSubTotalRuleGroupFieldNumber;
+ sal_Bool bContainsSort;
+ sal_Bool bContainsSubTotal;
+ sal_Bool bNative;
+ sal_Bool bIsSelection;
+ sal_Bool bKeepFormats;
+ sal_Bool bMoveCells;
+ sal_Bool bStripData;
+ sal_Bool bContainsHeader;
+ sal_Bool bAutoFilter;
+ sal_Bool bSubTotalsBindFormatsToContent;
+ sal_Bool bSubTotalsIsCaseSensitive;
+ sal_Bool bSubTotalsInsertPageBreaks;
+ sal_Bool bSubTotalsSortGroups;
+ sal_Bool bSubTotalsEnabledUserList;
+ sal_Bool bSubTotalsAscending;
+ sal_Bool bFilterCopyOutputData;
+ sal_Bool bFilterIsCaseSensitive;
+ sal_Bool bFilterSkipDuplicates;
+ sal_Bool bFilterUseRegularExpressions;
+ sal_Bool bFilterConditionSourceRange;
+ RangeType meRangeType;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ ScDBData* ConvertToDBData(const ::rtl::OUString& rName);
+
+public:
+
+ ScXMLDatabaseRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList);
+
+ virtual ~ScXMLDatabaseRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetDatabaseName(const rtl::OUString sTempDatabaseName) { sDatabaseName = sTempDatabaseName; }
+ void SetConnectionRessource(const rtl::OUString sTempConRes) { sConnectionRessource = sTempConRes; }
+ void SetSourceObject(const rtl::OUString sTempSourceObject) { sSourceObject = sTempSourceObject; }
+ void SetSourceType(const com::sun::star::sheet::DataImportMode nTempSourceType) { nSourceType = nTempSourceType; }
+ void SetNative(const sal_Bool bTempNative) { bNative = bTempNative; }
+ void SetSubTotalsBindFormatsToContent(const sal_Bool bTemp ) { bSubTotalsBindFormatsToContent = bTemp; }
+ void SetSubTotalsIsCaseSensitive(const sal_Bool bTemp) { bSubTotalsIsCaseSensitive = bTemp; }
+ void SetSubTotalsInsertPageBreaks(const sal_Bool bTemp) { bSubTotalsInsertPageBreaks = bTemp; }
+ void SetSubTotalsEnabledUserList(const sal_Bool bTemp) { bSubTotalsEnabledUserList = bTemp; }
+ void SetSubTotalsUserListIndex(const sal_Int16 nTemp) { nSubTotalsUserListIndex = nTemp; }
+ void SetSubTotalsAscending(const sal_Bool bTemp) { bSubTotalsAscending = bTemp; }
+ void SetSubTotalsSortGroups(const sal_Bool bTemp) { bSubTotalsSortGroups = bTemp; }
+ void AddSubTotalRule(const ScSubTotalRule& rRule) { aSubTotalRules.push_back(rRule); }
+ void SetSortSequence(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& aTempSortSequence) { aSortSequence = aTempSortSequence; }
+ void SetFilterCopyOutputData(const sal_Bool bTemp) { bFilterCopyOutputData = bTemp; }
+ void SetFilterIsCaseSensitive(const sal_Bool bTemp) { bFilterIsCaseSensitive = bTemp; }
+ void SetFilterSkipDuplicates(const sal_Bool bTemp) { bFilterSkipDuplicates = bTemp; }
+ void SetFilterUseRegularExpressions(const sal_Bool bTemp) { bFilterUseRegularExpressions = bTemp; }
+ void SetFilterFields(const com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2>& aTemp) { aFilterFields = aTemp; }
+ void SetFilterOutputPosition(const com::sun::star::table::CellAddress& aTemp) { aFilterOutputPosition = aTemp; }
+ void SetFilterConditionSourceRangeAddress(const com::sun::star::table::CellRangeAddress& aTemp) { aFilterConditionSourceRangeAddress = aTemp;
+ bFilterConditionSourceRange = sal_True; }
+};
+
+class ScXMLSourceSQLContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceSQLContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceSQLContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceTableContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSourceQueryContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ rtl::OUString sDBName;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSourceQueryContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSourceQueryContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLConResContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLConResContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLConResContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSubTotalRulesContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalRulesContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSubTotalRulesContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSortGroupsContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortGroupsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSortGroupsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLSubTotalRuleContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+ ScSubTotalRule aSubTotalRule;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalRuleContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSubTotalRuleContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddSubTotalColumn(const com::sun::star::sheet::SubTotalColumn aSubTotalColumn)
+ { aSubTotalRule.aSubTotalColumns.realloc(aSubTotalRule.aSubTotalColumns.getLength() + 1);
+ aSubTotalRule.aSubTotalColumns[aSubTotalRule.aSubTotalColumns.getLength() - 1] = aSubTotalColumn; }
+};
+
+class ScXMLSubTotalFieldContext : public SvXMLImportContext
+{
+ ScXMLSubTotalRuleContext* pSubTotalRuleContext;
+ rtl::OUString sFieldNumber;
+ rtl::OUString sFunction;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSubTotalFieldContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSubTotalRuleContext* pSubTotalRuleContext);
+
+ virtual ~ScXMLSubTotalFieldContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
new file mode 100644
index 000000000000..44ca47e74bc3
--- /dev/null
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -0,0 +1,4459 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+
+#include "xmlexprt.hxx"
+#include "XMLConverter.hxx"
+#include "xmlstyle.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+#include "olinetab.hxx"
+#include "cellsuno.hxx"
+#include "cell.hxx"
+#include "rangenam.hxx"
+#include "XMLTableMasterPageExport.hxx"
+#include "drwlayer.hxx"
+#include "XMLExportDataPilot.hxx"
+#include "XMLExportDatabaseRanges.hxx"
+#include "XMLExportDDELinks.hxx"
+#include "XMLExportIterator.hxx"
+#include "XMLColumnRowGroupExport.hxx"
+#include "XMLStylesExportHelper.hxx"
+#include "XMLChangeTrackingExportHelper.hxx"
+#include "sheetdata.hxx"
+#include "docoptio.hxx"
+#include "XMLExportSharedData.hxx"
+#include "chgviset.hxx"
+#include "docuno.hxx"
+#include "textuno.hxx"
+#include "chartlis.hxx"
+#include "scitems.hxx"
+#include "docpool.hxx"
+#include "userdat.hxx"
+#include "dociter.hxx"
+#include "chgtrack.hxx"
+#include "rangeutl.hxx"
+#include "convuno.hxx"
+#include "postit.hxx"
+#include "externalrefmgr.hxx"
+#include "editutil.hxx"
+#include "tabprotection.hxx"
+#include "cachedattraccess.hxx"
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/txtparae.hxx>
+#include <xmloff/xmlcnitm.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/XMLEventExport.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <tools/debug.hxx>
+#include "tools/color.hxx"
+#include <rtl/math.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/unoshape.hxx>
+#include <comphelper/extract.hxx>
+#include <editeng/eeitem.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/sheet/XLabelRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+#include <com/sun/star/form/XFormsSupplier2.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+#include "XMLCodeNameProvider.hxx"
+
+#include <sfx2/objsh.hxx>
+
+#include <vector>
+
+//! not found in unonames.hxx
+#define SC_STANDARDFORMAT "StandardFormat"
+#define SC_LAYERID "LayerID"
+
+#define SC_DEFAULT_TABLE_COUNT 3
+#define SC_VIEWCHANGES_COUNT 13
+#define SC_SHOW_CHANGES 0
+#define SC_SHOW_ACCEPTED_CHANGES 1
+#define SC_SHOW_REJECTED_CHANGES 2
+#define SC_SHOW_CHANGES_BY_DATETIME 3
+#define SC_SHOW_CHANGES_BY_DATETIME_MODE 4
+#define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5
+#define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6
+#define SC_SHOW_CHANGES_BY_AUTHOR 7
+#define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8
+#define SC_SHOW_CHANGES_BY_COMMENT 9
+#define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10
+#define SC_SHOW_CHANGES_BY_RANGES 11
+#define SC_SHOW_CHANGES_BY_RANGES_LIST 12
+
+using namespace formula;
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::std::vector;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+
+//----------------------------------------------------------------------------
+
+namespace
+{
+OUString lcl_RangeSequenceToString(
+ const uno::Sequence< OUString > & rRanges,
+ const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter )
+{
+ OUStringBuffer aResult;
+ const sal_Int32 nMaxIndex( rRanges.getLength() - 1 );
+ const sal_Unicode cSep( sal_Char(' '));
+ for( sal_Int32 i=0; i<=nMaxIndex; ++i )
+ {
+ OUString aRange( rRanges[i] );
+ if( xFormatConverter.is())
+ aRange = xFormatConverter->convertRangeToXML( aRange );
+ aResult.append( aRange );
+ if( i < nMaxIndex )
+ aResult.append( cSep );
+ }
+ return aResult.makeStringAndClear();
+}
+
+OUString lcl_GetRawString( ScDocument* pDoc, const ScAddress& rPos )
+{
+ // return text/edit cell string content, with line feeds in edit cells
+
+ String aVal; // document uses tools-strings
+ if (pDoc)
+ {
+ ScBaseCell* pCell = pDoc->GetCell( rPos );
+ if (pCell)
+ {
+ CellType eType = pCell->GetCellType();
+ if ( eType == CELLTYPE_STRING )
+ static_cast<ScStringCell*>(pCell)->GetString(aVal); // string cell: content
+ else if ( eType == CELLTYPE_EDIT )
+ {
+ // edit cell: text with line breaks
+ const EditTextObject* pData = static_cast<ScEditCell*>(pCell)->GetData();
+ if (pData)
+ {
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ aVal = rEngine.GetText( LINEEND_LF );
+ }
+ }
+ }
+ }
+ return aVal;
+}
+} // anonymous namespace
+
+//----------------------------------------------------------------------------
+
+OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_getImplementationName() );
+ return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_ALL );
+}
+
+OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLMetaExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Meta_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_META );
+}
+
+OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLStylesExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Styles_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLContentExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Content_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLSettingsExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOOoExport_Settings_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_SETTINGS );
+}
+
+// Oasis Filter
+
+OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_ALL|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Meta_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_META|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Styles_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Content_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS|EXPORT_OASIS);
+}
+
+OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsExporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLOasisExport_Settings_getImplementationName() );
+ const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_SETTINGS|EXPORT_OASIS);
+}
+//----------------------------------------------------------------------------
+
+class ScXMLShapeExport : public XMLShapeExport
+{
+public:
+ ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
+ ~ScXMLShapeExport();
+
+ /** is called before a shape element for the given XShape is exported */
+ virtual void onExport( const uno::Reference < drawing::XShape >& xShape );
+};
+
+ScXMLShapeExport::~ScXMLShapeExport()
+{
+}
+
+void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape )
+{
+ uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ {
+ sal_Int16 nLayerID = 0;
+ if( (xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ))) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) )
+ GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+sal_Int16 ScXMLExport::GetFieldUnit()
+{
+ com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xProperties(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" )) ),
+ com::sun::star::uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ sal_Int16 nFieldUnit = 0;
+ if (xProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Metric"))) >>= nFieldUnit)
+ return nFieldUnit;
+ }
+ return 0;
+}
+
+
+// #110680#
+ScXMLExport::ScXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nExportFlag)
+: SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ),
+ pDoc(NULL),
+ nSourceStreamPos(0),
+ pNumberFormatAttributesExportHelper(NULL),
+ pSharedData(NULL),
+ pColumnStyles(NULL),
+ pRowStyles(NULL),
+ pCellStyles(NULL),
+ pRowFormatRanges(NULL),
+ aTableStyles(),
+ pGroupColumns (NULL),
+ pGroupRows (NULL),
+ pDefaults(NULL),
+ pChartListener(NULL),
+ pCurrentCell(NULL),
+ pMergedRangesContainer(NULL),
+ pValidationsContainer(NULL),
+ pCellsItr(NULL),
+ pChangeTrackingExportHelper(NULL),
+ sLayerID(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID )),
+ sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")),
+ nOpenRow(-1),
+ nProgressCount(0),
+ nCurrentTable(0),
+ bHasRowHeader(false),
+ bRowHeaderOpen(false),
+ mbShowProgress( false )
+{
+ if (getExportFlags() & EXPORT_CONTENT)
+ {
+ pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP);
+ pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP);
+ pColumnStyles = new ScColumnStyles();
+ pRowStyles = new ScRowStyles();
+ pRowFormatRanges = new ScRowFormatRanges();
+ pMergedRangesContainer = new ScMyMergedRangesContainer();
+ pValidationsContainer = new ScMyValidationsContainer();
+ pCellsItr = new ScMyNotEmptyCellsIterator(*this);
+ pDefaults = new ScMyDefaultStyles();
+ }
+ pCellStyles = new ScFormatRangeStyles();
+
+ // document is not set here - create ScChangeTrackingExportHelper later
+
+ xScPropHdlFactory = new XMLScPropHdlFactory;
+ xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
+ xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
+ xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesProperties, xScPropHdlFactory);
+ xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesProperties, xScPropHdlFactory);
+ xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper);
+ xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
+ xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper);
+ xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper);
+ xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper);
+
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)),
+ xCellStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)),
+ xColumnStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)),
+ xRowStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)));
+ GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)),
+ xTableStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX)));
+
+ if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 )
+ {
+ // This name is reserved for the external ref cache tables. This
+ // should not conflict with user-defined styles since this name is
+ // used for a table style which is not available in the UI.
+ sExternalRefTabStyleName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ta_extref"));
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName);
+
+ sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME));
+ sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME));
+ sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED));
+ sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA));
+ sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE));
+ sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE));
+ sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL));
+ sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL));
+ sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN));
+ sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW));
+ sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE));
+ sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
+ }
+}
+
+
+ScXMLExport::~ScXMLExport()
+{
+ if (pGroupColumns)
+ delete pGroupColumns;
+ if (pGroupRows)
+ delete pGroupRows;
+ if (pColumnStyles)
+ delete pColumnStyles;
+ if (pRowStyles)
+ delete pRowStyles;
+ if (pCellStyles)
+ delete pCellStyles;
+ if (pRowFormatRanges)
+ delete pRowFormatRanges;
+ if (pMergedRangesContainer)
+ delete pMergedRangesContainer;
+ if (pValidationsContainer)
+ delete pValidationsContainer;
+ if (pChangeTrackingExportHelper)
+ delete pChangeTrackingExportHelper;
+ if (pChartListener)
+ delete pChartListener;
+ if (pCellsItr)
+ delete pCellsItr;
+ if (pDefaults)
+ delete pDefaults;
+ if (pNumberFormatAttributesExportHelper)
+ delete pNumberFormatAttributesExportHelper;
+}
+
+void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
+{
+ xSourceStream = xNewStream;
+
+ if ( xSourceStream.is() )
+ {
+ // make sure it's a plain UTF-8 stream as written by OOo itself
+
+ const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ sal_Int32 nLen = strlen(pXmlHeader);
+
+ uno::Sequence<sal_Int8> aFileStart(nLen);
+ sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
+
+ if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
+ {
+ // invalid - ignore stream, save normally
+ xSourceStream.clear();
+ }
+ else
+ {
+ // keep track of the bytes already read
+ nSourceStreamPos = nRead;
+
+ const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ if (pSheetData)
+ {
+ // add the loaded namespaces to the name space map
+
+ if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
+ {
+ // conflicts in the namespaces - ignore the stream, save normally
+ xSourceStream.clear();
+ }
+ }
+ }
+ }
+}
+
+sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
+{
+ NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
+ if (itr == aNumFmtIndexMap.end())
+ return -1;
+
+ return itr->second;
+}
+
+sal_Bool ScXMLExport::HasDrawPages(uno::Reference <sheet::XSpreadsheetDocument>& xDoc)
+{
+ uno::Reference <beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY );
+ return (xDocProps.is() && ::cppu::any2bool( xDocProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_HASDRAWPAGES))) ));
+}
+
+void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ nTableCount = xIndex->getCount();
+ if (!pSharedData)
+ CreateSharedData(nTableCount);
+ pCellStyles->AddNewTable(nTableCount - 1);
+ pDoc->InitializeAllNoteCaptions( true );
+ if (HasDrawPages(xSpreadDoc))
+ {
+ rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
+ for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xDrawPageSupplier.is())
+ {
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage());
+ ScMyDrawPage aDrawPage;
+ aDrawPage.bHasForms = false;
+ aDrawPage.xDrawPage.set(xDrawPage);
+ pSharedData->AddDrawPage(aDrawPage, nTable);
+ uno::Reference<container::XIndexAccess> xShapesIndex (xDrawPage, uno::UNO_QUERY);
+ if (xShapesIndex.is())
+ {
+ sal_Int32 nShapes(xShapesIndex->getCount());
+ for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape)
+ {
+ uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
+ if( xShapeProp.is() )
+ {
+ sal_Int16 nLayerID = 0;
+ if( xShapeProp->getPropertyValue(sLayerID) >>= nLayerID )
+ {
+ if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) )
+ CollectInternalShape( xShape );
+ else
+ {
+ ++nShapesCount;
+ if (SvxShape* pShapeImp = SvxShape::getImplementation(xShape))
+ {
+ if (SdrObject *pSdrObj = pShapeImp->GetSdrObject())
+ {
+ if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjData( pSdrObj ))
+ {
+ ScMyShape aMyShape;
+ aMyShape.aAddress = pAnchor->maStart;
+ aMyShape.aEndAddress = pAnchor->maEnd;
+ aMyShape.nEndX = pAnchor->maEndOffset.X();
+ aMyShape.nEndY = pAnchor->maEndOffset.Y();
+ aMyShape.xShape = xShape;
+ pSharedData->AddNewShape(aMyShape);
+ pSharedData->SetLastColumn(nTable, pAnchor->maStart.Col());
+ pSharedData->SetLastRow(nTable, pAnchor->maStart.Row());
+ }
+ else
+ pSharedData->AddTableShape(nTable, xShape);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ sal_Int32 nRef(nCellCount + (2 * nTableCount) + (2 * nShapesCount));
+ GetProgressBarHelper()->SetReference(nRef);
+ GetProgressBarHelper()->SetValue(0);
+}
+
+void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount)
+{
+ // #i84077# To avoid compiler warnings about uninitialized aShapeItr,
+ // it's initialized using this dummy list. The iterator contains shapes
+ // from all sheets, so it can't be declared inside the nTable loop where
+ // it is used.
+ ScMyShapeList aDummyInitList;
+
+ pSharedData->SortShapesContainer();
+ pSharedData->SortNoteShapes();
+ const ScMyShapeList* pShapeList(NULL);
+ ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end();
+ if (pSharedData->GetShapesContainer())
+ {
+ pShapeList = pSharedData->GetShapesContainer()->GetShapes();
+ aShapeItr = pShapeList->begin();
+ }
+ if (pSharedData->HasDrawPage())
+ {
+ for (SCTAB nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable));
+ uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY);
+
+ if (xShapes.is())
+ {
+ GetShapeExport()->seekShapes(xShapes);
+ uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
+ if( xFormsSupplier.is() && xFormsSupplier->hasForms() )
+ {
+ GetFormExport()->examineForms(xDrawPage);
+ pSharedData->SetDrawPageHasForms(nTable, sal_True);
+ }
+ ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
+ if (pTableShapes)
+ {
+ ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin());
+ ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end());
+ while (aItr != aEndItr)
+ {
+ GetShapeExport()->collectShapeAutoStyles(*aItr);
+ IncrementProgressBar(false);
+ ++aItr;
+ }
+ }
+ if (pShapeList)
+ {
+ ScMyShapeList::const_iterator aEndItr(pShapeList->end());
+ while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable))
+ {
+ GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape);
+ IncrementProgressBar(false);
+ ++aShapeItr;
+ }
+ }
+ const ScMyNoteShapeList* pNoteShapes = NULL;
+ ScMyNoteShapeList::const_iterator aNoteShapeItr;
+ ScMyNoteShapeList::const_iterator aNoteShapeEndItr;
+ if (pSharedData->GetNoteShapes())
+ {
+ pNoteShapes = pSharedData->GetNoteShapes()->GetNotes();
+ if (pNoteShapes)
+ {
+ aNoteShapeItr = pNoteShapes->begin();
+ aNoteShapeEndItr = pNoteShapes->end();
+ }
+ }
+ if (pNoteShapes)
+ {
+ while (aNoteShapeItr != aNoteShapeEndItr)
+ {
+ if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable)
+ GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape);
+ ++aNoteShapeItr;
+ }
+ }
+ }
+ }
+ }
+ pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added
+}
+
+void ScXMLExport::_ExportMeta()
+{
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ GetAutoStylePool()->ClearEntries();
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+
+ uno::Sequence<beans::NamedValue> stats(3);
+ stats[0] = beans::NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TableCount")),
+ uno::makeAny(nTableCount));
+ stats[1] = beans::NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellCount")),
+ uno::makeAny(nCellCount));
+ stats[2] = beans::NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectCount")),
+ uno::makeAny(nShapesCount));
+
+ // update document statistics at the model
+ uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xPropSup->getDocumentProperties());
+ if (xDocProps.is()) {
+ xDocProps->setDocumentStatistics(stats);
+ }
+
+ // export document properties
+ SvXMLExport::_ExportMeta();
+}
+
+void ScXMLExport::_ExportFontDecls()
+{
+ GetFontAutoStylePool(); // make sure the pool is created
+ SvXMLExport::_ExportFontDecls();
+}
+
+table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
+{
+ table::CellRangeAddress aCellAddress;
+ uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
+ uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY);
+ uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
+ if (xUsedArea.is() && xCellAddress.is())
+ {
+ xUsedArea->gotoEndOfUsedArea(sal_True);
+ aCellAddress = xCellAddress->getRangeAddress();
+ }
+ return aCellAddress;
+}
+
+void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc,
+ ScMyAreaLinksContainer& rAreaLinks )
+{
+ uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY );
+ if( !xPropSet.is() ) return;
+
+ uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AREALINKS ) ) ), uno::UNO_QUERY);
+ if( xLinksIAccess.is() )
+ {
+ const OUString sFilter( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTER ) );
+ const OUString sFilterOpt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTOPT ) );
+ const OUString sURL( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_LINKURL ) );
+ const OUString sRefresh( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_REFDELAY ) );
+
+ sal_Int32 nCount(xLinksIAccess->getCount());
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
+ if( xAreaLink.is() )
+ {
+ ScMyAreaLink aAreaLink;
+ aAreaLink.aDestRange = xAreaLink->getDestArea();
+ aAreaLink.sSourceStr = xAreaLink->getSourceArea();
+ uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY );
+ if( xLinkProp.is() )
+ {
+ xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter;
+ xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions;
+ xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL;
+ xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh;
+ }
+ rAreaLinks.AddNewAreaLink( aAreaLink );
+ }
+ }
+ }
+ rAreaLinks.Sort();
+}
+
+// core implementation
+void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp )
+{
+ if (pDoc)
+ {
+ ScDetOpList* pOpList(pDoc->GetDetOpList());
+ if( pOpList )
+ {
+ sal_uInt32 nCount(pOpList->Count());
+ for( sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ ScDetOpData* pDetData(pOpList->GetObject( static_cast<sal_uInt16>(nIndex) ));
+ if( pDetData )
+ {
+ const ScAddress& rDetPos = pDetData->GetPos();
+ SCTAB nTab = rDetPos.Tab();
+ if ( nTab < pDoc->GetTableCount() )
+ {
+ rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, nIndex );
+
+ // cells with detective operations are written even if empty
+ pSharedData->SetLastColumn( nTab, rDetPos.Col() );
+ pSharedData->SetLastRow( nTab, rDetPos.Row() );
+ }
+ }
+ }
+ rDetOp.Sort();
+ }
+ }
+}
+
+void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
+ const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible)
+{
+ CheckAttrList();
+ AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex));
+ if (!bIsVisible)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
+ if (nRepeatColumns > 1)
+ {
+ OUString sOUEndCol(OUString::valueOf(static_cast <sal_Int32> (nRepeatColumns)));
+ AddAttribute(sAttrColumnsRepeated, sOUEndCol);
+ }
+ if (nIndex != -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ SvXMLElementExport aElemC(*this, sElemCol, sal_True, sal_True);
+}
+
+void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
+ const sal_Int32 nStyleIndex, const sal_Bool bIsVisible)
+{
+ sal_Int32 nRepeat(1);
+ sal_Int32 nPrevIndex((*pDefaults->GetColDefaults())[nColumn].nIndex);
+ sal_Bool bPrevAutoStyle((*pDefaults->GetColDefaults())[nColumn].bIsAutoStyle);
+ for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i)
+ {
+ if (((*pDefaults->GetColDefaults())[i].nIndex != nPrevIndex) ||
+ ((*pDefaults->GetColDefaults())[i].bIsAutoStyle != bPrevAutoStyle))
+ {
+ WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
+ nPrevIndex = (*pDefaults->GetColDefaults())[i].nIndex;
+ bPrevAutoStyle = (*pDefaults->GetColDefaults())[i].bIsAutoStyle;
+ nRepeat = 1;
+ }
+ else
+ ++nRepeat;
+ }
+ WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible);
+}
+
+void ScXMLExport::OpenHeaderColumn()
+{
+ StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True );
+}
+
+void ScXMLExport::CloseHeaderColumn()
+{
+ EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True);
+}
+
+void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader)
+{
+ sal_Int32 nColsRepeated (1);
+ rtl::OUString sParent;
+ sal_Int32 nIndex;
+ sal_Int32 nPrevColumn(0);
+ sal_Bool bPrevIsVisible (sal_True);
+ sal_Bool bWasHeader (false);
+ sal_Bool bIsHeader (false);
+ sal_Bool bIsClosed (sal_True);
+ sal_Int32 nPrevIndex (-1);
+ sal_Int32 nColumn;
+ for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn)
+ {
+ CheckAttrList();
+ sal_Bool bIsVisible(sal_True);
+ nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible);
+
+ bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn);
+ if (bIsHeader != bWasHeader)
+ {
+ if (bIsHeader)
+ {
+ if (nColumn > 0)
+ {
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+ }
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ if(pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ OpenHeaderColumn();
+ bWasHeader = sal_True;
+ bIsClosed = false;
+ }
+ else
+ {
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ CloseHeaderColumn();
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+ if(pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ bWasHeader = false;
+ bIsClosed = sal_True;
+ }
+ }
+ else if (nColumn == 0)
+ {
+ if (pGroupColumns->IsGroupStart(nColumn))
+ pGroupColumns->OpenGroups(nColumn);
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ }
+ else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) &&
+ !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1))
+ ++nColsRepeated;
+ else
+ {
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ {
+ if (bIsHeader)
+ CloseHeaderColumn();
+ pGroupColumns->CloseGroups(nColumn - 1);
+ if (bIsHeader)
+ OpenHeaderColumn();
+ }
+ if (pGroupColumns->IsGroupStart(nColumn))
+ {
+ if (bIsHeader)
+ CloseHeaderColumn();
+ pGroupColumns->OpenGroups(nColumn);
+ if (bIsHeader)
+ OpenHeaderColumn();
+ }
+ bPrevIsVisible = bIsVisible;
+ nPrevIndex = nIndex;
+ nPrevColumn = nColumn;
+ nColsRepeated = 1;
+ }
+ }
+ WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible);
+ if (!bIsClosed)
+ CloseHeaderColumn();
+ if (pGroupColumns->IsGroupEnd(nColumn - 1))
+ pGroupColumns->CloseGroups(nColumn - 1);
+}
+
+void ScXMLExport::ExportExternalRefCacheStyles()
+{
+ sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex(
+ "NumberFormat", XML_NAMESPACE_STYLE, OUString(RTL_CONSTASCII_USTRINGPARAM("data-style-name")));
+
+ if (nEntryIndex < 0)
+ // No entry index for the number format is found.
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ if (!pRefMgr->hasExternalData())
+ // No external reference data cached.
+ return;
+
+ // Export each unique number format used in the external ref cache.
+ vector<sal_uInt32> aNumFmts;
+ pRefMgr->getAllCachedNumberFormats(aNumFmts);
+ const OUString aDefaultStyle = OUString(RTL_CONSTASCII_USTRINGPARAM("Default")).intern();
+ for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end();
+ itr != itrEnd; ++itr)
+ {
+ sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr);
+
+ addDataStyle(nNumFmt);
+
+ uno::Any aVal;
+ aVal <<= nNumFmt;
+ vector<XMLPropertyState> aProps;
+ aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
+ aVal <<= aDefaultStyle;
+ aProps.push_back(XMLPropertyState(nEntryIndex, aVal));
+
+ OUString aName;
+ sal_Int32 nIndex;
+ if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps))
+ {
+ OUString* pTemp(new OUString(aName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex, true))
+ delete pTemp;
+ }
+ else
+ {
+ sal_Bool bIsAuto;
+ nIndex = pCellStyles->GetIndexOfStyleName(
+ aName, OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)), bIsAuto);
+ }
+
+ // store the number format to index mapping for later use.
+ aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex));
+ }
+}
+
+void ScXMLExport::WriteRowContent()
+{
+ ScMyRowFormatRange aRange;
+ sal_Int32 nIndex(-1);
+#ifdef DBG_UTIL
+ sal_Int32 nPrevCol(0);
+#endif
+ sal_Int32 nCols(0);
+ sal_Int32 nPrevValidationIndex(-1);
+ sal_Bool bIsAutoStyle(sal_True);
+ sal_Bool bIsFirst(sal_True);
+ while (pRowFormatRanges->GetNext(aRange))
+ {
+#ifdef DBG_UTIL
+ DBG_ASSERT(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing");
+#endif
+ if (bIsFirst)
+ {
+ nIndex = aRange.nIndex;
+ nPrevValidationIndex = aRange.nValidationIndex;
+ bIsAutoStyle = aRange.bIsAutoStyle;
+ nCols = aRange.nRepeatColumns;
+ bIsFirst = false;
+#ifdef DBG_UTIL
+ nPrevCol = aRange.nStartColumn;
+#endif
+ }
+ else
+ {
+ if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) ||
+ (aRange.nIndex == nIndex && nIndex == -1)) &&
+ nPrevValidationIndex == aRange.nValidationIndex)
+ nCols += aRange.nRepeatColumns;
+ else
+ {
+ if (nIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ if (nPrevValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
+ if (nCols > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nCols);
+ AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
+ nIndex = aRange.nIndex;
+ bIsAutoStyle = aRange.bIsAutoStyle;
+ nCols = aRange.nRepeatColumns;
+ nPrevValidationIndex = aRange.nValidationIndex;
+#ifdef DBG_UTIL
+ nPrevCol = aRange.nStartColumn;
+#endif
+ }
+ }
+ }
+ if (!bIsFirst)
+ {
+ table::CellAddress aCellAddress;
+ if (nIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle));
+ if (nPrevValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex));
+ if (nCols > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nCols);
+ AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear());
+ }
+ SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True);
+ }
+}
+
+void ScXMLExport::WriteRowStartTag(
+ sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int32 nEqualRows,
+ bool bHidden, bool bFiltered)
+{
+ AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex));
+ if (bHidden)
+ {
+ if (bFiltered)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER);
+ else
+ AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE);
+ }
+ if (nEqualRows > 1)
+ {
+ rtl::OUStringBuffer aBuf;
+ GetMM100UnitConverter().convertNumber(aBuf, nEqualRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear());
+ }
+
+ const ScMyDefaultStyleList& rRowDefaults = *pDefaults->GetRowDefaults();
+ if ( nRow >= sal::static_int_cast<sal_Int32>( rRowDefaults.size() ) )
+ {
+ // used to happen with detective operations - if there are more cases, use the last row's style
+ DBG_ERRORFILE("WriteRowStartTag: not enough defaults");
+ nRow = rRowDefaults.size() - 1;
+ }
+ sal_Int32 nCellStyleIndex(rRowDefaults[nRow].nIndex);
+ if (nCellStyleIndex != -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME,
+ *pCellStyles->GetStyleNameByIndex(nCellStyleIndex,
+ (*pDefaults->GetRowDefaults())[nRow].bIsAutoStyle));
+ StartElement( sElemRow, sal_True);
+}
+
+void ScXMLExport::OpenHeaderRows()
+{
+ StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
+ bRowHeaderOpen = sal_True;
+}
+
+void ScXMLExport::CloseHeaderRows()
+{
+ EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True);
+}
+
+void ScXMLExport::OpenNewRow(
+ const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows,
+ bool bHidden, bool bFiltered)
+{
+ nOpenRow = nStartRow;
+ if (pGroupRows->IsGroupStart(nStartRow))
+ {
+ if (bHasRowHeader && bRowHeaderOpen)
+ CloseHeaderRows();
+ pGroupRows->OpenGroups(nStartRow);
+ if (bHasRowHeader && bRowHeaderOpen)
+ OpenHeaderRows();
+ }
+ if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow)
+ {
+ if (nStartRow == aRowHeaderRange.StartRow)
+ OpenHeaderRows();
+ sal_Int32 nEquals;
+ if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1)
+ nEquals = aRowHeaderRange.EndRow - nStartRow + 1;
+ else
+ nEquals = nEqualRows;
+ WriteRowStartTag(nStartRow, nIndex, nEquals, bHidden, bFiltered);
+ nOpenRow = nStartRow + nEquals - 1;
+ if (nEquals < nEqualRows)
+ {
+ CloseRow(nStartRow + nEquals - 1);
+ WriteRowStartTag(nStartRow, nIndex, nEqualRows - nEquals, bHidden, bFiltered);
+ nOpenRow = nStartRow + nEqualRows - 1;
+ }
+ }
+ else
+ WriteRowStartTag(nStartRow, nIndex, nEqualRows, bHidden, bFiltered);
+}
+
+void ScXMLExport::OpenAndCloseRow(
+ const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEqualRows,
+ bool bHidden, bool bFiltered)
+{
+ OpenNewRow(nIndex, nStartRow, nEqualRows, bHidden, bFiltered);
+ WriteRowContent();
+ CloseRow(nStartRow + nEqualRows - 1);
+ pRowFormatRanges->Clear();
+}
+
+void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr)
+{
+ if (nRepeatRow > 1)
+ {
+ sal_Int32 nPrevIndex(0), nIndex;
+ bool bPrevHidden = false;
+ bool bPrevFiltered = false;
+ bool bHidden = false;
+ bool bFiltered = false;
+ sal_Int32 nEqualRows(1);
+ sal_Int32 nEndRow(nStartRow + nRepeatRow);
+ sal_Int32 nRow;
+ for (nRow = nStartRow; nRow < nEndRow; ++nRow)
+ {
+ if (nRow == nStartRow)
+ {
+ nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
+ if (pDoc)
+ {
+ bPrevHidden = rRowAttr.rowHidden(nTable, nRow);
+ bPrevFiltered = rRowAttr.rowFiltered(nTable, nRow);
+ }
+ }
+ else
+ {
+ nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow);
+ if (pDoc)
+ {
+ bHidden = rRowAttr.rowHidden(nTable, nRow);
+ bFiltered = rRowAttr.rowFiltered(nTable, nRow);
+ }
+ if (nIndex == nPrevIndex && bHidden == bPrevHidden && bFiltered == bPrevFiltered &&
+ !(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) &&
+ !(pGroupRows->IsGroupStart(nRow)) &&
+ !(pGroupRows->IsGroupEnd(nRow - 1)))
+ ++nEqualRows;
+ else
+ {
+ if (nRow < nEndRow)
+ {
+ ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges);
+ OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
+ delete pRowFormatRanges;
+ pRowFormatRanges = pTempRowFormatRanges;
+ }
+ else
+ OpenAndCloseRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
+ nEqualRows = 1;
+ nPrevIndex = nIndex;
+ bPrevHidden = bHidden;
+ bPrevFiltered = bFiltered;
+ }
+ }
+ }
+ OpenNewRow(nPrevIndex, nRow - nEqualRows, nEqualRows, bPrevHidden, bPrevFiltered);
+ }
+ else
+ {
+ sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow);
+ bool bHidden = false;
+ bool bFiltered = false;
+ if (pDoc)
+ {
+ bHidden = rRowAttr.rowHidden(nTable, nStartRow);
+ bFiltered = rRowAttr.rowFiltered(nTable, nStartRow);
+ }
+ OpenNewRow(nIndex, nStartRow, 1, bHidden, bFiltered);
+ }
+ nOpenRow = nStartRow + nRepeatRow - 1;
+}
+
+void ScXMLExport::CloseRow(const sal_Int32 nRow)
+{
+ if (nOpenRow > -1)
+ {
+ EndElement(sElemRow, sal_True);
+ if (bHasRowHeader && nRow == aRowHeaderRange.EndRow)
+ {
+ CloseHeaderRows();
+ bRowHeaderOpen = false;
+ }
+ if (pGroupRows->IsGroupEnd(nRow))
+ {
+ if (bHasRowHeader && bRowHeaderOpen)
+ CloseHeaderRows();
+ pGroupRows->CloseGroups(nRow);
+ if (bHasRowHeader && bRowHeaderOpen)
+ OpenHeaderRows();
+ }
+ }
+ nOpenRow = -1;
+}
+
+void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
+ const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet)
+{
+ pRowFormatRanges->Clear();
+ ScXMLCachedRowAttrAccess aRowAttr(pDoc);
+ if (nStartRow == nEndRow)
+ {
+ pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges);
+ if (nOpenRow == - 1)
+ OpenRow(nSheet, nStartRow, 1, aRowAttr);
+ WriteRowContent();
+ pRowFormatRanges->Clear();
+ }
+ else
+ {
+ if (nOpenRow > -1)
+ {
+ pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow);
+ sal_Int32 nRows(1);
+ sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
+ while (nRows < nTotalRows)
+ {
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
+ DBG_ASSERT(nMaxRows, "something wents wrong");
+ if (nMaxRows >= nTotalRows - nRows)
+ {
+ OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr);
+ nRows += nTotalRows - nRows;
+ }
+ else
+ {
+ OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr);
+ nRows += nMaxRows;
+ }
+ if (!pRowFormatRanges->GetSize())
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow + nRows - 1);
+ }
+ if (nTotalRows == 1)
+ CloseRow(nStartRow);
+ OpenRow(nSheet, nEndRow, 1, aRowAttr);
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ }
+ else
+ {
+ sal_Int32 nRows(0);
+ sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1);
+ while (nRows < nTotalRows)
+ {
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows();
+ if (nMaxRows >= nTotalRows - nRows)
+ {
+ OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows, aRowAttr);
+ nRows += nTotalRows - nRows;
+ }
+ else
+ {
+ OpenRow(nSheet, nStartRow + nRows, nMaxRows, aRowAttr);
+ nRows += nMaxRows;
+ }
+ if (!pRowFormatRanges->GetSize())
+ pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ CloseRow(nStartRow + nRows - 1);
+ }
+ OpenRow(nSheet, nEndRow, 1, aRowAttr);
+ pRowFormatRanges->Clear();
+ pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges);
+ WriteRowContent();
+ }
+ }
+}
+
+void ScXMLExport::GetColumnRowHeader(sal_Bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange,
+ sal_Bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange,
+ rtl::OUString& rPrintRanges) const
+{
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ rHasRowHeader = xPrintAreas->getPrintTitleRows();
+ rHasColumnHeader = xPrintAreas->getPrintTitleColumns();
+ rRowHeaderRange = xPrintAreas->getTitleRows();
+ rColumnHeaderRange = xPrintAreas->getTitleColumns();
+ uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() );
+ ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ }
+}
+
+void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups)
+{
+ sal_Int32 nDepth(pFields->GetDepth());
+ for(sal_Int32 i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nFields = pFields->GetCount(static_cast<sal_uInt16>(i));
+ for (sal_Int32 j = 0; j < nFields; ++j)
+ {
+ ScMyColumnRowGroup aGroup;
+ ScOutlineEntry* pEntry(pFields->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j)));
+ aGroup.nField = pEntry->GetStart();
+ aGroup.nLevel = static_cast<sal_Int16>(i);
+ aGroup.bDisplay = !(pEntry->IsHidden());
+ pGroups->AddGroup(aGroup, pEntry->GetEnd());
+ }
+ }
+ if (nDepth)
+ pGroups->Sort();
+}
+
+void ScXMLExport::FillColumnRowGroups()
+{
+ if (pDoc)
+ {
+ ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), false );
+ if(pOutlineTable)
+ {
+ ScOutlineArray* pCols(pOutlineTable->GetColArray());
+ ScOutlineArray* pRows(pOutlineTable->GetRowArray());
+ if (pCols)
+ FillFieldGroup(pCols, pGroupColumns);
+ if (pRows)
+ FillFieldGroup(pRows, pGroupRows);
+ pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast());
+ pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast());
+ }
+ }
+}
+
+void ScXMLExport::SetBodyAttributes()
+{
+ if (pDoc && pDoc->IsDocProtected())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
+ rtl::OUStringBuffer aBuffer;
+ uno::Sequence<sal_Int8> aPassHash;
+ ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED;
+ const ScDocProtection* p = pDoc->GetDocProtection();
+ if (p)
+ {
+ if (p->hasPasswordHash(PASSHASH_SHA1))
+ {
+ aPassHash = p->getPasswordHash(PASSHASH_SHA1);
+ eHashUsed = PASSHASH_SHA1;
+ }
+ else if (p->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1))
+ {
+ aPassHash = p->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1);
+ eHashUsed = PASSHASH_XL;
+ }
+ }
+ SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash);
+ if (aBuffer.getLength())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
+ if (eHashUsed == PASSHASH_XL)
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
+ ScPassHashHelper::getHashURI(PASSHASH_XL));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2,
+ ScPassHashHelper::getHashURI(PASSHASH_SHA1));
+ }
+ else if (eHashUsed == PASSHASH_SHA1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
+ ScPassHashHelper::getHashURI(PASSHASH_SHA1));
+ }
+ }
+}
+
+static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
+ const uno::Reference< io::XOutputStream >& xOutput,
+ sal_Int32 nCount )
+{
+ const sal_Int32 nBufSize = 16*1024;
+ uno::Sequence<sal_Int8> aSequence(nBufSize);
+
+ sal_Int32 nRemaining = nCount;
+ bool bFirst = true;
+
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
+ if (bFirst)
+ {
+ // safety check: Make sure the copied part actually points to the start of an element
+ if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
+ {
+ return false; // abort and set an error
+ }
+ bFirst = false;
+ }
+ if (nRead == nRemaining)
+ {
+ // safety check: Make sure the copied part also ends at the end of an element
+ if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
+ {
+ return false; // abort and set an error
+ }
+ }
+
+ if ( nRead == nBufSize )
+ {
+ xOutput->writeBytes( aSequence );
+ nRemaining -= nRead;
+ }
+ else
+ {
+ if ( nRead > 0 )
+ {
+ uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
+ xOutput->writeBytes( aTempBuf );
+ }
+ nRemaining = 0;
+ }
+ }
+ return true; // successful
+}
+
+static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
+{
+ // skipBytes in zip stream is implemented as reading.
+ // For now, split into several calls to avoid allocating a large buffer.
+ // Later, skipBytes should be changed.
+
+ const sal_Int32 nMaxSize = 32*1024;
+
+ if ( nBytesToSkip > 0 )
+ {
+ sal_Int32 nRemaining = nBytesToSkip;
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
+ xInput->skipBytes( nSkip );
+ nRemaining -= nSkip;
+ }
+ }
+}
+
+void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
+{
+ uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
+ uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
+ if ( xDestSource.is() )
+ {
+ uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
+ uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
+ if ( xDestSeek.is() )
+ {
+ // temporary: set same stream again to clear buffer
+ xDestSource->setOutputStream( xDestStream );
+
+ if ( getExportFlags() & EXPORT_PRETTY )
+ {
+ ByteString aOutStr("\n ");
+ uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() );
+ xDestStream->writeBytes( aOutSeq );
+ }
+
+ rNewStart = (sal_Int32)xDestSeek->getPosition();
+
+ if ( nStartOffset > nSourceStreamPos )
+ lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
+
+ if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
+ {
+ // If copying went wrong, set an error.
+ // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
+
+ uno::Sequence<OUString> aEmptySeq;
+ SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
+ }
+ nSourceStreamPos = nEndOffset;
+
+ rNewEnd = (sal_Int32)xDestSeek->getPosition();
+ }
+ }
+}
+
+void ScXMLExport::_ExportContent()
+{
+ nCurrentTable = 0;
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ OSL_FAIL("no shared data setted");
+ }
+ ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
+ if (!GetModel().is())
+ return;
+
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if ( !xSpreadDoc.is() )
+ return;
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData)
+ pSheetData->ResetSaveEntries();
+
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ //_GetNamespaceMap().ClearQNamesCache();
+ pChangeTrackingExportHelper->CollectAndWriteChanges();
+ WriteCalculationSettings(xSpreadDoc);
+ sal_Int32 nTableCount(xIndex->getCount());
+ ScMyAreaLinksContainer aAreaLinks;
+ GetAreaLinks( xSpreadDoc, aAreaLinks );
+ ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
+ ScMyDetectiveOpContainer aDetectiveOpContainer;
+ GetDetectiveOpList( aDetectiveOpContainer );
+
+ pCellStyles->Sort();
+ pMergedRangesContainer->Sort();
+ pSharedData->GetDetectiveObjContainer()->Sort();
+
+ pCellsItr->Clear();
+ pCellsItr->SetShapes( pSharedData->GetShapesContainer() );
+ pCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() );
+ pCellsItr->SetMergedRanges( pMergedRangesContainer );
+ pCellsItr->SetAreaLinks( &aAreaLinks );
+ pCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges );
+ pCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() );
+ pCellsItr->SetDetectiveOp( &aDetectiveOpContainer );
+
+ if (nTableCount > 0)
+ pValidationsContainer->WriteValidations(*this);
+ WriteTheLabelRanges( xSpreadDoc );
+ for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
+ {
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable))
+ pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
+
+ if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
+ {
+ sal_Int32 nNewStart = -1;
+ sal_Int32 nNewEnd = -1;
+ CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
+
+ // store position of copied sheet in output
+ pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
+
+ // skip iterator entries for this sheet
+ pCellsItr->SkipTable(static_cast<SCTAB>(nTable));
+ }
+ else
+ {
+ uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ WriteTable(nTable, xTable);
+ }
+ IncrementProgressBar(false);
+ }
+ }
+ WriteExternalRefCaches();
+ WriteNamedExpressions(xSpreadDoc);
+ aExportDatabaseRanges.WriteDatabaseRanges(xSpreadDoc);
+ ScXMLExportDataPilot aExportDataPilot(*this);
+ aExportDataPilot.WriteDataPilots(xSpreadDoc);
+ WriteConsolidation();
+ ScXMLExportDDELinks aExportDDELinks(*this);
+ aExportDDELinks.WriteDDELinks(xSpreadDoc);
+ IncrementProgressBar(sal_True, 0);
+ GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
+}
+
+void ScXMLExport::_ExportStyles( sal_Bool bUsed )
+{
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ }
+ ScXMLStyleExport aStylesExp(*this, rtl::OUString(), GetAutoStylePool().get());
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper);
+ if (pSharedData->HasShapes())
+ {
+ GetShapeExport()->ExportGraphicDefaults();
+ }
+ }
+ uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY);
+ if (xStyleFamiliesSupplier.is())
+ {
+ uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
+ if (xStylesFamilies.is())
+ {
+ uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles"))), uno::UNO_QUERY);
+ if (xCellStyles.is())
+ {
+ sal_Int32 nCount(xCellStyles->getCount());
+ rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY);
+ if (xCellProperties.is())
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat)
+ addDataStyle(nNumberFormat);
+ }
+ }
+ }
+ }
+ }
+ }
+ exportDataStyles();
+
+ aStylesExp.exportStyleFamily(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper, false, XML_STYLE_FAMILY_TABLE_CELL);
+
+ SvXMLExport::_ExportStyles(bUsed);
+}
+
+void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
+ const uno::Reference<sheet::XSpreadsheet>& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName)
+{
+ //! pass xCellRanges instead
+ uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
+
+ rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
+ rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
+
+ rtl::OUString sStyleName;
+ sal_Int32 nNumberFormat(-1);
+ sal_Int32 nValidationIndex(-1);
+ std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ sal_Int32 nCount(0);
+ while (aItr != aEndItr)
+ {
+ if (aItr->mnIndex != -1)
+ {
+ switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
+ {
+ case CTF_SC_VALIDATION :
+ {
+ pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
+ // this is not very slow, because it is most the last property or
+ // if it is not the last property it is the property before the last property,
+ // so in the worst case only one property has to be copied, but in the best case no
+ // property has to be copied
+ aItr = xPropStates.erase(aItr);
+ aEndItr = xPropStates.end(); // old aEndItr is invalidated!
+ }
+ break;
+ case CTF_SC_CELLSTYLE :
+ {
+ aItr->maValue >>= sStyleName;
+ aItr->mnIndex = -1;
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ case CTF_SC_NUMBERFORMAT :
+ {
+ if (aItr->maValue >>= nNumberFormat)
+ addDataStyle(nNumberFormat);
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ default:
+ {
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ }
+ }
+ else
+ {
+ ++aItr;
+ ++nCount;
+ }
+ }
+ if (nCount == 1) // this is the CellStyle and should be removed if alone
+ xPropStates.clear();
+ if (nNumberFormat == -1)
+ xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
+ if (sStyleName.getLength())
+ {
+ if (xPropStates.size())
+ {
+ sal_Int32 nIndex;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
+ // add to pCellStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ sal_Bool bIsAutoStyle(sal_True);
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ else
+ nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
+
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ }
+ }
+ }
+ else
+ {
+ rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
+ sal_Int32 nIndex(0);
+ if (!pCellStyles->AddStyleName(pTemp, nIndex, false))
+ {
+ delete pTemp;
+ pTemp = NULL;
+ }
+ if ( !pOldName )
+ {
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, false, nValidationIndex, nNumberFormat);
+ if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible)
+{
+ rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
+ if(xPropStates.size())
+ {
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ while (aItr != aEndItr)
+ {
+ if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
+ {
+ aItr->maValue >>= rIsVisible;
+ break;
+ }
+ ++aItr;
+ }
+
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
+ // add to pColumnStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex)
+{
+ rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
+ if(xPropStates.size())
+ {
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
+ // add to pRowStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
+ }
+ }
+}
+
+uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
+{
+ uno::Any aRet;
+ uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
+ try
+ {
+ sal_Int32 nSkip = nIndex;
+ while ( nSkip > 0 )
+ {
+ (void) xEnum->nextElement();
+ --nSkip;
+ }
+ aRet = xEnum->nextElement();
+ }
+ catch (container::NoSuchElementException&)
+ {
+ // leave aRet empty
+ }
+ return aRet;
+}
+
+void ScXMLExport::_ExportAutoStyles()
+{
+ if (!GetModel().is())
+ return;
+
+ Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+ if (!xSpreadDoc.is())
+ return;
+
+ Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if (!xIndex.is())
+ return;
+
+ if (getExportFlags() & EXPORT_CONTENT)
+ {
+ // re-create automatic styles with old names from stored data
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData && pDoc)
+ {
+ // formulas have to be calculated now, to detect changed results
+ // (during normal save, they will be calculated anyway)
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (pDoc->IsStreamValid(nTab))
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty
+ pCell = aIter.GetNext();
+ }
+ }
+
+ // stored cell styles
+ const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
+ while (aCellIter != aCellEnd)
+ {
+ ScAddress aPos = aCellIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ Reference <beans::XPropertySet> xProperties(
+ xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
+
+ AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
+ }
+ ++aCellIter;
+ }
+
+ // stored column styles
+ const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
+ while (aColumnIter != aColumnEnd)
+ {
+ ScAddress aPos = aColumnIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+ Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ sal_Bool bIsVisible(sal_True);
+ AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
+ }
+ ++aColumnIter;
+ }
+
+ // stored row styles
+ const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
+ while (aRowIter != aRowEnd)
+ {
+ ScAddress aPos = aRowIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
+ Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
+ }
+ ++aRowIter;
+ }
+
+ // stored table styles
+ const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
+ while (aTableIter != aTableEnd)
+ {
+ ScAddress aPos = aTableIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromTable needed?
+ Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xTableProperties.is())
+ {
+ std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTableIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
+ }
+ }
+ ++aTableIter;
+ }
+
+ // stored styles for notes
+
+ UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
+ GetShapeExport(); // make sure the graphics styles family is added
+
+ const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
+ while (aNoteIter != aNoteEnd)
+ {
+ ScAddress aPos = aNoteIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromNote needed?
+
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ // all uno shapes are created anyway in CollectSharedData
+ Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
+ if (xShapeProperties.is())
+ {
+ if ( aNoteIter->maStyleName.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maStyleName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
+ }
+ if ( aNoteIter->maTextStyle.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(
+ GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maTextStyle );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ }
+ ++aNoteIter;
+ }
+
+ // note paragraph styles
+
+ UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
+
+ const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
+ while (aNoteParaIter != aNoteParaEnd)
+ {
+ ScAddress aPos = aNoteParaIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ Reference<beans::XPropertySet> xParaProp(
+ lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
+ if ( xParaProp.is() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteParaIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ ++aNoteParaIter;
+ }
+
+ // note text styles
+
+ UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
+
+ const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
+ while (aNoteTextIter != aNoteTextEnd)
+ {
+ ScAddress aPos = aNoteTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aNoteTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ }
+ ++aNoteTextIter;
+ }
+
+ // stored text styles
+
+ const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
+ while (aTextIter != aTextEnd)
+ {
+ ScAddress aPos = aTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromText needed?
+ //! cache sheet object
+
+ Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
+ Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ ++aTextIter;
+ }
+ }
+
+ ExportExternalRefCacheStyles();
+
+ if (!pSharedData)
+ {
+ sal_Int32 nTableCount(0);
+ sal_Int32 nShapesCount(0);
+ sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0);
+ CollectSharedData(nTableCount, nShapesCount, nCellCount);
+ }
+ sal_Int32 nTableCount(xIndex->getCount());
+ pCellStyles->AddNewTable(nTableCount - 1);
+ CollectShapesAutoStyles(nTableCount);
+ for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable, IncrementProgressBar(false))
+ {
+ bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) &&
+ pSheetData->HasStreamPos(nTable) && xSourceStream.is();
+
+ Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (!xTable.is())
+ continue;
+
+ // table styles array must be complete, including copied tables - Add should find the stored style
+ Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
+ if (xTableProperties.is())
+ {
+ std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
+ if(xPropStates.size())
+ {
+ rtl::OUString sParent;
+ rtl::OUString sName;
+ GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
+ aTableStyles.push_back(sName);
+ }
+ }
+
+ if (bUseStream)
+ continue;
+
+ // collect other auto-styles only for non-copied sheets
+ Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
+ if ( xCellFormatRanges.is() )
+ {
+ Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
+ if (xFormatRangesIndex.is())
+ {
+ sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount());
+ GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount);
+ for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange)
+ {
+ Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY);
+ if (xCellRanges.is())
+ {
+ Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ AddStyleFromCells(xProperties, xTable, nTable, NULL);
+ IncrementProgressBar(false);
+ }
+ }
+ }
+ }
+ }
+ Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ if (pDoc)
+ {
+ pDoc->SyncColRowFlags();
+ Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+ if (xTableColumns.is())
+ {
+ sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable)));
+ pSharedData->SetLastColumn(nTable, nColumns);
+ table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
+ if (aCellAddress.EndColumn > nColumns)
+ {
+ ++nColumns;
+ pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn);
+ }
+ else
+ pColumnStyles->AddNewTable(nTable, nColumns);
+ sal_Int32 nColumn = 0;
+ while (nColumn <= MAXCOL)
+ {
+ sal_Int32 nIndex(-1);
+ sal_Bool bIsVisible(sal_True);
+ Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
+ if (xColumnProperties.is())
+ {
+ AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
+ pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
+ }
+ sal_Int32 nOld(nColumn);
+ nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn));
+ for (sal_Int32 i = nOld + 1; i < nColumn; ++i)
+ pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
+ }
+ if (aCellAddress.EndColumn > nColumns)
+ {
+ sal_Bool bIsVisible(sal_True);
+ sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible));
+ for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i)
+ pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible);
+ }
+ }
+ Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
+ if (xTableRows.is())
+ {
+ sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable)));
+ pSharedData->SetLastRow(nTable, nRows);
+ table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable));
+ if (aCellAddress.EndRow > nRows)
+ {
+ ++nRows;
+ pRowStyles->AddNewTable(nTable, aCellAddress.EndRow);
+ }
+ else
+ pRowStyles->AddNewTable(nTable, nRows);
+ sal_Int32 nRow = 0;
+ while (nRow <= nRows && nRow <= MAXROW)
+ {
+ sal_Int32 nIndex = 0;
+ Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
+ if(xRowProperties.is())
+ {
+ AddStyleFromRow( xRowProperties, NULL, nIndex );
+ pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
+ }
+ sal_Int32 nOld(nRow);
+ nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
+ if (nRow > nOld + 1)
+ pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
+ }
+ if (aCellAddress.EndRow > nRows)
+ {
+ sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows));
+ pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow);
+ }
+ }
+ }
+ }
+ Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY);
+ if (xCellRangesQuery.is())
+ {
+ Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED));
+ Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY);
+ if (xSheetCellRanges.is() && xSheetOperation.is())
+ {
+ sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT)));
+ Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells());
+ if (xCellsAccess.is())
+ {
+ GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount);
+ Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration());
+ if (xCells.is())
+ {
+ sal_uInt32 nCount2(0);
+ while (xCells->hasMoreElements())
+ {
+ Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY);
+ if (xText.is())
+ GetTextParagraphExport()->collectTextAutoStyles(xText, false, false);
+ ++nCount2;
+ IncrementProgressBar(false);
+ }
+ if(nCount2 > nCount)
+ GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount);
+ }
+ }
+ }
+ }
+ }
+ pChangeTrackingExportHelper->CollectAutoStyles();
+
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+ exportAutoDataStyles();
+ GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL,
+ GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap());
+
+ GetShapeExport()->exportAutoStyles();
+ GetFormExport()->exportAutoStyles( );
+
+ if (pDoc)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ // #i100879# write the table style for cached tables only if there are cached tables
+ // (same logic as in ExportExternalRefCacheStyles)
+ if (pRefMgr->hasExternalData())
+ {
+ // Special table style for the external ref cache tables.
+ AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName);
+ AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE);
+ SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE);
+ SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True);
+ }
+ }
+ }
+
+ if (getExportFlags() & EXPORT_MASTERSTYLES)
+ {
+ GetPageExport()->collectAutoStyles(sal_True);
+ GetPageExport()->exportAutoStyles();
+ }
+
+ // #i30251#; only write Text Styles once
+
+ if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES))
+ GetTextParagraphExport()->exportTextAutoStyles();
+}
+
+void ScXMLExport::_ExportMasterStyles()
+{
+ GetPageExport()->exportMasterStyles( sal_True );
+}
+
+void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape )
+{
+ // detective objects and notes
+ if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) )
+ {
+ if( SdrObject* pObject = pShapeImp->GetSdrObject() )
+ {
+ // collect note caption objects from all layers (internal or hidden)
+ if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) )
+ {
+ pSharedData->AddNoteObj( xShape, pCaptData->maStart );
+
+ // #i60851# When the file is saved while editing a new note,
+ // the cell is still empty -> last column/row must be updated
+ DBG_ASSERT( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" );
+ pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() );
+ pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() );
+ }
+ // other objects from internal layer only (detective)
+ else if( pObject->GetLayer() == SC_LAYER_INTERN )
+ {
+ ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) );
+ ScAddress aPosition;
+ ScRange aSourceRange;
+ sal_Bool bRedLine;
+ ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType(
+ pObject, nCurrentTable, aPosition, aSourceRange, bRedLine );
+ pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine );
+ }
+ }
+ }
+}
+
+sal_Bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress,
+ const uno::Reference <sheet::XSpreadsheet>& xTable)
+{
+ sal_Bool bReady(false);
+ sal_Int32 nRow(pCellAddress->StartRow);
+ sal_Int32 nCol(pCellAddress->StartColumn);
+ sal_Int32 nEndRow(pCellAddress->EndRow);
+ sal_Int32 nEndCol(pCellAddress->EndColumn);
+ sal_Bool bRowInc(nEndRow > nRow);
+ while(!bReady && nRow <= nEndRow && nCol <= nEndCol)
+ {
+ uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY);
+ if (xSheetCellRange.is())
+ {
+ uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange));
+ if(xCursor.is())
+ {
+ uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY);
+ xCursor->collapseToMergedArea();
+ table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress());
+ if ((aCellAddress2.EndRow > nRow ||
+ aCellAddress2.EndColumn > nCol) &&
+ aCellAddress2.StartRow == nRow &&
+ aCellAddress2.StartColumn == nCol)
+ {
+ pMergedRangesContainer->AddRange(aCellAddress2);
+ pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn);
+ pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow);
+ }
+ else
+ bReady = sal_True;
+ }
+ }
+ if (!bReady)
+ {
+ if (bRowInc)
+ ++nRow;
+ else
+ ++nCol;
+ }
+ }
+ DBG_ASSERT(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible");
+ return !bReady;
+}
+
+sal_Bool ScXMLExport::IsMatrix (const ScAddress& aCell,
+ table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const
+{
+ bIsFirst = false;
+
+ ScRange aMatrixRange;
+
+ if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange))
+ {
+ ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange );
+ if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) &&
+ (aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row()))
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() ||
+ aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row())
+ return sal_True;
+ else
+ {
+ bIsFirst = sal_True;
+ return sal_True;
+ }
+ }
+
+ return false;
+}
+
+sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const
+{
+ if (rMyCell.bHasStringValue)
+ return sal_True;
+ else
+ {
+ rMyCell.sStringValue = ScCellObj::GetOutputString_Impl(pDoc, aPos);
+ rMyCell.bHasStringValue = sal_True;
+ return sal_True;
+ }
+}
+
+void ScXMLExport::WriteTable(sal_Int32 nTable, const Reference<sheet::XSpreadsheet>& xTable)
+{
+ if (!xTable.is())
+ return;
+
+ xCurrentTable.set(xTable);
+ xCurrentTableCellRange.set(xTable, uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY );
+ if (!xName.is())
+ return;
+
+ nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable );
+ rtl::OUString sOUTableName(xName->getName());
+ AddAttribute(sAttrName, sOUTableName);
+ AddAttribute(sAttrStyleName, aTableStyles[nTable]);
+
+ uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY);
+ ScTableProtection* pProtect = NULL;
+ if (xProtectable.is() && xProtectable->isProtected())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
+ if (pDoc)
+ {
+ pProtect = pDoc->GetTabProtection(nTable);
+ if (pProtect)
+ {
+ rtl::OUStringBuffer aBuffer;
+ ScPasswordHash eHashUsed = PASSHASH_UNSPECIFIED;
+ if (pProtect->hasPasswordHash(PASSHASH_SHA1))
+ {
+ SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_SHA1));
+ eHashUsed = PASSHASH_SHA1;
+ }
+ else if (pProtect->hasPasswordHash(PASSHASH_XL, PASSHASH_SHA1))
+ {
+ // Double-hash this by SHA1 on top of the legacy xls hash.
+ uno::Sequence<sal_Int8> aHash = pProtect->getPasswordHash(PASSHASH_XL, PASSHASH_SHA1);
+ SvXMLUnitConverter::encodeBase64(aBuffer, aHash);
+ eHashUsed = PASSHASH_XL;
+ }
+ if (aBuffer.getLength())
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
+ if (eHashUsed == PASSHASH_XL)
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
+ ScPassHashHelper::getHashURI(PASSHASH_XL));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2,
+ ScPassHashHelper::getHashURI(PASSHASH_SHA1));
+ }
+ else if (eHashUsed == PASSHASH_SHA1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM,
+ ScPassHashHelper::getHashURI(PASSHASH_SHA1));
+ }
+ }
+ }
+ }
+ rtl::OUString sPrintRanges;
+ table::CellRangeAddress aColumnHeaderRange;
+ sal_Bool bHasColumnHeader;
+ GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges);
+ if( sPrintRanges.getLength() )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges );
+ else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable)))
+ AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE);
+ SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True);
+
+ if (pProtect && pProtect->isProtected())
+ {
+ if (pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SELECT_PROTECTED_CELLS, XML_TRUE);
+ if (pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SELECT_UNPROTECTED_CELLS, XML_TRUE);
+
+ rtl::OUString aElemName = GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_PROTECTION));
+
+ SvXMLElementExport aElemProtected(*this, aElemName, true, true);
+ }
+
+ CheckAttrList();
+
+ if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) &&
+ getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+ // store sheet events
+ uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY);
+ GetEventExport().ExportExt( xEvents );
+ }
+
+ WriteTableSource();
+ WriteScenario();
+ uno::Reference<drawing::XDrawPage> xDrawPage;
+ if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is())
+ {
+ ::xmloff::OOfficeFormsExport aForms(*this);
+ GetFormExport()->exportForms( xDrawPage );
+ sal_Bool bRet(GetFormExport()->seekPage( xDrawPage ));
+ DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" );
+ (void)bRet; // avoid warning in product version
+ }
+ if (pSharedData->HasDrawPage())
+ {
+ GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY));
+ WriteTableShapes();
+ }
+ table::CellRangeAddress aRange(GetEndAddress(xTable, nTable));
+ pSharedData->SetLastColumn(nTable, aRange.EndColumn);
+ pSharedData->SetLastRow(nTable, aRange.EndRow);
+ pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable);
+ pGroupColumns->NewTable();
+ pGroupRows->NewTable();
+ FillColumnRowGroups();
+ if (bHasColumnHeader)
+ pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn);
+ bRowHeaderOpen = sal_False;
+ if (bHasRowHeader)
+ pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow);
+ pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable),
+ pSharedData->GetLastColumn(nTable), pCellStyles, pDoc);
+ pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults());
+ pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults());
+ pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults());
+ pCellStyles->SetColDefaults(pDefaults->GetColDefaults());
+ ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader);
+ sal_Bool bIsFirst(sal_True);
+ sal_Int32 nEqualCells(0);
+ ScMyCell aCell;
+ ScMyCell aPrevCell;
+ while(pCellsItr->GetNext(aCell, pCellStyles))
+ {
+ if (bIsFirst)
+ {
+ ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
+ aPrevCell = aCell;
+ bIsFirst = sal_False;
+ }
+ else
+ {
+ if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) &&
+ (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column))
+ {
+ if(IsCellEqual(aPrevCell, aCell))
+ ++nEqualCells;
+ else
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ nEqualCells = 0;
+ aPrevCell = aCell;
+ }
+ }
+ else
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
+ aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable);
+ nEqualCells = 0;
+ aPrevCell = aCell;
+ }
+ }
+ }
+ if (!bIsFirst)
+ {
+ SetRepeatAttribute(nEqualCells);
+ WriteCell(aPrevCell);
+ ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row,
+ pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
+ }
+ else
+ ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable);
+
+ CloseRow(pSharedData->GetLastRow(nTable));
+ nEqualCells = 0;
+
+ if (pDoc)
+ {
+ // Export sheet-local named ranges.
+ ScRangeName* pRN = pDoc->GetRangeName(nTable);
+ if (pRN && !pRN->empty())
+ {
+ SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True);
+ ScRangeName::const_iterator itr = pRN->begin(), itrEnd = pRN->end();
+ for (; itr != itrEnd; ++itr)
+ {
+ CheckAttrList();
+
+ // name
+ OUString aStr = itr->GetName();
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aStr);
+
+ // base cell
+ ScAddress aPos = itr->GetPos();
+ aPos.Format(aStr, SCA_ABS_3D, pDoc, FormulaGrammar::CONV_OOO);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, aStr);
+
+ // expression
+ itr->GetSymbol(aStr, pDoc->GetStorageGrammar());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, aStr);
+
+ SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True);
+ }
+ }
+ }
+}
+
+void ScXMLExport::WriteCell (ScMyCell& aCell)
+{
+ ScAddress aCellPos;
+ ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress );
+ if (aCell.nStyleIndex != -1)
+ AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle));
+ if (aCell.nValidationIndex > -1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex));
+ sal_Bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered);
+ sal_Bool bIsFirstMatrixCell(aCell.bIsMatrixBase);
+ if (bIsFirstMatrixCell)
+ {
+ sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1);
+ sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, nColumns);
+ SvXMLUnitConverter::convertNumber(sRows, nRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ sal_Bool bIsEmpty(false);
+ switch (aCell.nType)
+ {
+ case table::CellContentType_EMPTY :
+ {
+ bIsEmpty = sal_True;
+ }
+ break;
+ case table::CellContentType_VALUE :
+ {
+ if (!aCell.bHasDoubleValue)
+ {
+ aCell.fValue = pDoc->GetValue( aCellPos );
+ aCell.bHasDoubleValue = sal_True;
+ }
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ aCell.nNumberFormat, aCell.fValue);
+ }
+ break;
+ case table::CellContentType_TEXT :
+ {
+ if (GetCellText(aCell, aCellPos))
+ {
+ rtl::OUString sFormula(lcl_GetRawString(pDoc, aCellPos));
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ sFormula, aCell.sStringValue, sal_True, sal_True);
+ }
+ }
+ break;
+ case table::CellContentType_FORMULA :
+ {
+ ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aCellPos) : NULL;
+ if (pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ rtl::OUStringBuffer sFormula;
+ ScFormulaCell* pFormulaCell((ScFormulaCell*) pBaseCell);
+ if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell))
+ {
+ const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
+ sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
+ pFormulaCell->GetFormula(sFormula, eGrammar);
+ rtl::OUString sOUFormula(sFormula.makeStringAndClear());
+ if (!bIsMatrix)
+ {
+ AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula, false ));
+ }
+ else
+ {
+ AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula.copy(1, sOUFormula.getLength() - 2), false ));
+ }
+ }
+ if (pFormulaCell->IsValue())
+ {
+ sal_Bool bIsStandard;
+ rtl::OUString sCurrency;
+ GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard);
+ if (bIsStandard)
+ {
+ if (pDoc)
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ pFormulaCell->GetStandardFormat(*pDoc->GetFormatTable(), 0),
+ pDoc->GetValue( aCellPos ));
+ }
+ else
+ {
+ if (pDoc)
+ GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes(
+ aCell.nNumberFormat, pDoc->GetValue( aCellPos ));
+ }
+ }
+ else
+ {
+ if (GetCellText(aCell, aCellPos))
+ if (aCell.sStringValue.getLength())
+ {
+ AddAttribute(sAttrValueType, XML_STRING);
+ AddAttribute(sAttrStringValue, aCell.sStringValue);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rtl::OUString* pCellString(&sElemCell);
+ if (aCell.bIsCovered)
+ {
+ pCellString = &sElemCoveredCell;
+ }
+ else
+ {
+ if (aCell.bIsMergedBase)
+ {
+ sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1);
+ sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1);
+ rtl::OUStringBuffer sColumns;
+ rtl::OUStringBuffer sRows;
+ SvXMLUnitConverter::convertNumber(sColumns, nColumns);
+ SvXMLUnitConverter::convertNumber(sRows, nRows);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear());
+ }
+ }
+ SvXMLElementExport aElemC(*this, *pCellString, sal_True, sal_True);
+ CheckAttrList();
+ WriteAreaLink(aCell);
+ WriteAnnotation(aCell);
+ WriteDetective(aCell);
+
+ sal_Bool bEditCell = false;
+
+ if (!bIsEmpty)
+ {
+ if ((aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell)) ||
+ (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell)))
+ {
+ bEditCell = sal_True;
+ uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
+ if ( xText.is())
+ GetTextParagraphExport()->exportText(xText, false, false);
+ }
+ else
+ {
+ SvXMLElementExport aElemP(*this, sElemP, sal_True, false);
+ sal_Bool bPrevCharWasSpace(sal_True);
+ if (GetCellText(aCell, aCellPos))
+ GetTextParagraphExport()->exportText(aCell.sStringValue, bPrevCharWasSpace);
+ }
+ }
+ WriteShapes(aCell);
+ if (!bIsEmpty)
+ IncrementProgressBar(bEditCell);
+}
+
+void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
+{
+ uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
+ bool bIsChart( false );
+ rtl::OUString sPropCLSID (RTL_CONSTASCII_USTRINGPARAM("CLSID"));
+ rtl::OUString sPropModel (RTL_CONSTASCII_USTRINGPARAM("Model"));
+ rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName"));
+ if (xShapeProps.is())
+ {
+ sal_Int32 nZOrder = 0;
+ if (xShapeProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))) >>= nZOrder)
+ {
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertNumber(sBuffer, nZOrder);
+ AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear());
+ }
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo();
+ if( xPropSetInfo->hasPropertyByName( sPropCLSID ) )
+ {
+ rtl::OUString sCLSID;
+ if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID)
+ {
+ if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) )
+ {
+ // we have a chart
+ ::rtl::OUString sRanges;
+ if ( pDoc )
+ {
+ ::rtl::OUString aChartName;
+ xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
+ ScRange aEmptyRange;
+ ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
+ sal_uInt16 nIndex = 0;
+ ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
+ if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
+ {
+ ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
+ if ( pListener )
+ {
+ const ScRangeListRef& rRangeList = pListener->GetRangeList();
+ if ( rRangeList.Is() )
+ {
+ ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ if ( sRanges.getLength() > 0 )
+ {
+ bIsChart = true;
+ SvXMLAttributeList* pAttrList = new SvXMLAttributeList();
+ if ( pAttrList )
+ {
+ pAttrList->AddAttribute(
+ GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges );
+ }
+ GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList );
+ }
+ }
+ }
+ }
+ }
+
+ if ( sRanges.getLength() == 0 )
+ {
+ uno::Reference< frame::XModel > xChartModel;
+ if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) &&
+ xChartModel.is())
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY );
+ if( xChartDoc.is() && xReceiver.is() &&
+ ! xChartDoc->hasInternalDataProvider())
+ {
+ // we have a chart that gets its data from Calc
+ bIsChart = true;
+ uno::Sequence< ::rtl::OUString > aRepresentations(
+ xReceiver->getUsedRangeRepresentations());
+ SvXMLAttributeList* pAttrList = 0;
+ if(aRepresentations.getLength())
+ {
+ // add the ranges used by the chart to the shape
+ // element to be able to start listening after
+ // load (when the chart is not yet loaded)
+ uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
+ sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
+ pAttrList = new SvXMLAttributeList();
+ pAttrList->AddAttribute(
+ GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
+ }
+ GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!bIsChart)
+ {
+ // #i66550 HLINK_FOR_SHAPES
+ rtl::OUString sHlink;
+ uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
+ if ( xProps.is() )
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_HYPERLINK ) ) ) >>= sHlink;
+
+ std::auto_ptr< SvXMLElementExport > pDrawA;
+ // enlose shapes with <draw:a> element only if sHlink contains something
+ if ( sHlink.getLength() > 0 )
+ {
+ // need to get delete the attributes that are pre-loaded
+ // for the shape export ( otherwise they will become
+ // attributes of the draw:a element ) This *shouldn't*
+ // affect performance adversely as there are only a
+ // couple of attributes involved
+ uno::Reference< xml::sax::XAttributeList > xSaveAttribs( new SvXMLAttributeList( GetAttrList() ) );
+ ClearAttrList();
+ // Add Hlink
+ AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sHlink);
+ pDrawA.reset( new SvXMLElementExport( *this, XML_NAMESPACE_DRAW, XML_A, false, false ) );
+ // Attribute list has been cleared by previous operation
+ // re-add pre-loaded attributes
+ AddAttributeList( xSaveAttribs );
+ }
+ GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint);
+ }
+ IncrementProgressBar(false);
+}
+
+void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
+{
+ if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc )
+ {
+ awt::Point aPoint;
+ Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row),
+ static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), static_cast<SCTAB>(rMyCell.aCellAddress.Sheet));
+ sal_Bool bNegativePage(pDoc->IsNegativePage(rMyCell.aCellAddress.Sheet));
+ if (bNegativePage)
+ aPoint.X = aRec.Right();
+ else
+ aPoint.X = aRec.Left();
+ aPoint.Y = aRec.Top();
+ ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin();
+ ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end());
+ while (aItr != aEndItr)
+ {
+ if (aItr->xShape.is())
+ {
+ if (bNegativePage)
+ aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X;
+ if ( !aItr->xShape->getShapeType().equals(sCaptionShape) )
+ {
+ Rectangle aEndRec(pDoc->GetMMRect(aItr->aEndAddress.Col(), aItr->aEndAddress.Row(),
+ aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), aItr->aEndAddress.Tab()));
+ rtl::OUString sEndAddress;
+ ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress);
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertMeasure(sBuffer, aItr->nEndX);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear());
+ GetMM100UnitConverter().convertMeasure(sBuffer, aItr->nEndY);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
+ }
+ ExportShape(aItr->xShape, &aPoint);
+ }
+ ++aItr;
+ }
+ }
+}
+
+void ScXMLExport::WriteTableShapes()
+{
+ ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes());
+ if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty())
+ {
+ DBG_ASSERT(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table");
+ SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, sal_True, false);
+ ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin());
+ ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end());
+ while (aItr != aEndItr)
+ {
+ if (aItr->is())
+ {
+ if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable)))
+ {
+ awt::Point aPoint((*aItr)->getPosition());
+ awt::Size aSize((*aItr)->getSize());
+ aPoint.X += aPoint.X + aSize.Width;
+ aPoint.Y = 0;
+ ExportShape(*aItr, &aPoint);
+ }
+ else
+ ExportShape(*aItr, NULL);
+ }
+ aItr = (*pTableShapes)[nCurrentTable].erase(aItr);
+ }
+ }
+}
+
+void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell )
+{
+ if( rMyCell.bHasAreaLink )
+ {
+ const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink;
+ AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr );
+ AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter );
+ if( rAreaLink.sFilterOptions.getLength() )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions );
+ OUStringBuffer sValue;
+ SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetColCount() );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() );
+ SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetRowCount() );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() );
+ if( rAreaLink.nRefresh )
+ {
+ SvXMLUnitConverter::convertTime( sValue, (double)rAreaLink.nRefresh / 86400 );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() );
+ }
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, sal_True, sal_True );
+ }
+}
+
+void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape)
+{
+ if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is())
+ {
+ rtl::OUString sAuthor(pCurrentCell->xAnnotation->getAuthor());
+ if (sAuthor.getLength())
+ {
+ SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC,
+ XML_CREATOR, sal_True,
+ false );
+ Characters(sAuthor);
+ }
+
+ String aDate(pCurrentCell->xAnnotation->getDate());
+ if (pDoc)
+ {
+ SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
+ double fDate;
+ sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
+ if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate))
+ {
+ rtl::OUStringBuffer sBuf;
+ GetMM100UnitConverter().convertDateTime(sBuf, fDate,sal_True);
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC,
+ XML_DATE, sal_True,
+ false );
+ Characters(sBuf.makeStringAndClear());
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ false );
+ Characters(rtl::OUString(aDate));
+ }
+ }
+ else
+ {
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META,
+ XML_DATE_STRING, sal_True,
+ false );
+ Characters(rtl::OUString(aDate));
+ }
+ }
+}
+
+void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell)
+{
+ if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is())
+ {
+
+ if (rMyCell.xAnnotation->getIsVisible())
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE);
+
+ pCurrentCell = &rMyCell;
+
+ if(rMyCell.xNoteShape.is())
+ GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL);
+
+ pCurrentCell = NULL;
+
+ rMyCell.xNoteShape.clear();
+ }
+}
+
+void ScXMLExport::WriteDetective( const ScMyCell& rMyCell )
+{
+ if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp )
+ {
+ const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec;
+ const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec;
+ sal_Int32 nObjCount(rObjVec.size());
+ sal_Int32 nOpCount(rOpVec.size());
+ if( nObjCount || nOpCount )
+ {
+ SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, sal_True, sal_True );
+ OUString sString;
+ ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin());
+ ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end());
+ while(aObjItr != aEndObjItr)
+ {
+ if (aObjItr->eObjType != SC_DETOBJ_CIRCLE)
+ {
+ if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB))
+ {
+ ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString );
+ }
+ ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString );
+ if( aObjItr->bHasError )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE );
+ }
+ else
+ AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE );
+ SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, sal_True, sal_True );
+ ++aObjItr;
+ }
+ OUStringBuffer aBuffer;
+ ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin());
+ ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end());
+ while(aOpItr != aEndOpItr)
+ {
+ OUString sOpString;
+ ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString );
+ SvXMLUnitConverter::convertNumber( aBuffer, aOpItr->nIndex );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() );
+ SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, sal_True, sal_True );
+ ++aOpItr;
+ }
+ }
+ }
+}
+
+void ScXMLExport::SetRepeatAttribute (const sal_Int32 nEqualCellCount)
+{
+ if (nEqualCellCount > 0)
+ {
+ sal_Int32 nTemp(nEqualCellCount + 1);
+ OUString sOUEqualCellCount(OUString::valueOf(nTemp));
+ AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount);
+ IncrementProgressBar(false, nEqualCellCount);
+ }
+}
+
+sal_Bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const
+{
+ return (aCell1.nType == aCell2.nType);
+}
+
+sal_Bool ScXMLExport::IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell) const
+{
+ ScAddress aCoreAddress(static_cast<SCCOL>(aAddress.Column),
+ static_cast<SCROW>(aAddress.Row),
+ static_cast<SCTAB>(aAddress.Sheet));
+ ScBaseCell* pBaseCell = GetDocument() ? GetDocument()->GetCell(aCoreAddress) : NULL;
+ if (pMyCell)
+ pMyCell->pBaseCell = pBaseCell;
+
+ if (pBaseCell)
+ return (pBaseCell->GetCellType() == CELLTYPE_EDIT);
+ return false;
+}
+
+sal_Bool ScXMLExport::IsEditCell(ScMyCell& rCell) const
+{
+ if (rCell.bKnowWhetherIsEditCell)
+ return rCell.bIsEditCell;
+ else
+ {
+ rCell.bIsEditCell = IsEditCell(rCell.aCellAddress, &rCell);
+ rCell.bKnowWhetherIsEditCell = sal_True;
+ return rCell.bIsEditCell;
+ }
+}
+
+sal_Bool ScXMLExport::IsMultiLineFormulaCell(ScMyCell& rCell) const
+{
+ if (rCell.pBaseCell)
+ {
+ if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
+ return false;
+
+ return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
+ }
+
+ ScAddress aAddr(static_cast<SCCOL>(rCell.aCellAddress.Column),
+ static_cast<SCROW>(rCell.aCellAddress.Row),
+ static_cast<SCTAB>(rCell.aCellAddress.Sheet));
+ ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aAddr) : NULL;
+ if (!pBaseCell)
+ return false;
+
+ rCell.pBaseCell = pBaseCell;
+ if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA)
+ return false;
+
+ return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult();
+}
+
+sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
+{
+ ScAddress aCellPos1;
+ ScUnoConversion::FillScAddress( aCellPos1, aCell1.aCellAddress );
+ ScAddress aCellPos2;
+ ScUnoConversion::FillScAddress( aCellPos2, aCell2.aCellAddress );
+ sal_Bool bIsEqual = false;
+ if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase &&
+ aCell1.bIsCovered == aCell2.bIsCovered &&
+ !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase &&
+ aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered &&
+ aCell1.bHasAnnotation == aCell2.bHasAnnotation &&
+ !aCell1.bHasShape && !aCell2.bHasShape &&
+ aCell1.bHasAreaLink == aCell2.bHasAreaLink &&
+ !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj)
+ {
+ if( (aCell1.bHasAreaLink &&
+ (aCell1.aAreaLink.GetColCount() == 1) &&
+ (aCell2.aAreaLink.GetColCount() == 1) &&
+ aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) ||
+ !aCell1.bHasAreaLink )
+ {
+ if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && false/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable
+ {
+ if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) ||
+ ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) &&
+ (aCell1.nValidationIndex == aCell2.nValidationIndex) &&
+ IsCellTypeEqual(aCell1, aCell2))
+ {
+ switch ( aCell1.nType )
+ {
+ case table::CellContentType_EMPTY :
+ {
+ bIsEqual = sal_True;
+ }
+ break;
+ case table::CellContentType_VALUE :
+ {
+ if(!aCell1.bHasDoubleValue)
+ {
+ aCell1.fValue = pDoc->GetValue( aCellPos1 );
+ aCell1.bHasDoubleValue = sal_True;
+ }
+ if (!aCell2.bHasDoubleValue)
+ {
+ aCell2.fValue = pDoc->GetValue( aCellPos2 );
+ aCell2.bHasDoubleValue = sal_True;
+ }
+ // #i29101# number format may be different from column default styles,
+ // but can lead to different value types, so it must also be compared
+ bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
+ (aCell1.fValue == aCell2.fValue);
+ }
+ break;
+ case table::CellContentType_TEXT :
+ {
+ if (IsEditCell(aCell1) || IsEditCell(aCell2))
+ bIsEqual = false;
+ else
+ {
+ if (GetCellText(aCell1, aCellPos1) && GetCellText(aCell2, aCellPos2))
+ {
+ bIsEqual = (aCell1.sStringValue == aCell2.sStringValue) &&
+ (lcl_GetRawString(pDoc, aCellPos1) == lcl_GetRawString(pDoc, aCellPos2));
+ }
+ else
+ bIsEqual = false;
+ }
+ }
+ break;
+ case table::CellContentType_FORMULA :
+ {
+ bIsEqual = false;
+ }
+ break;
+ default :
+ {
+ bIsEqual = false;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ return bIsEqual;
+}
+
+void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ sal_Bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN))) ));
+ sal_Bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE))) ));
+ sal_Bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS))) ));
+ sal_Bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE))) ));
+ sal_Bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED))) ));
+ sal_Bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED))) ));
+ sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0);
+ sal_Int32 nIterationCount(100);
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT))) >>= nIterationCount;
+ double fIterationEpsilon = 0;
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON))) >>= fIterationEpsilon;
+ util::Date aNullDate;
+ xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE))) >>= aNullDate;
+ if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions ||
+ bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) ||
+ aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930)
+ {
+ if (bIgnoreCase)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE);
+ if (bCalcAsShown)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE);
+ if (!bMatchWholeCell)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE);
+ if (!bLookUpLabels)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE);
+ if (!bUseRegularExpressions)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE);
+ if (nYear2000 != 1930)
+ {
+ rtl::OUStringBuffer sBuffer;
+ GetMM100UnitConverter().convertNumber(sBuffer, nYear2000);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True);
+ {
+ if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899)
+ {
+ rtl::OUStringBuffer sDate;
+ GetMM100UnitConverter().convertDateTime(sDate, 0.0, aNullDate);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear());
+ SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True);
+ }
+ if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001))
+ {
+ rtl::OUStringBuffer sBuffer;
+ if (bIsIterationEnabled)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE);
+ if (nIterationCount != 100)
+ {
+ GetMM100UnitConverter().convertNumber(sBuffer, nIterationCount);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear());
+ }
+ if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001))
+ {
+ GetMM100UnitConverter().convertDouble(sBuffer, fIterationEpsilon);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear());
+ }
+ SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, sal_True, sal_True);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::WriteTableSource()
+{
+ uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY);
+ if (xLinkable.is() && GetModel().is())
+ {
+ sheet::SheetLinkMode nMode (xLinkable->getLinkMode());
+ if (nMode != sheet::SheetLinkMode_NONE)
+ {
+ rtl::OUString sLink (xLinkable->getLinkUrl());
+ uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY);
+ if (xProps.is())
+ {
+ uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETLINKS))), uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nCount(xIndex->getCount());
+ if (nCount)
+ {
+ sal_Bool bFound(false);
+ uno::Reference <beans::XPropertySet> xLinkProps;
+ for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i)
+ {
+ xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY);
+ if (xLinkProps.is())
+ {
+ rtl::OUString sNewLink;
+ if (xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LINKURL))) >>= sNewLink)
+ bFound = sLink.equals(sNewLink);
+ }
+ }
+ if (bFound && xLinkProps.is())
+ {
+ rtl::OUString sFilter;
+ rtl::OUString sFilterOptions;
+ rtl::OUString sTableName (xLinkable->getLinkSheetName());
+ sal_Int32 nRefresh(0);
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTER))) >>= sFilter;
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTOPT))) >>= sFilterOptions;
+ xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh;
+ if (sLink.getLength())
+ {
+ AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink));
+ if (sTableName.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName);
+ if (sFilter.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter);
+ if (sFilterOptions.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions);
+ if (nMode != sheet::SheetLinkMode_NORMAL)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
+ if( nRefresh )
+ {
+ rtl::OUStringBuffer sBuffer;
+ SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() );
+ }
+ SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// core implementation
+void ScXMLExport::WriteScenario()
+{
+ if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable)))
+ {
+ String sComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+ pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags);
+ if (!(nFlags & SC_SCENARIO_SHOWFRAME))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE);
+ rtl::OUStringBuffer aBuffer;
+ SvXMLUnitConverter::convertColor(aBuffer, aColor);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear());
+ if (!(nFlags & SC_SCENARIO_TWOWAY))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE);
+ if (!(nFlags & SC_SCENARIO_ATTRIB))
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE);
+ if (nFlags & SC_SCENARIO_VALUE)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE);
+ if (nFlags & SC_SCENARIO_PROTECT)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
+ SvXMLUnitConverter::convertBool(aBuffer, pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable)));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear());
+ const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable));
+ rtl::OUString sRangeListStr;
+ ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr);
+ if (sComment.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, rtl::OUString(sComment));
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, sal_True, sal_True);
+ }
+}
+
+void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc )
+{
+ uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY );
+ if( !xDocProp.is() ) return;
+
+ sal_Int32 nCount(0);
+ uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLLABELRNG ) ) ), uno::UNO_QUERY);
+ if( xColRangesIAccess.is() )
+ nCount += xColRangesIAccess->getCount();
+
+ uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ROWLABELRNG ) ) ), uno::UNO_QUERY);
+ if( xRowRangesIAccess.is() )
+ nCount += xRowRangesIAccess->getCount();
+
+ if( nCount )
+ {
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, sal_True, sal_True );
+ WriteLabelRanges( xColRangesIAccess, sal_True );
+ WriteLabelRanges( xRowRangesIAccess, false );
+ }
+}
+
+void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn )
+{
+ if( !xRangesIAccess.is() ) return;
+
+ sal_Int32 nCount(xRangesIAccess->getCount());
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
+ if( xRange.is() )
+ {
+ OUString sRangeStr;
+ table::CellRangeAddress aCellRange( xRange->getLabelArea() );
+ ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr );
+ aCellRange = xRange->getDataArea();
+ ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW );
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, sal_True, sal_True );
+ }
+ }
+}
+
+void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc)
+{
+ uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY);
+ if (!xPropertySet.is())
+ return;
+
+ uno::Reference <sheet::XNamedRanges> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NAMEDRANGES))), uno::UNO_QUERY);
+ CheckAttrList();
+ if (!xNamedRanges.is())
+ return;
+
+ uno::Sequence <rtl::OUString> aRangesNames(xNamedRanges->getElementNames());
+ sal_Int32 nNamedRangesCount = aRangesNames.getLength();
+ if (nNamedRangesCount <= 0)
+ return;
+
+ if (!pDoc)
+ return;
+
+ ScRangeName* pNamedRanges = pDoc->GetRangeName();
+ SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True);
+ for (sal_Int32 i = 0; i < nNamedRangesCount; ++i)
+ {
+ CheckAttrList();
+ rtl::OUString sNamedRange(aRangesNames[i]);
+ uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName(sNamedRange), uno::UNO_QUERY);
+ if (!xNamedRange.is())
+ continue;
+
+ uno::Reference <container::XNamed> xNamed (xNamedRange, uno::UNO_QUERY);
+ uno::Reference <sheet::XCellRangeReferrer> xCellRangeReferrer (xNamedRange, uno::UNO_QUERY);
+ if (!xNamed.is() || !xCellRangeReferrer.is())
+ continue;
+
+ rtl::OUString sOUName(xNamed->getName());
+ AddAttribute(sAttrName, sOUName);
+
+ OUString sOUBaseCellAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseCellAddress,
+ xNamedRange->getReferencePosition(), pDoc, FormulaGrammar::CONV_OOO, ' ', sal_False, SCA_ABS_3D );
+ AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sOUBaseCellAddress);
+
+ const ScRangeData* pNamedRange = pNamedRanges->findByName(sOUName);
+ String sContent;
+ pNamedRange->GetSymbol(sContent, pDoc->GetStorageGrammar());
+ rtl::OUString sOUTempContent(sContent);
+ uno::Reference <table::XCellRange> xCellRange(xCellRangeReferrer->getReferredCells());
+ if(xCellRange.is())
+ {
+ rtl::OUString sOUContent(sOUTempContent.copy(1, sOUTempContent.getLength() - 2));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sOUContent);
+ sal_Int32 nRangeType(xNamedRange->getType());
+ rtl::OUStringBuffer sBufferRangeType;
+ if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER)
+ sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN));
+ if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW));
+ }
+ if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_FILTER));
+ }
+ if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA)
+ {
+ if (sBufferRangeType.getLength() > 0)
+ sBufferRangeType.appendAscii(" ");
+ sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE));
+ }
+ rtl::OUString sRangeType = sBufferRangeType.makeStringAndClear();
+ if (sRangeType.getLength())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType);
+ SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, sal_True, sal_True);
+ }
+ else
+ {
+ AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sOUTempContent);
+ SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True);
+ }
+ }
+}
+
+void ScXMLExport::WriteExternalRefCaches()
+{
+ if (!pDoc)
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pRefMgr->resetSrcFileData(GetOrigFileName());
+ sal_uInt16 nCount = pRefMgr->getExternalFileCount();
+ for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
+ {
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
+ continue;
+
+ vector<OUString> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
+ continue;
+
+ for (vector<OUString>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end();
+ itr != itrEnd; ++itr)
+ {
+ ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
+ if (!pTable.get() || !pTable->isReferenced())
+ continue;
+
+ OUStringBuffer aBuf;
+ aBuf.append(sal_Unicode('\''));
+ aBuf.append(*pUrl);
+ aBuf.append(sal_Unicode('\''));
+ aBuf.append(sal_Unicode('#'));
+ aBuf.append(*itr);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aBuf.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName);
+ SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True);
+ {
+ const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId);
+ if (pExtFileData)
+ {
+ String aRelUrl;
+ if (pExtFileData->maRelativeName.Len())
+ aRelUrl = pExtFileData->maRelativeName;
+ else
+ aRelUrl = GetRelativeReference(pExtFileData->maRelativeName);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr);
+ if (pExtFileData->maFilterName.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName);
+ if (pExtFileData->maFilterOptions.Len())
+ AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY);
+ }
+ SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True);
+ }
+
+ // Determine maximum column count of used area, for repeated cells.
+ SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere..
+ vector<SCROW> aRows;
+ pTable->getAllRows(aRows);
+ for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
+ itrRow != itrRowEnd; ++itrRow)
+ {
+ SCROW nRow = *itrRow;
+ vector<SCCOL> aCols;
+ pTable->getAllCols(nRow, aCols);
+ if (!aCols.empty())
+ {
+ SCCOL nCol = aCols.back();
+ if (nMaxColsUsed <= nCol)
+ nMaxColsUsed = nCol + 1;
+ }
+ }
+
+ // Column definitions have to be present to make a valid file
+ {
+ if (nMaxColsUsed > 1)
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
+ OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed)));
+ SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True);
+ }
+
+ // Write cache content for this table.
+ SCROW nLastRow = 0;
+ bool bFirstRow = true;
+ for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end();
+ itrRow != itrRowEnd; ++itrRow)
+ {
+ SCROW nRow = *itrRow;
+ if (bFirstRow)
+ {
+ if (nRow > 0)
+ {
+ if (nRow > 1)
+ {
+ OUStringBuffer aVal;
+ aVal.append(nRow);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ else
+ {
+ SCROW nRowGap = nRow - nLastRow;
+ if (nRowGap > 1)
+ {
+ if (nRowGap > 2)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nRowGap-1));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nMaxColsUsed));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True);
+
+ vector<SCCOL> aCols;
+ pTable->getAllCols(nRow, aCols);
+ SCCOL nLastCol = 0;
+ bool bFirstCol = true;
+ for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
+ itrCol != itrColEnd; ++itrCol)
+ {
+ SCCOL nCol = *itrCol;
+ if (bFirstCol)
+ {
+ if (nCol > 0)
+ {
+ if (nCol > 1)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nCol));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+ else
+ {
+ SCCOL nColGap = nCol - nLastCol;
+ if (nColGap > 1)
+ {
+ if (nColGap > 2)
+ {
+ OUStringBuffer aVal;
+ aVal.append(static_cast<sal_Int32>(nColGap-1));
+ AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear());
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ }
+ }
+
+ // Write out this cell.
+ sal_uInt32 nNumFmt = 0;
+ ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt);
+ OUString aStrVal;
+ if (pToken.get())
+ {
+ sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt);
+ if (nIndex >= 0)
+ {
+ const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true);
+ AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName);
+ }
+
+ switch(pToken->GetType())
+ {
+ case svDouble:
+ {
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
+ OUStringBuffer aVal;
+ aVal.append(pToken->GetDouble());
+ aStrVal = aVal.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal);
+ }
+ break;
+ case svString:
+ {
+ AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
+ aStrVal = pToken->GetString();
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
+ SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, sal_True, false);
+ Characters(aStrVal);
+
+ nLastCol = nCol;
+ bFirstCol = false;
+ }
+ nLastRow = nRow;
+ bFirstRow = false;
+ }
+ }
+ }
+}
+
+// core implementation
+void ScXMLExport::WriteConsolidation()
+{
+ if (pDoc)
+ {
+ const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData());
+ if( pCons )
+ {
+ OUString sStrData;
+
+ ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData );
+
+ sStrData = OUString();
+ for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex )
+ ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, sal_True );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData );
+
+ ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO );
+ AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData );
+
+ if( pCons->bByCol && !pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN );
+ else if( !pCons->bByCol && pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW );
+ else if( pCons->bByCol && pCons->bByRow )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH );
+
+ if( pCons->bReferenceData )
+ AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE );
+
+ SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, sal_True, sal_True );
+ }
+ }
+}
+
+SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool()
+{
+ return new ScXMLAutoStylePoolP(*this);
+}
+
+XMLPageExport* ScXMLExport::CreatePageExport()
+{
+ return new XMLTableMasterPageExport( *this );
+}
+
+void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL);
+ if (pViewSettings)
+ {
+ sal_Int32 nChangePos(rProps.getLength());
+ rProps.realloc(nChangePos + 1);
+ beans::PropertyValue* pProps(rProps.getArray());
+ if (pProps)
+ {
+ uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT);
+ beans::PropertyValue* pChangeProps(aChangeProps.getArray());
+ if (pChangeProps)
+ {
+ pChangeProps[SC_SHOW_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
+ pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges();
+ pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowAcceptedChanges"));
+ pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted();
+ pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRejectedChanges"));
+ pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected();
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate();
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeMode"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode());
+ util::DateTime aDateTime;
+ ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheFirstDateTime(), aDateTime);
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeFirstDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= aDateTime;
+ ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheLastDateTime(), aDateTime);
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeSecondDatetime"));
+ pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= aDateTime;
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthor"));
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor();
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthorName"));
+ pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= rtl::OUString (pViewSettings->GetTheAuthorToShow());
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByComment"));
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment();
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByCommentText"));
+ pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= rtl::OUString (pViewSettings->GetTheComment());
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRanges"));
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange();
+ rtl::OUString sRangeList;
+ ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO);
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRangesList"));
+ pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList;
+
+ pProps[nChangePos].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesViewSettings"));
+ pProps[nChangePos].Value <<= aChangeProps;
+ }
+ }
+ }
+}
+
+void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ rProps.realloc(4);
+ beans::PropertyValue* pProps(rProps.getArray());
+ if(pProps)
+ {
+ if (GetModel().is())
+ {
+ ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
+ if (pDocObj)
+ {
+ SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
+ if (pEmbeddedObj)
+ {
+ Rectangle aRect(pEmbeddedObj->GetVisArea());
+ sal_uInt16 i(0);
+ pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth());
+ pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight"));
+ pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight());
+ }
+ }
+ }
+ }
+ GetChangeTrackViewSettings(rProps);
+}
+
+
+
+
+void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ SvXMLUnitConverter::convertPropertySet(rProps, xProperties);
+
+ sal_Int32 nPropsToAdd = 0;
+ rtl::OUStringBuffer aTrackedChangesKey;
+ if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected())
+ {
+ SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection());
+ if (aTrackedChangesKey.getLength())
+ ++nPropsToAdd;
+ }
+
+ bool bVBACompat = false;
+ uno::Reference <container::XNameAccess> xCodeNameAccess;
+ DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" );
+ if( pDoc && pDoc->IsInVBAMode() )
+ {
+ // VBA compatibility mode
+ bVBACompat = true;
+ ++nPropsToAdd;
+ // code names
+ xCodeNameAccess = new XMLCodeNameProvider( pDoc );
+ if( xCodeNameAccess->hasElements() )
+ ++nPropsToAdd;
+ else
+ xCodeNameAccess.clear();
+ }
+
+ if( nPropsToAdd > 0 )
+ {
+ sal_Int32 nCount(rProps.getLength());
+ rProps.realloc(nCount + nPropsToAdd);
+ if (aTrackedChangesKey.getLength())
+ {
+ rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
+ rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear();
+ ++nCount;
+ }
+ if( bVBACompat )
+ {
+ rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"));
+ rProps[nCount].Value <<= bVBACompat;
+ ++nCount;
+ }
+ if( xCodeNameAccess.is() )
+ {
+ rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
+ rProps[nCount].Value <<= xCodeNameAccess;
+ ++nCount;
+ }
+ }
+ }
+ }
+}
+
+XMLShapeExport* ScXMLExport::CreateShapeExport()
+{
+ return new ScXMLShapeExport(*this);
+}
+
+void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount)
+{
+ pSharedData = new ScMySharedData(nTableCount);
+}
+
+XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper()
+{
+ if (!pNumberFormatAttributesExportHelper)
+ pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this );
+ return pNumberFormatAttributesExportHelper;
+}
+
+void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
+{
+ const SfxPoolItem* pItem;
+ sal_uInt32 nItems(pPool->GetItemCount2( nAttrib ));
+ for( sal_uInt32 i = 0; i < nItems; ++i )
+ {
+ if( 0 != (pItem = pPool->GetItem2( nAttrib, i ) ) )
+ {
+ const SvXMLAttrContainerItem *pUnknown((const SvXMLAttrContainerItem *)pItem);
+ if( (pUnknown->GetAttrCount() > 0) )
+ {
+ sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
+ while( USHRT_MAX != nIdx )
+ {
+ if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
+ {
+ const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
+ // Add namespace declaration for unknown attributes if
+ // there aren't existing ones for the prefix used by the
+ // attibutes
+ _GetNamespaceMap().Add( rPrefix,
+ pUnknown->GetNamespace( nIdx ),
+ XML_NAMESPACE_UNKNOWN );
+ }
+ nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
+ }
+ }
+ }
+ }
+
+ // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
+ _GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_PRESENTATION ),
+ GetXMLToken( XML_N_PRESENTATION ),
+ XML_NAMESPACE_PRESENTATION );
+}
+
+void ScXMLExport::IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc)
+{
+ nProgressCount += nInc;
+ if (bEditCell || nProgressCount > 100)
+ {
+ GetProgressBarHelper()->Increment(nProgressCount);
+ nProgressCount = 0;
+ }
+}
+
+sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass )
+{
+ if( (getExportFlags() & (EXPORT_FONTDECLS|EXPORT_STYLES|
+ EXPORT_MASTERSTYLES|EXPORT_CONTENT)) != 0 )
+ {
+ if (GetDocument())
+ {
+ CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF);
+ CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS);
+ CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS);
+ ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS);
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS);
+ CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES);
+ }
+
+ // sheet events use officeooo namespace
+ if( (getExportFlags() & EXPORT_CONTENT) != 0 &&
+ getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST )
+ {
+ bool bAnySheetEvents = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (pDoc->GetSheetEvents(nTab))
+ bAnySheetEvents = true;
+ if (bAnySheetEvents)
+ _GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_OFFICE_EXT ),
+ GetXMLToken( XML_N_OFFICE_EXT ),
+ XML_NAMESPACE_OFFICE_EXT );
+ }
+ }
+ }
+ return SvXMLExport::exportDoc( eClass );
+}
+
+// XExporter
+void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ SvXMLExport::setSourceDocument( xComponent );
+
+ pDoc = ScXMLConverter::GetScDocument( GetModel() );
+ DBG_ASSERT( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" );
+ if (!pDoc)
+ throw lang::IllegalArgumentException();
+
+ // create ScChangeTrackingExportHelper after document is known
+ pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this);
+
+ // Set the document's storage grammar corresponding to the ODF version that
+ // is to be written.
+ SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion();
+ switch (meODFDefaultVersion)
+ {
+ // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF
+ case SvtSaveOptions::ODFVER_010:
+ case SvtSaveOptions::ODFVER_011:
+ pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF);
+ break;
+ default:
+ pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF);
+ }
+}
+
+// XFilter
+sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (pDoc)
+ pDoc->DisableIdle(sal_True);
+ sal_Bool bReturn(SvXMLExport::filter(aDescriptor));
+ if (pDoc)
+ pDoc->DisableIdle(false);
+ return bReturn;
+}
+
+void SAL_CALL ScXMLExport::cancel()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (pDoc)
+ pDoc->DisableIdle(false);
+ SvXMLExport::cancel();
+}
+
+// XInitialization
+void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ SvXMLExport::initialize(aArguments);
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ScXMLExport::getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ sal_uInt16 nFlags = getExportFlags();
+ if (nFlags & EXPORT_OASIS)
+ {
+ nFlags |= EXPORT_OASIS;
+ switch( nFlags )
+ {
+ case EXPORT_ALL:
+ return ScXMLOasisExport_getImplementationName();
+ case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
+ return ScXMLOasisExport_Styles_getImplementationName();
+ case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
+ return ScXMLOasisExport_Content_getImplementationName();
+ case EXPORT_META:
+ return ScXMLOasisExport_Meta_getImplementationName();
+ case EXPORT_SETTINGS:
+ return ScXMLOasisExport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLOasisExport_getImplementationName();
+ }
+ }
+ else
+ {
+ switch( nFlags )
+ {
+ case EXPORT_ALL:
+ return ScXMLOOoExport_getImplementationName();
+ case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS):
+ return ScXMLOOoExport_Styles_getImplementationName();
+ case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS):
+ return ScXMLOOoExport_Content_getImplementationName();
+ case EXPORT_META:
+ return ScXMLOOoExport_Meta_getImplementationName();
+ case EXPORT_SETTINGS:
+ return ScXMLOOoExport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLOOoExport_getImplementationName();
+ }
+ }
+ return SvXMLExport::getImplementationName();
+}
+
+sal_Bool SAL_CALL ScXMLExport::supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return SvXMLExport::supportsService( ServiceName );
+}
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScXMLExport::getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return SvXMLExport::getSupportedServiceNames();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return SvXMLExport::getSomething(aIdentifier);
+}
+
+void ScXMLExport::DisposingModel()
+{
+ SvXMLExport::DisposingModel();
+ pDoc = NULL;
+ xCurrentTable = 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
new file mode 100644
index 000000000000..7dcd400b8a68
--- /dev/null
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLEXPRT_HXX
+#define SC_XMLEXPRT_HXX
+
+#include <xmloff/xmlexp.hxx>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace beans { class XPropertySet; }
+} } }
+
+#include <boost/unordered_map.hpp>
+
+class ScOutlineArray;
+class SvXMLExportPropertyMapper;
+class ScMyShapesContainer;
+class ScMyMergedRangesContainer;
+class ScMyValidationsContainer;
+class ScMyNotEmptyCellsIterator;
+class ScChangeTrackingExportHelper;
+class ScColumnStyles;
+class ScRowStyles;
+class ScFormatRangeStyles;
+class ScRowFormatRanges;
+class ScMyOpenCloseColumnRowGroup;
+class ScMyAreaLinksContainer;
+class ScMyDetectiveOpContainer;
+struct ScMyCell;
+class ScDocument;
+class ScMySharedData;
+class ScMyDefaultStyles;
+class XMLNumberFormatAttributesExportHelper;
+class ScChartListener;
+class SfxItemPool;
+class ScAddress;
+class ScBaseCell;
+class ScXMLCachedRowAttrAccess;
+
+typedef std::vector< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes > > ScMyXShapesVec;
+
+class ScXMLExport : public SvXMLExport
+{
+ ScDocument* pDoc;
+ com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet> xCurrentTable;
+ com::sun::star::uno::Reference <com::sun::star::table::XCellRange> xCurrentTableCellRange;
+
+ com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xSourceStream;
+ sal_Int32 nSourceStreamPos;
+
+ UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory;
+ UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xCellStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xColumnStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xRowStylesExportPropertySetMapper;
+ UniReference < SvXMLExportPropertyMapper > xTableStylesExportPropertySetMapper;
+ XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper;
+ typedef ::boost::unordered_map<sal_Int32, sal_Int32> NumberFormatIndexMap;
+ NumberFormatIndexMap aNumFmtIndexMap;
+ ScMySharedData* pSharedData;
+ ScColumnStyles* pColumnStyles;
+ ScRowStyles* pRowStyles;
+ ScFormatRangeStyles* pCellStyles;
+ ScRowFormatRanges* pRowFormatRanges;
+ std::vector<rtl::OUString> aTableStyles;
+ com::sun::star::table::CellRangeAddress aRowHeaderRange;
+ ScMyOpenCloseColumnRowGroup* pGroupColumns;
+ ScMyOpenCloseColumnRowGroup* pGroupRows;
+ ScMyDefaultStyles* pDefaults;
+ ScChartListener* pChartListener;
+ const ScMyCell* pCurrentCell;
+
+ ScMyMergedRangesContainer* pMergedRangesContainer;
+ ScMyValidationsContainer* pValidationsContainer;
+ ScMyNotEmptyCellsIterator* pCellsItr;
+ ScChangeTrackingExportHelper* pChangeTrackingExportHelper;
+ const rtl::OUString sLayerID;
+ const rtl::OUString sCaptionShape;
+ rtl::OUString sExternalRefTabStyleName;
+ rtl::OUString sAttrName;
+ rtl::OUString sAttrStyleName;
+ rtl::OUString sAttrColumnsRepeated;
+ rtl::OUString sAttrFormula;
+ rtl::OUString sAttrValueType;
+ rtl::OUString sAttrStringValue;
+ rtl::OUString sElemCell;
+ rtl::OUString sElemCoveredCell;
+ rtl::OUString sElemCol;
+ rtl::OUString sElemRow;
+ rtl::OUString sElemTab;
+ rtl::OUString sElemP;
+ sal_Int32 nOpenRow;
+ sal_Int32 nProgressCount;
+ sal_uInt16 nCurrentTable;
+ sal_Bool bHasRowHeader;
+ sal_Bool bRowHeaderOpen;
+ sal_Bool mbShowProgress;
+
+ sal_Int32 GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const;
+ sal_Bool HasDrawPages(com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xDoc);
+ void CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount);
+ void CollectShapesAutoStyles(const sal_Int32 nTableCount);
+ void WriteTablesView(const com::sun::star::uno::Any& aTableView);
+ void WriteView(const com::sun::star::uno::Any& aView);
+ virtual void _ExportFontDecls();
+ virtual void _ExportStyles( sal_Bool bUsed );
+ virtual void _ExportAutoStyles();
+ virtual void _ExportMasterStyles();
+ virtual void SetBodyAttributes();
+ virtual void _ExportContent();
+ virtual void _ExportMeta();
+
+ void CollectInternalShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ com::sun::star::table::CellRangeAddress GetEndAddress(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable,
+ const sal_Int32 nTable);
+// ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
+ void GetAreaLinks( com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, ScMyAreaLinksContainer& rAreaLinks );
+ void GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp );
+ void WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
+ const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible);
+ void WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns,
+ const sal_Int32 nStyleIndex, const sal_Bool bIsVisible);
+ void OpenHeaderColumn();
+ void CloseHeaderColumn();
+ void ExportColumns(const sal_Int32 nTable, const com::sun::star::table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader);
+ void ExportExternalRefCacheStyles();
+ void ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
+ const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet);
+ void WriteRowContent();
+ void WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int32 nEmptyRows, bool bHidden, bool bFiltered);
+ void OpenHeaderRows();
+ void CloseHeaderRows();
+ void OpenNewRow(const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows,
+ bool bHidden, bool bFiltered);
+ void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows,
+ bool bHidden, bool bFiltered);
+ void OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr);
+ void CloseRow(const sal_Int32 nRow);
+ void GetColumnRowHeader(sal_Bool& bHasColumnHeader, com::sun::star::table::CellRangeAddress& aColumnHeaderRange,
+ sal_Bool& bHasRowHeader, com::sun::star::table::CellRangeAddress& aRowHeaderRange,
+ rtl::OUString& rPrintRanges) const;
+ void FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups);
+ void FillColumnRowGroups();
+
+ sal_Bool GetMerged (const com::sun::star::table::CellRangeAddress* pCellRange,
+ const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable);
+
+ sal_Bool GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const;
+
+ void WriteTable(sal_Int32 nTable, const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet>& xTable);
+ void WriteCell (ScMyCell& aCell);
+ void WriteAreaLink(const ScMyCell& rMyCell);
+ void WriteAnnotation(ScMyCell& rMyCell);
+ void WriteDetective(const ScMyCell& rMyCell);
+ void ExportShape(const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape, com::sun::star::awt::Point* pPoint);
+ void WriteShapes(const ScMyCell& rMyCell);
+ void WriteTableShapes();
+ void SetRepeatAttribute (const sal_Int32 nEqualCellCount);
+
+ sal_Bool IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const;
+ sal_Bool IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell = NULL) const;
+ sal_Bool IsEditCell(ScMyCell& rCell) const;
+ sal_Bool IsMultiLineFormulaCell(ScMyCell& rCell) const;
+ sal_Bool IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2);
+
+ void WriteCalculationSettings(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+ void WriteTableSource();
+ void WriteScenario(); // core implementation
+ void WriteTheLabelRanges(const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc);
+ void WriteLabelRanges( const com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn );
+ void WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc);
+ void WriteExternalRefCaches();
+ void WriteConsolidation(); // core implementation
+
+ void CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib);
+
+ void AddStyleFromCells(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xProperties,
+ const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheet >& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName );
+ void AddStyleFromColumn(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible );
+ void AddStyleFromRow(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex );
+
+ void IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc = 1);
+
+ void CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd );
+
+protected:
+ virtual SvXMLAutoStylePoolP* CreateAutoStylePool();
+ virtual XMLPageExport* CreatePageExport();
+ virtual XMLShapeExport* CreateShapeExport();
+ virtual XMLFontAutoStylePool* CreateFontAutoStylePool();
+public:
+ // #110680#
+ ScXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nExportFlag);
+
+ virtual ~ScXMLExport();
+
+ static sal_Int16 GetFieldUnit();
+ inline ScDocument* GetDocument() { return pDoc; }
+ inline const ScDocument* GetDocument() const { return pDoc; }
+ sal_Bool IsMatrix (const ScAddress& aCell,
+ com::sun::star::table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const;
+
+ UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() { return xCellStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() { return xTableStylesPropertySetMapper; }
+
+ void SetSourceStream( const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xNewStream );
+
+ void GetChangeTrackViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+ virtual void GetViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+ virtual void GetConfigurationSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
+
+ virtual void exportAnnotationMeta( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape);
+
+ void CreateSharedData(const sal_Int32 nTableCount);
+ void SetSharedData(ScMySharedData* pTemp) { pSharedData = pTemp; }
+ ScMySharedData* GetSharedData() { return pSharedData; }
+ XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper();
+
+ // Export the document.
+ virtual sal_uInt32 exportDoc( enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_TOKEN_INVALID );
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual void DisposingModel();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx
new file mode 100644
index 000000000000..1e2277465c2a
--- /dev/null
+++ b/sc/source/filter/xml/xmlexternaltabi.cxx
@@ -0,0 +1,440 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlexternaltabi.hxx"
+#include "xmlimprt.hxx"
+#include "xmltabi.hxx"
+#include "xmlstyli.hxx"
+
+#include "token.hxx"
+#include "document.hxx"
+
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
+
+// ============================================================================
+
+ScXMLExternalRefTabSourceContext::ScXMLExternalRefTabSourceContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo)
+{
+ using namespace ::xmloff::token;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
+ rtl::OUString aLocalName;
+ sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ if (nAttrPrefix == XML_NAMESPACE_XLINK)
+ {
+ if (IsXMLToken(aLocalName, XML_HREF))
+ maRelativeUrl = sValue;
+ }
+ else if (nAttrPrefix == XML_NAMESPACE_TABLE)
+ {
+ if (IsXMLToken(aLocalName, XML_TABLE_NAME))
+ maTableName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_NAME))
+ maFilterName = sValue;
+ else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS))
+ maFilterOptions = sValue;
+ }
+ }
+}
+
+ScXMLExternalRefTabSourceContext::~ScXMLExternalRefTabSourceContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefTabSourceContext::CreateChildContext(
+ sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+/**
+ * Make sure the URL is a valid relative URL, mainly to avoid storing
+ * absolute URL as relative URL by accident. For now, we only check the first
+ * three characters which are assumed to be always '../', because the relative
+ * URL for an external document is always in reference to the content.xml
+ * fragment of the original document.
+ */
+static bool lcl_isValidRelativeURL(const OUString& rUrl)
+{
+ sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3));
+ if (n < 3)
+ return false;
+ const sal_Unicode* p = rUrl.getStr();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (i < 2 && c != '.')
+ // the path must begin with '..'
+ return false;
+ else if (i == 2 && c != '/')
+ // a '/' path separator must follow
+ return false;
+ }
+ return true;
+}
+
+void ScXMLExternalRefTabSourceContext::EndElement()
+{
+ ScDocument* pDoc = mrScImport.GetDocument();
+ if (!pDoc)
+ return;
+
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ if (lcl_isValidRelativeURL(maRelativeUrl))
+ pRefMgr->setRelativeFileName(mrExternalRefInfo.mnFileId, maRelativeUrl);
+ pRefMgr->setFilterData(mrExternalRefInfo.mnFileId, maFilterName, maFilterOptions);
+}
+
+// ============================================================================
+
+ScXMLExternalRefRowsContext::ScXMLExternalRefRowsContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& /* xAttrList */, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo)
+{
+}
+
+ScXMLExternalRefRowsContext::~ScXMLExternalRefRowsContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefRowsContext::CreateChildContext(
+ sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ // #i101319# row elements inside group, rows or header-rows
+ // are treated like row elements directly in the table element
+
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowsElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROWS_ROW_GROUP:
+ case XML_TOK_TABLE_ROWS_HEADER_ROWS:
+ case XML_TOK_TABLE_ROWS_ROWS:
+ return new ScXMLExternalRefRowsContext(
+ mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+ case XML_TOK_TABLE_ROWS_ROW:
+ return new ScXMLExternalRefRowContext(
+ mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+ default:
+ ;
+ }
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefRowsContext::EndElement()
+{
+}
+
+// ============================================================================
+
+ScXMLExternalRefRowContext::ScXMLExternalRefRowContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo),
+ mnRepeatRowCount(1)
+{
+ mrExternalRefInfo.mnCol = 0;
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = mrScImport.GetTableRowAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
+ rtl::OUString aLocalName;
+ sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+
+ switch (rAttrTokenMap.Get(nAttrPrefix, aLocalName))
+ {
+ case XML_TOK_TABLE_ROW_ATTR_REPEATED:
+ {
+ mnRepeatRowCount = std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
+ }
+ break;
+ }
+ }
+}
+
+ScXMLExternalRefRowContext::~ScXMLExternalRefRowContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefRowContext::CreateChildContext(
+ sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL)
+ return new ScXMLExternalRefCellContext(mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefRowContext::EndElement()
+{
+ ScExternalRefCache::TableTypeRef pTab = mrExternalRefInfo.mpCacheTable;
+
+ for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
+ {
+ // Performance: duplicates of a non-existent row will still not exist.
+ // Don't find that out for every cell.
+ // External references often are a sparse matrix.
+ if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
+ {
+ mrExternalRefInfo.mnRow += mnRepeatRowCount;
+ return;
+ }
+
+ for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
+ {
+ ScExternalRefCache::TokenRef pToken = pTab->getCell(
+ static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow));
+
+ if (pToken.get())
+ {
+ pTab->setCell(static_cast<SCCOL>(j),
+ static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
+ }
+ }
+ }
+ mrExternalRefInfo.mnRow += mnRepeatRowCount;
+}
+
+// ============================================================================
+
+ScXMLExternalRefCellContext::ScXMLExternalRefCellContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrExternalRefInfo(rRefInfo),
+ mfCellValue(0.0),
+ mnRepeatCount(1),
+ mnNumberFormat(-1),
+ mnCellType(::com::sun::star::util::NumberFormat::UNDEFINED),
+ mbIsNumeric(false),
+ mbIsEmpty(true)
+{
+ using namespace ::xmloff::token;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ OUString aLocalName;
+ sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
+ xAttrList->getNameByIndex(i), &aLocalName);
+
+ const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
+ sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
+
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
+ {
+ XMLTableStylesContext* pStyles = static_cast<XMLTableStylesContext*>(mrScImport.GetAutoStyles());
+ const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>(
+ pStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sValue, true));
+ if (pStyle)
+ mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat();
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
+ {
+ mnRepeatCount = ::std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
+ {
+ mnCellType = mrScImport.GetCellType(sValue);
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mrScImport.GetMM100UnitConverter().convertDouble(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
+ {
+ if (sValue.getLength() && mrScImport.SetNullDateOnUnitConverter())
+ {
+ mrScImport.GetMM100UnitConverter().convertDateTime(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mrScImport.GetMM100UnitConverter().convertTime(mfCellValue, sValue);
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ maCellString = sValue;
+ mbIsNumeric = false;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
+ {
+ if (sValue.getLength())
+ {
+ mfCellValue = IsXMLToken(sValue, XML_TRUE) ? 1.0 : 0.0;
+ mbIsNumeric = true;
+ mbIsEmpty = false;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLExternalRefCellContext::~ScXMLExternalRefCellContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext(
+ sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ if (nToken == XML_TOK_TABLE_ROW_CELL_P)
+ return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this);
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefCellContext::EndElement()
+{
+ if (maCellString.getLength())
+ mbIsEmpty = false;
+
+ for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol)
+ {
+ if (mbIsEmpty)
+ continue;
+
+ ScExternalRefCache::TokenRef aToken;
+ if (mbIsNumeric)
+ aToken.reset(new formula::FormulaDoubleToken(mfCellValue));
+ else
+ aToken.reset(new formula::FormulaStringToken(maCellString));
+
+ sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0;
+ mrExternalRefInfo.mpCacheTable->setCell(
+ static_cast<SCCOL>(mrExternalRefInfo.mnCol),
+ static_cast<SCROW>(mrExternalRefInfo.mnRow),
+ aToken, nNumFmt);
+ }
+}
+
+void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr)
+{
+ maCellString = rStr;
+}
+
+// ============================================================================
+
+ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& /*xAttrList*/,
+ ScXMLExternalRefCellContext& rParent ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+ mrParent(rParent)
+{
+}
+
+ScXMLExternalRefCellTextContext::~ScXMLExternalRefCellTextContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext(
+ sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar)
+{
+ maCellStrBuf.append(rChar);
+}
+
+void ScXMLExternalRefCellTextContext::EndElement()
+{
+ mrParent.SetCellString(maCellStrBuf.makeStringAndClear());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlexternaltabi.hxx b/sc/source/filter/xml/xmlexternaltabi.hxx
new file mode 100644
index 000000000000..1d3d1c836fe7
--- /dev/null
+++ b/sc/source/filter/xml/xmlexternaltabi.hxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLEXTERNALTABI_HXX
+#define SC_XMLEXTERNALTABI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include "rtl/ustrbuf.hxx"
+
+class ScXMLImport;
+struct ScXMLExternalTabData;
+
+class ScXMLExternalRefTabSourceContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefTabSourceContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefTabSourceContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+
+ ::rtl::OUString maRelativeUrl;
+ ::rtl::OUString maTableName;
+ ::rtl::OUString maFilterName;
+ ::rtl::OUString maFilterOptions;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefRowsContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefRowsContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefRowsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefRowContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefRowContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefRowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+ sal_Int32 mnRepeatRowCount;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefCellContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefCellContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalTabData& rRefInfo );
+
+ virtual ~ScXMLExternalRefCellContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetCellString(const ::rtl::OUString& rStr);
+
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+ ::rtl::OUString maCellString;
+ double mfCellValue;
+ sal_Int32 mnRepeatCount;
+ sal_Int32 mnNumberFormat;
+ sal_Int16 mnCellType;
+ bool mbIsNumeric;
+ bool mbIsEmpty;
+};
+
+// ============================================================================
+
+class ScXMLExternalRefCellTextContext : public SvXMLImportContext
+{
+public:
+ ScXMLExternalRefCellTextContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLExternalRefCellContext& rParent );
+
+ virtual ~ScXMLExternalRefCellTextContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void Characters(const ::rtl::OUString& rChar);
+
+ virtual void EndElement();
+
+private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalRefCellContext& mrParent;
+
+ ::rtl::OUStringBuffer maCellStrBuf;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx
new file mode 100644
index 000000000000..c350916ad898
--- /dev/null
+++ b/sc/source/filter/xml/xmlfilti.cxx
@@ -0,0 +1,787 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlfilti.hxx"
+#include "xmlimprt.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLFilterContext::ScXMLFilterContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext),
+ aFilterFields(),
+ bSkipDuplicates(false),
+ bCopyOutputData(false),
+ bUseRegularExpressions(false),
+ bConnectionOr(sal_True),
+ bNextConnectionOr(sal_True),
+ bConditionSourceRange(false)
+{
+ ScDocument* pDoc(GetScImport().GetDocument());
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart );
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ bConditionSourceRange = sal_True;
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
+ {
+ // not supported by StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
+ {
+ bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLFilterContext::~ScXMLFilterContext()
+{
+}
+
+SvXMLImportContext *ScXMLFilterContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_OR:
+ {
+ pContext = new ScXMLOrContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLFilterContext::EndElement()
+{
+ pDatabaseRangeContext->SetFilterUseRegularExpressions(bUseRegularExpressions);
+ if (bCopyOutputData)
+ {
+ pDatabaseRangeContext->SetFilterOutputPosition(aOutputPosition);
+ pDatabaseRangeContext->SetFilterCopyOutputData(bCopyOutputData);
+ }
+ else
+ pDatabaseRangeContext->SetFilterCopyOutputData(false);
+ pDatabaseRangeContext->SetFilterIsCaseSensitive(bIsCaseSensitive);
+ pDatabaseRangeContext->SetFilterSkipDuplicates(bSkipDuplicates);
+ pDatabaseRangeContext->SetFilterFields(aFilterFields);
+ if (bConditionSourceRange)
+ pDatabaseRangeContext->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress);
+}
+
+ScXMLAndContext::ScXMLAndContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(false);
+}
+
+ScXMLAndContext::~ScXMLAndContext()
+{
+}
+
+SvXMLImportContext *ScXMLAndContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_OR:
+ {
+ // not supported in StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLAndContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLOrContext::ScXMLOrContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(sal_True);
+}
+
+ScXMLOrContext::~ScXMLOrContext()
+{
+}
+
+SvXMLImportContext *ScXMLOrContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLOrContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLConditionContext::ScXMLConditionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext),
+ bIsCaseSensitive(false)
+{
+ sDataType = GetXMLToken(XML_TEXT);
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName );
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
+ {
+ nField = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_VALUE :
+ {
+ sConditionValue = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_OPERATOR :
+ {
+ sOperator = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLConditionContext::~ScXMLConditionContext()
+{
+}
+
+SvXMLImportContext *ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLConditionContext::getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const
+{
+ bUseRegularExpressions = false;
+ if (IsXMLToken(sTempOperator, XML_MATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
+ }
+ else if (IsXMLToken(sTempOperator, XML_NOMATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
+ }
+ else if (sTempOperator.compareToAscii("=") == 0)
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
+ else if (sTempOperator.compareToAscii("!=") == 0)
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_PERCENT;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_VALUES;
+ else if (IsXMLToken(sTempOperator, XML_EMPTY))
+ aFilterOperator = sheet::FilterOperator2::EMPTY;
+ else if (sTempOperator.compareToAscii(">") == 0)
+ aFilterOperator = sheet::FilterOperator2::GREATER;
+ else if (sTempOperator.compareToAscii(">=") == 0)
+ aFilterOperator = sheet::FilterOperator2::GREATER_EQUAL;
+ else if (sTempOperator.compareToAscii("<") == 0)
+ aFilterOperator = sheet::FilterOperator2::LESS;
+ else if (sTempOperator.compareToAscii("<=") == 0)
+ aFilterOperator = sheet::FilterOperator2::LESS_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_NOEMPTY))
+ aFilterOperator = sheet::FilterOperator2::NOT_EMPTY;
+ else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
+ aFilterOperator = sheet::FilterOperator2::TOP_PERCENT;
+ else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
+ aFilterOperator = sheet::FilterOperator2::TOP_VALUES;
+ else if (IsXMLToken(sTempOperator, XML_CONTAINS))
+ aFilterOperator = sheet::FilterOperator2::CONTAINS;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_CONTAIN))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_CONTAIN;
+ else if (IsXMLToken(sTempOperator, XML_BEGINS_WITH))
+ aFilterOperator = sheet::FilterOperator2::BEGINS_WITH;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_BEGIN_WITH))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH;
+ else if (IsXMLToken(sTempOperator, XML_ENDS_WITH))
+ aFilterOperator = sheet::FilterOperator2::ENDS_WITH;
+ else if (IsXMLToken(sTempOperator, XML_DOES_NOT_END_WITH))
+ aFilterOperator = sheet::FilterOperator2::DOES_NOT_END_WITH;
+}
+
+void ScXMLConditionContext::EndElement()
+{
+ sheet::TableFilterField2 aFilterField;
+ if (pFilterContext->GetConnection())
+ aFilterField.Connection = sheet::FilterConnection_OR;
+ else
+ aFilterField.Connection = sheet::FilterConnection_AND;
+ pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
+ sal_Bool bUseRegularExpressions;
+ getOperatorXML(sOperator, aFilterField.Operator, bUseRegularExpressions);
+ pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
+ aFilterField.Field = nField;
+ if (IsXMLToken(sDataType, XML_NUMBER))
+ {
+ aFilterField.NumericValue = sConditionValue.toDouble();
+ aFilterField.IsNumeric = sal_True;
+ }
+ else
+ {
+ aFilterField.StringValue = sConditionValue;
+ aFilterField.IsNumeric = false;
+ }
+ pFilterContext->AddFilterField(aFilterField);
+}
+
+//==========================================================================
+
+ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTableContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDataPilotTable(pTempDataPilotTableContext),
+ aFilterFields(),
+ nFilterFieldCount(0),
+ bSkipDuplicates(false),
+ bCopyOutputData(false),
+ bUseRegularExpressions(false),
+ bConnectionOr(sal_True),
+ bNextConnectionOr(sal_True),
+ bConditionSourceRange(false)
+{
+ ScDocument* pDoc(GetScImport().GetDocument());
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ aOutputPosition = aScRange.aStart;
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS :
+ {
+ sal_Int32 nOffset(0);
+ if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ bConditionSourceRange = sal_True;
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_CONDITION_SOURCE :
+ {
+ // not supported by StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES :
+ {
+ bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPFilterContext::~ScXMLDPFilterContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPFilterContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_OR:
+ {
+ pContext = new ScXMLDPOrContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPFilterContext::EndElement()
+{
+ aFilterFields.bRegExp = bUseRegularExpressions;
+ aFilterFields.bCaseSens = bIsCaseSensitive;
+ aFilterFields.bDuplicate = !bSkipDuplicates;
+// pDataPilotTable->SetFilterUseRegularExpressions(bUseRegularExpressions);
+ if (bCopyOutputData)
+ {
+ pDataPilotTable->SetFilterOutputPosition(aOutputPosition);
+ pDataPilotTable->SetFilterCopyOutputData(bCopyOutputData);
+ }
+ else
+ pDataPilotTable->SetFilterCopyOutputData(false);
+// pDataPilotTable->SetFilterIsCaseSensitive(bIsCaseSensitive);
+// pDataPilotTable->SetFilterSkipDuplicates(bSkipDuplicates);
+ pDataPilotTable->SetSourceQueryParam(aFilterFields);
+ if (bConditionSourceRange)
+ pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress);
+}
+
+void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField)
+{
+ aFilterFields.Resize(nFilterFieldCount + 1);
+ ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount));
+ rEntry = aFilterField;
+ rEntry.bDoQuery = sal_True;
+ ++nFilterFieldCount;
+}
+
+ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ pFilterContext = pTempFilterContext;
+ pFilterContext->OpenConnection(false);
+}
+
+ScXMLDPAndContext::~ScXMLDPAndContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPAndContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_OR:
+ {
+ // not supported in StarOffice
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPAndContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext)
+{
+ pFilterContext->OpenConnection(sal_True);
+}
+
+ScXMLDPOrContext::~ScXMLDPOrContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPOrContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_FILTER_AND:
+ {
+ pContext = new ScXMLDPAndContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ case XML_TOK_FILTER_CONDITION:
+ {
+ pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix,
+ rLName, xAttrList, pFilterContext);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLDPOrContext::EndElement()
+{
+ pFilterContext->CloseConnection();
+}
+
+ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pFilterContext(pTempFilterContext),
+ sDataType(GetXMLToken(XML_TEXT)),
+ bIsCaseSensitive(false)
+{
+
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_CONDITION_ATTR_FIELD_NUMBER :
+ {
+ nField = sValue.toInt32();
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_VALUE :
+ {
+ sConditionValue = sValue;
+ }
+ break;
+ case XML_TOK_CONDITION_ATTR_OPERATOR :
+ {
+ sOperator = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLDPConditionContext::~ScXMLDPConditionContext()
+{
+}
+
+SvXMLImportContext *ScXMLDPConditionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLDPConditionContext::getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions,
+ double& dVal) const
+{
+ bUseRegularExpressions = false;
+ if (IsXMLToken(sTempOperator, XML_MATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = SC_EQUAL;
+ }
+ else if (IsXMLToken(sTempOperator, XML_NOMATCH))
+ {
+ bUseRegularExpressions = sal_True;
+ aFilterOperator = SC_NOT_EQUAL;
+ }
+ else if (sTempOperator.compareToAscii("=") == 0)
+ aFilterOperator = SC_EQUAL;
+ else if (sTempOperator.compareToAscii("!=") == 0)
+ aFilterOperator = SC_NOT_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
+ aFilterOperator = SC_BOTPERC;
+ else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
+ aFilterOperator = SC_BOTVAL;
+ else if (IsXMLToken(sTempOperator, XML_EMPTY))
+ dVal = SC_EMPTYFIELDS;
+ else if (sTempOperator.compareToAscii(">") == 0)
+ aFilterOperator = SC_GREATER;
+ else if (sTempOperator.compareToAscii(">=") == 0)
+ aFilterOperator = SC_GREATER_EQUAL;
+ else if (sTempOperator.compareToAscii("<") == 0)
+ aFilterOperator = SC_LESS;
+ else if (sTempOperator.compareToAscii("<=") == 0)
+ aFilterOperator = SC_LESS_EQUAL;
+ else if (IsXMLToken(sTempOperator, XML_NOEMPTY))
+ dVal = SC_NONEMPTYFIELDS;
+ else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
+ aFilterOperator = SC_TOPPERC;
+ else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
+ aFilterOperator = SC_TOPVAL;
+}
+
+void ScXMLDPConditionContext::EndElement()
+{
+ ScQueryEntry aFilterField;
+ if (pFilterContext->GetConnection())
+ aFilterField.eConnect = SC_OR;
+ else
+ aFilterField.eConnect = SC_AND;
+ pFilterContext->SetIsCaseSensitive(bIsCaseSensitive);
+ sal_Bool bUseRegularExpressions;
+ double dVal(0.0);
+ getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions, dVal);
+ pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
+ aFilterField.nField = nField;
+ if (IsXMLToken(sDataType, XML_NUMBER))
+ {
+ aFilterField.nVal = sConditionValue.toDouble();
+ *aFilterField.pStr = sConditionValue;
+ aFilterField.bQueryByString = false;
+ if (dVal != 0.0)
+ {
+ aFilterField.nVal = dVal;
+ *aFilterField.pStr = EMPTY_STRING;
+ }
+ }
+ else
+ {
+ aFilterField.pStr = new String(sConditionValue);
+ aFilterField.bQueryByString = sal_True;
+ aFilterField.nVal = 0;
+ }
+ pFilterContext->AddFilterField(aFilterField);
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlfilti.hxx b/sc/source/filter/xml/xmlfilti.hxx
new file mode 100644
index 000000000000..4d0495ba341f
--- /dev/null
+++ b/sc/source/filter/xml/xmlfilti.hxx
@@ -0,0 +1,313 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLFILTI_HXX
+#define SC_XMLFILTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/sheet/FilterOperator.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <tools/stack.hxx>
+
+#include "xmldrani.hxx"
+#include "xmldpimp.hxx"
+
+class ScXMLImport;
+
+class ScXMLFilterContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields;
+ com::sun::star::table::CellAddress aOutputPosition;
+ com::sun::star::table::CellRangeAddress aConditionSourceRangeAddress;
+ sal_Int16 nUserListIndex;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bCopyOutputData;
+ sal_Bool bUseRegularExpressions;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+ sal_Bool bConnectionOr;
+ sal_Bool bNextConnectionOr;
+ sal_Bool bConditionSourceRange;
+ Stack aConnectionOrStack;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLFilterContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLFilterContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; }
+ void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;}
+ void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr;
+ bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp;
+ aConnectionOrStack.Push(pTemp);}
+ void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;}
+ sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; }
+ void AddFilterField(const com::sun::star::sheet::TableFilterField2 aFilterField) { aFilterFields.realloc(aFilterFields.getLength() + 1);
+ aFilterFields[aFilterFields.getLength() - 1] = aFilterField; }
+};
+
+class ScXMLAndContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLAndContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLAndContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLOrContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLOrContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLOrContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLConditionContext : public SvXMLImportContext
+{
+ ScXMLFilterContext* pFilterContext;
+
+ rtl::OUString sDataType;
+ rtl::OUString sConditionValue;
+ rtl::OUString sOperator;
+ sal_Int32 nField;
+ sal_Bool bIsCaseSensitive;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLConditionContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLConditionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const;
+ virtual void EndElement();
+};
+
+// Datapilot (Core)
+
+class ScXMLDPFilterContext : public SvXMLImportContext
+{
+ ScXMLDataPilotTableContext* pDataPilotTable;
+
+ ScQueryParam aFilterFields;
+ ScAddress aOutputPosition;
+ ScRange aConditionSourceRangeAddress;
+ sal_uInt8 nFilterFieldCount;
+ sal_Int16 nUserListIndex;
+ sal_Bool bSkipDuplicates;
+ sal_Bool bCopyOutputData;
+ sal_Bool bUseRegularExpressions;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+ sal_Bool bConnectionOr;
+ sal_Bool bNextConnectionOr;
+ sal_Bool bConditionSourceRange;
+ Stack aConnectionOrStack;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPFilterContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTempDataPilotTableContext);
+
+ virtual ~ScXMLDPFilterContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; }
+ void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;}
+ void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr;
+ bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp;
+ aConnectionOrStack.Push(pTemp);}
+ void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;}
+ sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; }
+ void AddFilterField (const ScQueryEntry& aFilterField);
+};
+
+class ScXMLDPAndContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPAndContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPAndContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPOrContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPOrContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPOrContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLDPConditionContext : public SvXMLImportContext
+{
+ ScXMLDPFilterContext* pFilterContext;
+
+ rtl::OUString sDataType;
+ rtl::OUString sConditionValue;
+ rtl::OUString sOperator;
+ sal_Int32 nField;
+ sal_Bool bIsCaseSensitive;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDPConditionContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDPFilterContext* pTempFilterContext);
+
+ virtual ~ScXMLDPConditionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ void getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions,
+ double& dVal) const;
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx
new file mode 100644
index 000000000000..388952a75701
--- /dev/null
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#ifdef PRECOMPILED
+#include "filt_pch.hxx"
+#endif
+
+
+#include "scitems.hxx"
+
+#include <editeng/eeitem.hxx>
+
+
+#include <xmloff/XMLFontAutoStylePool.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editeng.hxx>
+#include "document.hxx"
+#include "docpool.hxx"
+#include "xmlexprt.hxx"
+#include "stlpool.hxx"
+#include "attrib.hxx"
+
+class ScXMLFontAutoStylePool_Impl: public XMLFontAutoStylePool
+{
+ void AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults);
+ public:
+
+ ScXMLFontAutoStylePool_Impl( ScXMLExport& rExport );
+
+};
+
+void ScXMLFontAutoStylePool_Impl::AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults)
+{
+ const SfxPoolItem* pItem;
+ for( sal_uInt16 i=0; i < nIdCount; ++i )
+ {
+ sal_uInt16 nWhichId(pWhichIds[i]);
+ if (bExportDefaults && (0 != (pItem = &pItemPool->GetDefaultItem(nWhichId))))
+ {
+ const SvxFontItem *pFont((const SvxFontItem *)pItem);
+ Add( pFont->GetFamilyName(), pFont->GetStyleName(),
+ sal::static_int_cast<sal_Int16>(pFont->GetFamily()),
+ sal::static_int_cast<sal_Int16>(pFont->GetPitch()),
+ pFont->GetCharSet() );
+ }
+ sal_uInt32 nItems(pItemPool->GetItemCount2( nWhichId ));
+ for( sal_uInt32 j = 0; j < nItems; ++j )
+ {
+ if( 0 != (pItem = pItemPool->GetItem2( nWhichId, j ) ) )
+ {
+ const SvxFontItem *pFont((const SvxFontItem *)pItem);
+ Add( pFont->GetFamilyName(), pFont->GetStyleName(),
+ sal::static_int_cast<sal_Int16>(pFont->GetFamily()),
+ sal::static_int_cast<sal_Int16>(pFont->GetPitch()),
+ pFont->GetCharSet() );
+ }
+ }
+ }
+}
+
+ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(
+ ScXMLExport& rExportP ) :
+ XMLFontAutoStylePool( rExportP )
+{
+ sal_uInt16 aWhichIds[3] = { ATTR_FONT, ATTR_CJK_FONT,
+ ATTR_CTL_FONT };
+ sal_uInt16 aEditWhichIds[3] = { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
+ EE_CHAR_FONTINFO_CTL };
+ sal_uInt16 aPageWhichIds[4] = { ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERLEFT,
+ ATTR_PAGE_HEADERRIGHT, ATTR_PAGE_FOOTERRIGHT };
+
+ const SfxItemPool* pItemPool(rExportP.GetDocument() ? rExportP.GetDocument()->GetPool() : NULL);
+ AddFontItems(aWhichIds, 3, pItemPool, sal_True);
+ const SfxItemPool* pEditPool(rExportP.GetDocument()->GetEditPool());
+ AddFontItems(aEditWhichIds, 3, pEditPool, false);
+
+ SfxStyleSheetIterator* pItr(rExportP.GetDocument() ? rExportP.GetDocument()->GetStyleSheetPool()->CreateIterator(SFX_STYLE_FAMILY_PAGE, 0xFFFF) : NULL);
+ if(pItr)
+ {
+ SfxStyleSheetBase* pStyle(pItr->First());
+ SfxItemPool* pPageEditPool(EditEngine::CreatePool());
+ EditEngine aEditEngine(pPageEditPool);
+ while (pStyle)
+ {
+ const SfxItemPool& rPagePool(pStyle->GetPool().GetPool());
+ for (sal_uInt8 j = 0; j < 4; ++j)
+ {
+ sal_uInt16 nPageWhichId(aPageWhichIds[j]);
+ sal_uInt32 nPageHFItems(rPagePool.GetItemCount2(nPageWhichId));
+ const ScPageHFItem* pPageItem;
+ for (sal_uInt32 k = 0; k < nPageHFItems; ++k)
+ {
+ if (0 != (pPageItem = static_cast<const ScPageHFItem*>(rPagePool.GetItem2(nPageWhichId, k))))
+ {
+ const EditTextObject* pLeftArea(pPageItem->GetLeftArea());
+ if (pLeftArea)
+ {
+ aEditEngine.SetText(*pLeftArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, false);
+ }
+ const EditTextObject* pCenterArea(pPageItem->GetCenterArea());
+ if (pCenterArea)
+ {
+ aEditEngine.SetText(*pCenterArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, false);
+ }
+ const EditTextObject* pRightArea(pPageItem->GetRightArea());
+ if (pRightArea)
+ {
+ aEditEngine.SetText(*pRightArea);
+ AddFontItems(aEditWhichIds, 3, pPageEditPool, false);
+ }
+ }
+ }
+ }
+ pStyle = pItr->Next();
+ }
+ }
+}
+
+
+XMLFontAutoStylePool* ScXMLExport::CreateFontAutoStylePool()
+{
+ return new ScXMLFontAutoStylePool_Impl( *this );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
new file mode 100644
index 000000000000..c048813a1f66
--- /dev/null
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -0,0 +1,3187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svl/zforlist.hxx>
+#include <sal/macros.h>
+
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/i18nmap.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlmetai.hxx>
+#include <sfx2/objsh.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/xmlscripti.hxx>
+#include <xmloff/XMLFontStylesContext.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlerror.hxx>
+
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "nameuno.hxx"
+#include "xmlbodyi.hxx"
+#include "xmlstyli.hxx"
+#include "ViewSettingsSequenceDefines.hxx"
+
+#include "patattr.hxx"
+
+#include "XMLConverter.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "XMLChangeTrackingImportHelper.hxx"
+#include "chgviset.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "unonames.hxx"
+#include "rangeutl.hxx"
+#include "postit.hxx"
+#include "formulaparserpool.hxx"
+#include <comphelper/extract.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/CellInsertMode.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <memory>
+
+#define SC_LOCALE "Locale"
+#define SC_STANDARDFORMAT "StandardFormat"
+#define SC_CURRENCYSYMBOL "CurrencySymbol"
+#define SC_NAMEDRANGES "NamedRanges"
+#define SC_REPEAT_COLUMN "repeat-column"
+#define SC_REPEAT_ROW "repeat-row"
+#define SC_FILTER "filter"
+#define SC_PRINT_RANGE "print-range"
+
+using namespace com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::formula;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+OUString SAL_CALL ScXMLImport_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_ALL);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_ALL );
+}
+
+OUString SAL_CALL ScXMLImport_Meta_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Meta_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Meta_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Meta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_META );
+}
+
+OUString SAL_CALL ScXMLImport_Styles_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Styles_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Styles_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Styles_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLImport_Content_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Content_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Content_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Content_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META|IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_SETTINGS|IMPORT_FONTDECLS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS);
+}
+
+OUString SAL_CALL ScXMLImport_Settings_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsImporter" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Settings_getSupportedServiceNames() throw()
+{
+ const rtl::OUString aServiceName( ScXMLImport_Settings_getImplementationName() );
+ return uno::Sequence< rtl::OUString > ( &aServiceName, 1 );
+}
+
+uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Settings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ // #110680#
+ // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_SETTINGS);
+ return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_SETTINGS );
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowCellAttrTokenMap()
+{
+ static SvXMLTokenMapEntry aTableRowCellAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED },
+ { XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE },
+ { XML_NAMESPACE_OFFICE, XML_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_DATE_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_TIME_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_STRING_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE },
+ { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE },
+ { XML_NAMESPACE_TABLE, XML_FORMULA, XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA },
+ { XML_NAMESPACE_OFFICE, XML_CURRENCY, XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY },
+ XML_TOKEN_MAP_END
+ };
+
+ if ( !pTableRowCellAttrTokenMap )
+ pTableRowCellAttrTokenMap = new SvXMLTokenMap( aTableRowCellAttrTokenMap );
+ return *pTableRowCellAttrTokenMap;
+}
+
+//----------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// NB: virtually inherit so we can multiply inherit properly
+// in ScXMLFlatDocContext_Impl
+class ScXMLDocContext_Impl : public virtual SvXMLImportContext
+{
+protected:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLDocContext_Impl( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList );
+ virtual ~ScXMLDocContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList );
+};
+
+ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */ ) :
+SvXMLImportContext( rImport, nPrfx, rLName )
+{
+
+}
+
+ScXMLDocContext_Impl::~ScXMLDocContext_Impl()
+{
+}
+
+// context for flat file xml format
+class ScXMLFlatDocContext_Impl
+ : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
+{
+public:
+ ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ sal_uInt16 i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder);
+
+ virtual ~ScXMLFlatDocContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList);
+};
+
+ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ sal_uInt16 i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder) :
+SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
+ScXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName, i_xAttrList),
+SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
+ i_xDocProps, i_xDocBuilder)
+{
+}
+
+ScXMLFlatDocContext_Impl::~ScXMLFlatDocContext_Impl() { }
+
+
+SvXMLImportContext *ScXMLFlatDocContext_Impl::CreateChildContext(
+ sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
+{
+ // behave like meta base class iff we encounter office:meta
+ const SvXMLTokenMap& rTokenMap = GetScImport().GetDocElemTokenMap();
+ if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) {
+ return SvXMLMetaDocumentContext::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ } else {
+ return ScXMLDocContext_Impl::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ }
+}
+
+class ScXMLBodyContext_Impl : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const
+ { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+ virtual ~ScXMLBodyContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+};
+
+ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & /* xAttrList */ ) :
+SvXMLImportContext( rImport, nPrfx, rLName )
+{
+}
+
+ScXMLBodyContext_Impl::~ScXMLBodyContext_Impl()
+{
+}
+
+SvXMLImportContext *ScXMLBodyContext_Impl::CreateChildContext(
+ sal_uInt16 /* nPrefix */,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ return GetScImport().CreateBodyContext( rLocalName, xAttrList );
+}
+
+SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix,
+ const rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetDocElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ {
+ case XML_TOK_DOC_FONTDECLS:
+ if (GetScImport().getImportFlags() & IMPORT_FONTDECLS)
+ pContext = GetScImport().CreateFontDeclsContext(nPrefix, rLocalName, xAttrList);
+ break;
+ case XML_TOK_DOC_STYLES:
+ if (GetScImport().getImportFlags() & IMPORT_STYLES)
+ pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, false);
+ break;
+ case XML_TOK_DOC_AUTOSTYLES:
+ if (GetScImport().getImportFlags() & IMPORT_AUTOSTYLES)
+ pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, sal_True);
+ break;
+ case XML_TOK_DOC_MASTERSTYLES:
+ if (GetScImport().getImportFlags() & IMPORT_MASTERSTYLES)
+ pContext = new ScXMLMasterStylesContext( GetImport(), nPrefix, rLocalName,
+ xAttrList );
+ break;
+ case XML_TOK_DOC_META:
+ DBG_WARNING("XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
+ break;
+ case XML_TOK_DOC_SCRIPTS:
+ if (GetScImport().getImportFlags() & IMPORT_SCRIPTS)
+ pContext = GetScImport().CreateScriptContext( rLocalName );
+ break;
+ case XML_TOK_DOC_BODY:
+ if (GetScImport().getImportFlags() & IMPORT_CONTENT)
+ pContext = new ScXMLBodyContext_Impl( GetScImport(), nPrefix,
+ rLocalName, xAttrList );
+ break;
+ case XML_TOK_DOC_SETTINGS:
+ if (GetScImport().getImportFlags() & IMPORT_SETTINGS)
+ pContext = new XMLDocumentSettingsContext(GetScImport(), nPrefix, rLocalName, xAttrList );
+ break;
+ }
+
+ if(!pContext)
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDocElemTokenMap()
+{
+ if( !pDocElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDocTokenMap[] =
+ {
+ { XML_NAMESPACE_OFFICE, XML_FONT_FACE_DECLS, XML_TOK_DOC_FONTDECLS },
+ { XML_NAMESPACE_OFFICE, XML_STYLES, XML_TOK_DOC_STYLES },
+ { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES },
+ { XML_NAMESPACE_OFFICE, XML_MASTER_STYLES, XML_TOK_DOC_MASTERSTYLES },
+ { XML_NAMESPACE_OFFICE, XML_META, XML_TOK_DOC_META },
+ { XML_NAMESPACE_OFFICE, XML_SCRIPTS, XML_TOK_DOC_SCRIPTS },
+ { XML_NAMESPACE_OFFICE, XML_BODY, XML_TOK_DOC_BODY },
+ { XML_NAMESPACE_OFFICE, XML_SETTINGS, XML_TOK_DOC_SETTINGS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDocElemTokenMap = new SvXMLTokenMap( aDocTokenMap );
+
+ } // if( !pDocElemTokenMap )
+
+ return *pDocElemTokenMap;
+}
+
+
+const SvXMLTokenMap& ScXMLImport::GetBodyElemTokenMap()
+{
+ if( !pBodyElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aBodyTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, XML_TOK_BODY_TRACKED_CHANGES },
+ { XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, XML_TOK_BODY_CALCULATION_SETTINGS },
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, XML_TOK_BODY_CONTENT_VALIDATIONS },
+ { XML_NAMESPACE_TABLE, XML_LABEL_RANGES, XML_TOK_BODY_LABEL_RANGES },
+ { XML_NAMESPACE_TABLE, XML_TABLE, XML_TOK_BODY_TABLE },
+ { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, XML_TOK_BODY_NAMED_EXPRESSIONS },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, XML_TOK_BODY_DATABASE_RANGES },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_BODY_DATABASE_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, XML_TOK_BODY_DATA_PILOT_TABLES },
+ { XML_NAMESPACE_TABLE, XML_CONSOLIDATION, XML_TOK_BODY_CONSOLIDATION },
+ { XML_NAMESPACE_TABLE, XML_DDE_LINKS, XML_TOK_BODY_DDE_LINKS },
+ XML_TOKEN_MAP_END
+ };
+
+ pBodyElemTokenMap = new SvXMLTokenMap( aBodyTokenMap );
+ } // if( !pBodyElemTokenMap )
+
+ return *pBodyElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationsElemTokenMap()
+{
+ if( !pContentValidationsElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TOK_CONTENT_VALIDATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationsElemTokenMap = new SvXMLTokenMap( aContentValidationsElemTokenMap );
+ } // if( !pContentValidationsElemTokenMap )
+
+ return *pContentValidationsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationElemTokenMap()
+{
+ if( !pContentValidationElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE },
+ { XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE },
+ { XML_NAMESPACE_TABLE, XML_ERROR_MACRO, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO },
+ { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationElemTokenMap = new SvXMLTokenMap( aContentValidationElemTokenMap );
+ } // if( !pContentValidationElemTokenMap )
+
+ return *pContentValidationElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationAttrTokenMap()
+{
+ if( !pContentValidationAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_CONTENT_VALIDATION_NAME },
+ { XML_NAMESPACE_TABLE, XML_CONDITION, XML_TOK_CONTENT_VALIDATION_CONDITION },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationAttrTokenMap = new SvXMLTokenMap( aContentValidationAttrTokenMap );
+ } // if( !pContentValidationAttrTokenMap )
+
+ return *pContentValidationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationMessageElemTokenMap()
+{
+ if( !pContentValidationMessageElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationMessageElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TEXT, XML_P, XML_TOK_P },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationMessageElemTokenMap = new SvXMLTokenMap( aContentValidationMessageElemTokenMap );
+ } // if( !pContentValidationMessageElemTokenMap )
+
+ return *pContentValidationMessageElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationHelpMessageAttrTokenMap()
+{
+ if( !pContentValidationHelpMessageAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationHelpMessageAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_HELP_MESSAGE_ATTR_TITLE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_HELP_MESSAGE_ATTR_DISPLAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationHelpMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationHelpMessageAttrTokenMap );
+ } // if( !pContentValidationHelpMessageAttrTokenMap )
+
+ return *pContentValidationHelpMessageAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMessageAttrTokenMap()
+{
+ if( !pContentValidationErrorMessageAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationErrorMessageAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_ERROR_MESSAGE_ATTR_TITLE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationErrorMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMessageAttrTokenMap );
+ } // if( !pContentValidationErrorMessageAttrTokenMap )
+
+ return *pContentValidationErrorMessageAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMacroAttrTokenMap()
+{
+ if( !pContentValidationErrorMacroAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aContentValidationErrorMacroAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_ERROR_MACRO_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TOK_ERROR_MACRO_ATTR_EXECUTE },
+ XML_TOKEN_MAP_END
+ };
+
+ pContentValidationErrorMacroAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMacroAttrTokenMap );
+ } // if( !pContentValidationErrorMacroAttrTokenMap )
+
+ return *pContentValidationErrorMacroAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetLabelRangesElemTokenMap()
+{
+ if( !pLabelRangesElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aLabelRangesElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_LABEL_RANGE, XML_TOK_LABEL_RANGE_ELEM },
+ XML_TOKEN_MAP_END
+ };
+
+ pLabelRangesElemTokenMap = new SvXMLTokenMap( aLabelRangesElemTokenMap );
+ } // if( !pLabelRangesElemTokenMap )
+
+ return *pLabelRangesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetLabelRangeAttrTokenMap()
+{
+ if( !pLabelRangeAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aLabelRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_LABEL_RANGE_ATTR_ORIENTATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pLabelRangeAttrTokenMap = new SvXMLTokenMap( aLabelRangeAttrTokenMap );
+ } // if( !pLabelRangeAttrTokenMap )
+
+ return *pLabelRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap()
+{
+ if( !pTableElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, XML_TOK_TABLE_NAMED_EXPRESSIONS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COL_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_HEADER_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COL },
+ { XML_NAMESPACE_TABLE, XML_TABLE_PROTECTION, XML_TOK_TABLE_PROTECTION },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROW_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_HEADER_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROW },
+ { XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, XML_TOK_TABLE_SOURCE },
+ { XML_NAMESPACE_TABLE, XML_SCENARIO, XML_TOK_TABLE_SCENARIO },
+ { XML_NAMESPACE_TABLE, XML_SHAPES, XML_TOK_TABLE_SHAPES },
+ { XML_NAMESPACE_OFFICE, XML_FORMS, XML_TOK_TABLE_FORMS },
+ { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS },
+ { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableElemTokenMap = new SvXMLTokenMap( aTableTokenMap );
+ } // if( !pTableElemTokenMap )
+
+ return *pTableElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableProtectionAttrTokenMap()
+{
+ if (!pTableProtectionElemTokenMap)
+ {
+ static SvXMLTokenMapEntry aTableProtectionTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SELECT_PROTECTED_CELLS, XML_TOK_TABLE_SELECT_PROTECTED_CELLS },
+ { XML_NAMESPACE_TABLE, XML_SELECT_UNPROTECTED_CELLS, XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS },
+ XML_TOKEN_MAP_END
+ };
+ pTableProtectionElemTokenMap = new SvXMLTokenMap(aTableProtectionTokenMap);
+ }
+
+ return *pTableProtectionElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowsElemTokenMap()
+{
+ if( !pTableRowsElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableRowsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROWS_ROW_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_ROWS_HEADER_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS_ROWS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROWS_ROW },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowsElemTokenMap = new SvXMLTokenMap( aTableRowsElemTokenMap );
+ } // if( !pTableRowsElemTokenMap )
+
+ return *pTableRowsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableColsElemTokenMap()
+{
+ if( !pTableColsElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableColsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COLS_COL_GROUP },
+ { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_COLS_HEADER_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS_COLS },
+ { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COLS_COL },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableColsElemTokenMap = new SvXMLTokenMap( aTableColsElemTokenMap );
+ } // if( !pTableColsElemTokenMap )
+
+ return *pTableColsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableAttrTokenMap()
+{
+ if( !pTableAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTED },
+ { XML_NAMESPACE_TABLE, XML_PRINT_RANGES, XML_TOK_TABLE_PRINT_RANGES },
+ { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, XML_TOK_TABLE_PASSWORD },
+ { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM, XML_TOK_TABLE_PASSHASH },
+ { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2, XML_TOK_TABLE_PASSHASH_2 },
+ { XML_NAMESPACE_TABLE, XML_PRINT, XML_TOK_TABLE_PRINT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableAttrTokenMap = new SvXMLTokenMap( aTableAttrTokenMap );
+ } // if( !pTableAttrTokenMap )
+
+ return *pTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableScenarioAttrTokenMap()
+{
+ if( !pTableScenarioAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableScenarioAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER },
+ { XML_NAMESPACE_TABLE, XML_BORDER_COLOR, XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR },
+ { XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK },
+ { XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES },
+ { XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS },
+ { XML_NAMESPACE_TABLE, XML_IS_ACTIVE, XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE },
+ { XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES },
+ { XML_NAMESPACE_TABLE, XML_COMMENT, XML_TOK_TABLE_SCENARIO_ATTR_COMMENT },
+ { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableScenarioAttrTokenMap = new SvXMLTokenMap( aTableScenarioAttrTokenMap );
+ } // if( !pTableScenarioAttrTokenMap )
+
+ return *pTableScenarioAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableColAttrTokenMap()
+{
+ if( !pTableColAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableColAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_COL_ATTR_REPEATED },
+ { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_COL_ATTR_VISIBILITY },
+ { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableColAttrTokenMap = new SvXMLTokenMap( aTableColAttrTokenMap );
+ } // if( !pTableColAttrTokenMap )
+
+ return *pTableColAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowElemTokenMap()
+{
+ if( !pTableRowElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableRowTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TABLE_CELL, XML_TOK_TABLE_ROW_CELL },
+ { XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, XML_TOK_TABLE_ROW_COVERED_CELL },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowElemTokenMap = new SvXMLTokenMap( aTableRowTokenMap );
+ } // if( !pTableRowElemTokenMap )
+
+ return *pTableRowElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowAttrTokenMap()
+{
+ if( !pTableRowAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableRowAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_STYLE_NAME },
+ { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_ROW_ATTR_VISIBILITY },
+ { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, XML_TOK_TABLE_ROW_ATTR_REPEATED },
+ { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME },
+ // { XML_NAMESPACE_TABLE, XML_USE_OPTIMAL_HEIGHT, XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowAttrTokenMap = new SvXMLTokenMap( aTableRowAttrTokenMap );
+ } // if( !pTableRowAttrTokenMap )
+
+ return *pTableRowAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableRowCellElemTokenMap()
+{
+ if( !pTableRowCellElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableRowCellTokenMap[] =
+ {
+ { XML_NAMESPACE_TEXT, XML_P, XML_TOK_TABLE_ROW_CELL_P },
+ { XML_NAMESPACE_TABLE, XML_SUB_TABLE, XML_TOK_TABLE_ROW_CELL_TABLE },
+ { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_TABLE_ROW_CELL_ANNOTATION },
+ { XML_NAMESPACE_TABLE, XML_DETECTIVE, XML_TOK_TABLE_ROW_CELL_DETECTIVE },
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableRowCellElemTokenMap = new SvXMLTokenMap( aTableRowCellTokenMap );
+ } // if( !pTableRowCellElemTokenMap )
+
+ return *pTableRowCellElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableAnnotationAttrTokenMap()
+{
+ if( !pTableAnnotationAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableAnnotationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_OFFICE, XML_AUTHOR, XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR },
+ { XML_NAMESPACE_OFFICE, XML_CREATE_DATE, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE },
+ { XML_NAMESPACE_OFFICE, XML_CREATE_DATE_STRING, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING },
+ { XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY },
+ { XML_NAMESPACE_SVG, XML_X, XML_TOK_TABLE_ANNOTATION_ATTR_X },
+ { XML_NAMESPACE_SVG, XML_Y, XML_TOK_TABLE_ANNOTATION_ATTR_Y },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableAnnotationAttrTokenMap = new SvXMLTokenMap( aTableAnnotationAttrTokenMap );
+ } // if( !pTableAnnotationAttrTokenMap )
+
+ return *pTableAnnotationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveElemTokenMap()
+{
+ if( !pDetectiveElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDetectiveElemTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED },
+ { XML_NAMESPACE_TABLE, XML_OPERATION, XML_TOK_DETECTIVE_ELEM_OPERATION },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveElemTokenMap = new SvXMLTokenMap( aDetectiveElemTokenMap );
+ } // if( !pDetectiveElemTokenMap )
+
+ return *pDetectiveElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveHighlightedAttrTokenMap()
+{
+ if( !pDetectiveHighlightedAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDetectiveHighlightedAttrTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DIRECTION, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION },
+ { XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR },
+ { XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveHighlightedAttrTokenMap = new SvXMLTokenMap( aDetectiveHighlightedAttrTokenMap );
+ } // if( !pDetectiveHighlightedAttrTokenMap )
+
+ return *pDetectiveHighlightedAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDetectiveOperationAttrTokenMap()
+{
+ if( !pDetectiveOperationAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDetectiveOperationAttrTokenMap[]=
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DETECTIVE_OPERATION_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_INDEX, XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX },
+ XML_TOKEN_MAP_END
+ };
+
+ pDetectiveOperationAttrTokenMap = new SvXMLTokenMap( aDetectiveOperationAttrTokenMap );
+ } // if( !pDetectiveOperationAttrTokenMap )
+
+ return *pDetectiveOperationAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetTableCellRangeSourceAttrTokenMap()
+{
+ if( !pTableCellRangeSourceAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aTableCellRangeSourceAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_FILTER_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME },
+ { XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS },
+ { XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN },
+ { XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW },
+ { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pTableCellRangeSourceAttrTokenMap = new SvXMLTokenMap( aTableCellRangeSourceAttrTokenMap );
+ } // if( !pTableCellRangeSourceAttrTokenMap )
+
+ return *pTableCellRangeSourceAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedExpressionsElemTokenMap()
+{
+ if( !pNamedExpressionsElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aNamedExpressionsTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAMED_RANGE, XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE },
+ { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedExpressionsElemTokenMap = new SvXMLTokenMap( aNamedExpressionsTokenMap );
+ } // if( !pNamedExpressionsElemTokenMap )
+
+ return *pNamedExpressionsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedRangeAttrTokenMap()
+{
+ if( !pNamedRangeAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aNamedRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_RANGE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedRangeAttrTokenMap = new SvXMLTokenMap( aNamedRangeAttrTokenMap );
+ } // if( !pNamedRangeAttrTokenMap )
+
+ return *pNamedRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetNamedExpressionAttrTokenMap()
+{
+ if( !pNamedExpressionAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aNamedExpressionAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_EXPRESSION_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_EXPRESSION, XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION },
+ XML_TOKEN_MAP_END
+ };
+
+ pNamedExpressionAttrTokenMap = new SvXMLTokenMap( aNamedExpressionAttrTokenMap );
+ } // if( !pNamedExpressionAttrTokenMap )
+
+ return *pNamedExpressionAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangesElemTokenMap()
+{
+ if( !pDatabaseRangesElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangesTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_DATABASE_RANGE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangesElemTokenMap = new SvXMLTokenMap( aDatabaseRangesTokenMap );
+ } // if( !pDatabaseRangesElemTokenMap )
+
+ return *pDatabaseRangesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeElemTokenMap()
+{
+ if( !pDatabaseRangeElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATABASE_RANGE_SOURCE_SQL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATABASE_RANGE_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATABASE_RANGE_SOURCE_QUERY },
+ { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_FILTER },
+ { XML_NAMESPACE_TABLE, XML_SORT, XML_TOK_SORT },
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeElemTokenMap = new SvXMLTokenMap( aDatabaseRangeTokenMap );
+ } // if( !pDatabaseRangeElemTokenMap )
+
+ return *pDatabaseRangeElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeAttrTokenMap()
+{
+ if( !pDatabaseRangeAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATABASE_RANGE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION },
+ { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES },
+ { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE },
+ { XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeAttrTokenMap );
+ } // if( !pDatabaseRangeAttrTokenMap )
+
+ return *pDatabaseRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceSQLAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceSQLAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeSourceSQLAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_SQL_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE},
+ { XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT },
+ { XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceSQLAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceSQLAttrTokenMap );
+ } // if( !pDatabaseRangeSourceSQLAttrTokenMap )
+
+ return *pDatabaseRangeSourceSQLAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceTableAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceTableAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeSourceTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_TABLE_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE },
+ { XML_NAMESPACE_TABLE, XML_TABLE_NAME, XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceTableAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceTableAttrTokenMap );
+ } // if( !pDatabaseRangeSourceTableAttrTokenMap )
+
+ return *pDatabaseRangeSourceTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceQueryAttrTokenMap()
+{
+ if( !pDatabaseRangeSourceQueryAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeSourceQueryAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME },
+ { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_QUERY_ATTR_HREF },
+ { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE },
+ { XML_NAMESPACE_TABLE, XML_QUERY_NAME, XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSourceQueryAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceQueryAttrTokenMap );
+ } // if( !pDatabaseRangeSourceQueryAttrTokenMap )
+
+ return *pDatabaseRangeSourceQueryAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterElemTokenMap()
+{
+ if( !pFilterElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aFilterTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FILTER_AND, XML_TOK_FILTER_AND },
+ { XML_NAMESPACE_TABLE, XML_FILTER_OR, XML_TOK_FILTER_OR },
+ { XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, XML_TOK_FILTER_CONDITION },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterElemTokenMap = new SvXMLTokenMap( aFilterTokenMap );
+ } // if( !pFilterElemTokenMap )
+
+ return *pFilterElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterAttrTokenMap()
+{
+ if( !pFilterAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aFilterAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE, XML_TOK_FILTER_ATTR_CONDITION_SOURCE },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterAttrTokenMap = new SvXMLTokenMap( aFilterAttrTokenMap );
+ } // if( !pFilterAttrTokenMap )
+
+ return *pFilterAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetFilterConditionAttrTokenMap()
+{
+ if( !pFilterConditionAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aFilterConditionAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_CONDITION_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_CONDITION_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_CONDITION_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_VALUE, XML_TOK_CONDITION_ATTR_VALUE },
+ { XML_NAMESPACE_TABLE, XML_OPERATOR, XML_TOK_CONDITION_ATTR_OPERATOR },
+ XML_TOKEN_MAP_END
+ };
+
+ pFilterConditionAttrTokenMap = new SvXMLTokenMap( aFilterConditionAttrTokenMap );
+ } // if( !pFilterConditionAttrTokenMap )
+
+ return *pFilterConditionAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortElemTokenMap()
+{
+ if( !pSortElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aSortTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SORT_BY, XML_TOK_SORT_SORT_BY },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortElemTokenMap = new SvXMLTokenMap( aSortTokenMap );
+ } // if( !pSortElemTokenMap )
+
+ return *pSortElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortAttrTokenMap()
+{
+ if( !pSortAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aSortAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SORT_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_LANGUAGE, XML_TOK_SORT_ATTR_LANGUAGE },
+ { XML_NAMESPACE_TABLE, XML_COUNTRY, XML_TOK_SORT_ATTR_COUNTRY },
+ { XML_NAMESPACE_TABLE, XML_ALGORITHM, XML_TOK_SORT_ATTR_ALGORITHM },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortAttrTokenMap = new SvXMLTokenMap( aSortAttrTokenMap );
+ } // if( !pSortAttrTokenMap )
+
+ return *pSortAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSortSortByAttrTokenMap()
+{
+ if( !pSortSortByAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aSortSortByAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SORT_BY_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_BY_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_BY_ATTR_ORDER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSortSortByAttrTokenMap = new SvXMLTokenMap( aSortSortByAttrTokenMap );
+ } // if( !pSortSortByAttrTokenMap )
+
+ return *pSortSortByAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesElemTokenMap()
+{
+ if( !pDatabaseRangeSubTotalRulesElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SORT_GROUPS, XML_TOK_SUBTOTAL_RULES_SORT_GROUPS },
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSubTotalRulesElemTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesTokenMap );
+ } // if( !pDatabaseRangeSubTotalRulesElemTokenMap )
+
+ return *pDatabaseRangeSubTotalRulesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesAttrTokenMap()
+{
+ if( !pDatabaseRangeSubTotalRulesAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT },
+ { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE },
+ { XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDatabaseRangeSubTotalRulesAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesAttrTokenMap );
+ } // if( !pDatabaseRangeSubTotalRulesAttrTokenMap )
+
+ return *pDatabaseRangeSubTotalRulesAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSortGroupsAttrTokenMap()
+{
+ if( !pSubTotalRulesSortGroupsAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aSubTotalRulesSortGroupsAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE },
+ { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_GROUPS_ATTR_ORDER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSortGroupsAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSortGroupsAttrTokenMap );
+ } // if( !pSubTotalRulesSortGroupsAttrTokenMap )
+
+ return *pSubTotalRulesSortGroupsAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleElemTokenMap()
+{
+ if( !pSubTotalRulesSubTotalRuleElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSubTotalRuleElemTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleTokenMap );
+ } // if( !pSubTotalRulesSubTotalRuleElemTokenMap )
+
+ return *pSubTotalRulesSubTotalRuleElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleAttrTokenMap()
+{
+ if( !pSubTotalRulesSubTotalRuleAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRulesSubTotalRuleAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleAttrTokenMap );
+ } // if( !pSubTotalRulesSubTotalRuleAttrTokenMap )
+
+ return *pSubTotalRulesSubTotalRuleAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetSubTotalRuleSubTotalFieldAttrTokenMap()
+{
+ if( !pSubTotalRuleSubTotalFieldAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aSubTotalRuleSubTotalFieldAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION },
+ XML_TOKEN_MAP_END
+ };
+
+ pSubTotalRuleSubTotalFieldAttrTokenMap = new SvXMLTokenMap( aSubTotalRuleSubTotalFieldAttrTokenMap );
+ } // if( !pSubTotalRuleSubTotalFieldAttrTokenMap )
+
+ return *pSubTotalRuleSubTotalFieldAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTablesElemTokenMap()
+{
+ if( !pDataPilotTablesElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTablesElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, XML_TOK_DATA_PILOT_TABLE },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTablesElemTokenMap = new SvXMLTokenMap( aDataPilotTablesElemTokenMap );
+ } // if( !pDataPilotTablesElemTokenMap )
+
+ return *pDataPilotTablesElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableAttrTokenMap()
+{
+ if( !pDataPilotTableAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTableAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_TABLE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA },
+ { XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL },
+ { XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS },
+ { XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES },
+ { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_BUTTONS, XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS },
+ { XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON },
+ { XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN },
+ { XML_NAMESPACE_TABLE, XML_HEADER_GRID_LAYOUT, XML_TOK_DATA_PILOT_TABLE_ATTR_HEADER_GRID_LAYOUT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableAttrTokenMap = new SvXMLTokenMap( aDataPilotTableAttrTokenMap );
+ } // if( !pDataPilotTableAttrTokenMap )
+
+ return *pDataPilotTableAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap()
+{
+ if( !pDataPilotTableElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTableElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL },
+ { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableElemTokenMap = new SvXMLTokenMap( aDataPilotTableElemTokenMap );
+ } // if( !pDataPilotTableElemTokenMap )
+
+ return *pDataPilotTableElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap()
+{
+ if( !pDataPilotTableSourceServiceAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTableSourceServiceAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_SOURCE_SERVICE_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_NAME, XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME },
+ { XML_NAMESPACE_TABLE, XML_OBJECT_NAME, XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME },
+ { XML_NAMESPACE_TABLE, XML_USER_NAME, XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME },
+ { XML_NAMESPACE_TABLE, XML_PASSWORD, XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceServiceAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceServiceAttrTokenMap );
+ } // if( !pDataPilotTableSourceServiceAttrTokenMap )
+
+ return *pDataPilotTableSourceServiceAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap()
+{
+ if (!pDataPilotGrandTotalAttrTokenMap)
+ {
+ static SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap );
+ }
+
+ return *pDataPilotGrandTotalAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap()
+{
+ if( !pDataPilotTableSourceCellRangeAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTableSourceCellRangeAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_SOURCE_CELL_RANGE_ATTR_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceCellRangeAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeAttrTokenMap );
+ } // if( !pDataPilotTableSourceCellRangeAttrTokenMap )
+
+ return *pDataPilotTableSourceCellRangeAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeElemTokenMap()
+{
+ if( !pDataPilotTableSourceCellRangeElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotTableSourceCellRangeElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER},
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotTableSourceCellRangeElemTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeElemTokenMap );
+ } // if( !pDataPilotTableSourceCellRangeElemTokenMap )
+
+ return *pDataPilotTableSourceCellRangeElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap()
+{
+ if( !pDataPilotFieldAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE },
+ { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotFieldAttrTokenMap = new SvXMLTokenMap( aDataPilotFieldAttrTokenMap );
+ } // if( !pDataPilotFieldAttrTokenMap )
+
+ return *pDataPilotFieldAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldElemTokenMap()
+{
+ if( !pDataPilotFieldElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotFieldElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotFieldElemTokenMap = new SvXMLTokenMap( aDataPilotFieldElemTokenMap );
+ } // if( !pDataPilotFieldElemTokenMap )
+
+ return *pDataPilotFieldElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelAttrTokenMap()
+{
+ if( !pDataPilotLevelAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotLevelAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotLevelAttrTokenMap = new SvXMLTokenMap( aDataPilotLevelAttrTokenMap );
+ } // if( !pDataPilotLevelAttrTokenMap )
+
+ return *pDataPilotLevelAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelElemTokenMap()
+{
+ if( !pDataPilotLevelElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotLevelElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotLevelElemTokenMap = new SvXMLTokenMap( aDataPilotLevelElemTokenMap );
+ } // if( !pDataPilotLevelElemTokenMap )
+
+ return *pDataPilotLevelElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalsElemTokenMap()
+{
+ if( !pDataPilotSubTotalsElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotSubTotalsElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotSubTotalsElemTokenMap = new SvXMLTokenMap( aDataPilotSubTotalsElemTokenMap );
+ } // if( !pDataPilotSubTotalsElemTokenMap )
+
+ return *pDataPilotSubTotalsElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap()
+{
+ if( !pDataPilotSubTotalAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotSubTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotSubTotalAttrTokenMap );
+ } // if( !pDataPilotSubTotalAttrTokenMap )
+
+ return *pDataPilotSubTotalAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotMembersElemTokenMap()
+{
+ if( !pDataPilotMembersElemTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotMembersElemTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotMembersElemTokenMap = new SvXMLTokenMap( aDataPilotMembersElemTokenMap );
+ } // if( !pDataPilotMembersElemTokenMap )
+
+ return *pDataPilotMembersElemTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap()
+{
+ if( !pDataPilotMemberAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotMemberAttrTokenMap = new SvXMLTokenMap( aDataPilotMemberAttrTokenMap );
+ } // if( !pDataPilotMemberAttrTokenMap )
+
+ return *pDataPilotMemberAttrTokenMap;
+}
+
+const SvXMLTokenMap& ScXMLImport::GetConsolidationAttrTokenMap()
+{
+ if( !pConsolidationAttrTokenMap )
+ {
+ static SvXMLTokenMapEntry aConsolidationAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_CONSOLIDATION_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES },
+ { XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS },
+ { XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_TOK_CONSOLIDATION_ATTR_USE_LABEL },
+ { XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE },
+ XML_TOKEN_MAP_END
+ };
+
+ pConsolidationAttrTokenMap = new SvXMLTokenMap( aConsolidationAttrTokenMap );
+ } // if( !pConsolidationAttrTokenMap )
+
+ return *pConsolidationAttrTokenMap;
+}
+
+
+SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext = 0;
+
+ if( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT_STYLES) ||
+ IsXMLToken(rLocalName, XML_DOCUMENT_CONTENT) ||
+ IsXMLToken(rLocalName, XML_DOCUMENT_SETTINGS) )) {
+ pContext = new ScXMLDocContext_Impl( *this, nPrefix, rLocalName,
+ xAttrList );
+ } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) {
+ pContext = CreateMetaContext(rLocalName);
+ } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
+ ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) {
+ uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
+ mxServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.dom.SAXDocumentBuilder"))),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ // flat OpenDocument file format
+ pContext = new ScXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
+ xAttrList, xDPS->getDocumentProperties(), xDocBuilder);
+ }
+ else
+ pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
+
+ return pContext;
+}
+
+// #110680#
+ScXMLImport::ScXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nImportFlag)
+: SvXMLImport( xServiceFactory, nImportFlag ),
+ pDoc( NULL ),
+ pChangeTrackingImportHelper(NULL),
+ pStylesImportHelper(NULL),
+ sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT)),
+ sLocale(RTL_CONSTASCII_USTRINGPARAM(SC_LOCALE)),
+ sCellStyle(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLSTYL)),
+ sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(SC_STANDARDFORMAT)),
+ sType(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)),
+// pScAutoStylePool(new SvXMLAutoStylePoolP),
+// pParaItemMapper( 0 ),
+// pI18NMap( new SvI18NMap ),
+ pDocElemTokenMap( 0 ),
+ pStylesElemTokenMap( 0 ),
+ pStylesAttrTokenMap( 0 ),
+ pStyleElemTokenMap( 0 ),
+ pBodyElemTokenMap( 0 ),
+ pContentValidationsElemTokenMap( 0 ),
+ pContentValidationElemTokenMap( 0 ),
+ pContentValidationAttrTokenMap( 0 ),
+ pContentValidationMessageElemTokenMap( 0 ),
+ pContentValidationHelpMessageAttrTokenMap( 0 ),
+ pContentValidationErrorMessageAttrTokenMap( 0 ),
+ pContentValidationErrorMacroAttrTokenMap( 0 ),
+ pLabelRangesElemTokenMap( 0 ),
+ pLabelRangeAttrTokenMap( 0 ),
+ pTableElemTokenMap( 0 ),
+ pTableProtectionElemTokenMap(NULL),
+ pTableRowsElemTokenMap( 0 ),
+ pTableColsElemTokenMap( 0 ),
+ pTableScenarioAttrTokenMap( 0 ),
+ pTableAttrTokenMap( 0 ),
+ pTableColAttrTokenMap( 0 ),
+ pTableRowElemTokenMap( 0 ),
+ pTableRowAttrTokenMap( 0 ),
+ pTableRowCellElemTokenMap( 0 ),
+ pTableRowCellAttrTokenMap( 0 ),
+ pTableAnnotationAttrTokenMap( 0 ),
+ pDetectiveElemTokenMap( 0 ),
+ pDetectiveHighlightedAttrTokenMap( 0 ),
+ pDetectiveOperationAttrTokenMap( 0 ),
+ pTableCellRangeSourceAttrTokenMap( 0 ),
+ pNamedExpressionsElemTokenMap( 0 ),
+ pNamedRangeAttrTokenMap( 0 ),
+ pNamedExpressionAttrTokenMap( 0 ),
+ pDatabaseRangesElemTokenMap( 0 ),
+ pDatabaseRangeElemTokenMap( 0 ),
+ pDatabaseRangeAttrTokenMap( 0 ),
+ pDatabaseRangeSourceSQLAttrTokenMap( 0 ),
+ pDatabaseRangeSourceTableAttrTokenMap( 0 ),
+ pDatabaseRangeSourceQueryAttrTokenMap( 0 ),
+ pFilterElemTokenMap( 0 ),
+ pFilterAttrTokenMap( 0 ),
+ pFilterConditionAttrTokenMap( 0 ),
+ pSortElemTokenMap( 0 ),
+ pSortAttrTokenMap( 0 ),
+ pSortSortByAttrTokenMap( 0 ),
+ pDatabaseRangeSubTotalRulesElemTokenMap( 0 ),
+ pDatabaseRangeSubTotalRulesAttrTokenMap( 0 ),
+ pSubTotalRulesSortGroupsAttrTokenMap( 0 ),
+ pSubTotalRulesSubTotalRuleElemTokenMap( 0 ),
+ pSubTotalRulesSubTotalRuleAttrTokenMap( 0 ),
+ pSubTotalRuleSubTotalFieldAttrTokenMap( 0 ),
+ pDataPilotTablesElemTokenMap( 0 ),
+ pDataPilotTableAttrTokenMap( 0 ),
+ pDataPilotTableElemTokenMap( 0 ),
+ pDataPilotTableSourceServiceAttrTokenMap( 0 ),
+ pDataPilotGrandTotalAttrTokenMap(NULL),
+ pDataPilotTableSourceCellRangeElemTokenMap( 0 ),
+ pDataPilotTableSourceCellRangeAttrTokenMap( 0 ),
+ pDataPilotFieldAttrTokenMap( 0 ),
+ pDataPilotFieldElemTokenMap( 0 ),
+ pDataPilotLevelAttrTokenMap( 0 ),
+ pDataPilotLevelElemTokenMap( 0 ),
+ pDataPilotSubTotalsElemTokenMap( 0 ),
+ pDataPilotSubTotalAttrTokenMap( 0 ),
+ pDataPilotMembersElemTokenMap( 0 ),
+ pDataPilotMemberAttrTokenMap( 0 ),
+ pConsolidationAttrTokenMap( 0 ),
+ aTables(*this),
+ pMyNamedExpressions(NULL),
+ pMyLabelRanges(NULL),
+ pValidations(NULL),
+ pDetectiveOpArray(NULL),
+ pSolarMutexGuard(NULL),
+ pNumberFormatAttributesExportHelper(NULL),
+ pStyleNumberFormats(NULL),
+ sPrevStyleName(),
+ sPrevCurrency(),
+ nSolarMutexLocked(0),
+ nProgressCount(0),
+ nStyleFamilyMask( 0 ),
+ nPrevCellType(0),
+ bLoadDoc( sal_True ),
+ bRemoveLastChar(false),
+ bNullDateSetted(false),
+ bSelfImportingXMLSet(false),
+ bLatinDefaultStyle(false),
+ bFromWrapper(false)
+{
+ pStylesImportHelper = new ScMyStylesImportHelper(*this);
+
+ xScPropHdlFactory = new XMLScPropHdlFactory;
+ xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory);
+ xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory);
+ xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesImportProperties, xScPropHdlFactory);
+ xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesImportProperties, xScPropHdlFactory);
+
+ // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
+ GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_PRESENTATION ),
+ GetXMLToken( XML_N_PRESENTATION ),
+ XML_NAMESPACE_PRESENTATION );
+
+ // initialize cell type map.
+ const struct { XMLTokenEnum _token; sal_Int16 _type; } aCellTypePairs[] =
+ {
+ { XML_FLOAT, util::NumberFormat::NUMBER },
+ { XML_STRING, util::NumberFormat::TEXT },
+ { XML_TIME, util::NumberFormat::TIME },
+ { XML_DATE, util::NumberFormat::DATETIME },
+ { XML_PERCENTAGE, util::NumberFormat::PERCENT },
+ { XML_CURRENCY, util::NumberFormat::CURRENCY },
+ { XML_BOOLEAN, util::NumberFormat::LOGICAL }
+ };
+ size_t n = SAL_N_ELEMENTS(aCellTypePairs);
+ for (size_t i = 0; i < n; ++i)
+ {
+ aCellTypeMap.insert(
+ CellTypeMap::value_type(
+ GetXMLToken(aCellTypePairs[i]._token), aCellTypePairs[i]._type));
+ }
+}
+
+ScXMLImport::~ScXMLImport() throw()
+{
+ // delete pI18NMap;
+ delete pDocElemTokenMap;
+ delete pStylesElemTokenMap;
+ delete pStylesAttrTokenMap;
+ delete pStyleElemTokenMap;
+ delete pBodyElemTokenMap;
+ delete pContentValidationsElemTokenMap;
+ delete pContentValidationElemTokenMap;
+ delete pContentValidationAttrTokenMap;
+ delete pContentValidationMessageElemTokenMap;
+ delete pContentValidationHelpMessageAttrTokenMap;
+ delete pContentValidationErrorMessageAttrTokenMap;
+ delete pContentValidationErrorMacroAttrTokenMap;
+ delete pLabelRangesElemTokenMap;
+ delete pLabelRangeAttrTokenMap;
+ delete pTableElemTokenMap;
+ delete pTableProtectionElemTokenMap;
+ delete pTableRowsElemTokenMap;
+ delete pTableColsElemTokenMap;
+ delete pTableAttrTokenMap;
+ delete pTableScenarioAttrTokenMap;
+ delete pTableColAttrTokenMap;
+ delete pTableRowElemTokenMap;
+ delete pTableRowAttrTokenMap;
+ delete pTableRowCellElemTokenMap;
+ delete pTableRowCellAttrTokenMap;
+ delete pTableAnnotationAttrTokenMap;
+ delete pDetectiveElemTokenMap;
+ delete pDetectiveHighlightedAttrTokenMap;
+ delete pDetectiveOperationAttrTokenMap;
+ delete pTableCellRangeSourceAttrTokenMap;
+ delete pNamedExpressionsElemTokenMap;
+ delete pNamedRangeAttrTokenMap;
+ delete pNamedExpressionAttrTokenMap;
+ delete pDatabaseRangesElemTokenMap;
+ delete pDatabaseRangeElemTokenMap;
+ delete pDatabaseRangeAttrTokenMap;
+ delete pDatabaseRangeSourceSQLAttrTokenMap;
+ delete pDatabaseRangeSourceTableAttrTokenMap;
+ delete pDatabaseRangeSourceQueryAttrTokenMap;
+ delete pFilterElemTokenMap;
+ delete pFilterAttrTokenMap;
+ delete pFilterConditionAttrTokenMap;
+ delete pSortElemTokenMap;
+ delete pSortAttrTokenMap;
+ delete pSortSortByAttrTokenMap;
+ delete pDatabaseRangeSubTotalRulesElemTokenMap;
+ delete pDatabaseRangeSubTotalRulesAttrTokenMap;
+ delete pSubTotalRulesSortGroupsAttrTokenMap;
+ delete pSubTotalRulesSubTotalRuleElemTokenMap;
+ delete pSubTotalRulesSubTotalRuleAttrTokenMap;
+ delete pSubTotalRuleSubTotalFieldAttrTokenMap;
+ delete pDataPilotTablesElemTokenMap;
+ delete pDataPilotTableAttrTokenMap;
+ delete pDataPilotTableElemTokenMap;
+ delete pDataPilotTableSourceServiceAttrTokenMap;
+ delete pDataPilotTableSourceCellRangeAttrTokenMap;
+ delete pDataPilotTableSourceCellRangeElemTokenMap;
+ delete pDataPilotFieldAttrTokenMap;
+ delete pDataPilotFieldElemTokenMap;
+ delete pDataPilotLevelAttrTokenMap;
+ delete pDataPilotLevelElemTokenMap;
+ delete pDataPilotSubTotalsElemTokenMap;
+ delete pDataPilotSubTotalAttrTokenMap;
+ delete pDataPilotMembersElemTokenMap;
+ delete pDataPilotMemberAttrTokenMap;
+ delete pConsolidationAttrTokenMap;
+
+ // if (pScAutoStylePool)
+ // delete pScAutoStylePool;
+ if (pChangeTrackingImportHelper)
+ delete pChangeTrackingImportHelper;
+ if (pNumberFormatAttributesExportHelper)
+ delete pNumberFormatAttributesExportHelper;
+ if (pStyleNumberFormats)
+ delete pStyleNumberFormats;
+ if (pStylesImportHelper)
+ delete pStylesImportHelper;
+
+ if (pSolarMutexGuard)
+ delete pSolarMutexGuard;
+
+ if (pMyNamedExpressions)
+ delete pMyNamedExpressions;
+ if (pMyLabelRanges)
+ delete pMyLabelRanges;
+ if (pValidations)
+ delete pValidations;
+ if (pDetectiveOpArray)
+ delete pDetectiveOpArray;
+}
+
+// ---------------------------------------------------------------------
+
+SvXMLImportContext *ScXMLImport::CreateFontDeclsContext(const sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ XMLFontStylesContext *pFSContext = new XMLFontStylesContext(
+ *this, nPrefix, rLocalName, xAttrList, gsl_getSystemTextEncoding());
+ SetFontDecls(pFSContext);
+ SvXMLImportContext* pContext = pFSContext;
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateStylesContext(const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList, sal_Bool bIsAutoStyle )
+{
+ SvXMLImportContext* pContext = new XMLTableStylesContext(
+ *this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList, bIsAutoStyle);
+
+ if (bIsAutoStyle)
+ SetAutoStyles((SvXMLStylesContext*)pContext);
+ else
+ SetStyles((SvXMLStylesContext*)pContext);
+
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateBodyContext(const ::rtl::OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ return new ScXMLBodyContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList);
+}
+
+SvXMLImportContext *ScXMLImport::CreateMetaContext(
+ const OUString& rLocalName )
+{
+ SvXMLImportContext* pContext = NULL;
+
+ if( !IsStylesOnlyMode() && (getImportFlags() & IMPORT_META))
+ {
+ uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
+ mxServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.dom.SAXDocumentBuilder"))),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ pContext = new SvXMLMetaDocumentContext(*this,
+ XML_NAMESPACE_OFFICE, rLocalName,
+ xDPS->getDocumentProperties(), xDocBuilder);
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( *this,
+ XML_NAMESPACE_OFFICE, rLocalName );
+
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateScriptContext(
+ const OUString& rLocalName )
+{
+ SvXMLImportContext* pContext = NULL;
+
+ if( !(IsStylesOnlyMode()) )
+ {
+ pContext = new XMLScriptContext( *this,
+ XML_NAMESPACE_OFFICE, rLocalName,
+ GetModel() );
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE,
+ rLocalName );
+
+ return pContext;
+}
+
+void ScXMLImport::SetStatistics(
+ const uno::Sequence<beans::NamedValue> & i_rStats)
+{
+ static const char* s_stats[] =
+ { "TableCount", "CellCount", "ObjectCount", 0 };
+
+ SvXMLImport::SetStatistics(i_rStats);
+
+ sal_uInt32 nCount(0);
+ for (sal_Int32 i = 0; i < i_rStats.getLength(); ++i) {
+ for (const char** pStat = s_stats; *pStat != 0; ++pStat) {
+ if (i_rStats[i].Name.equalsAscii(*pStat)) {
+ sal_Int32 val = 0;
+ if (i_rStats[i].Value >>= val) {
+ nCount += val;
+ } else {
+ OSL_FAIL("ScXMLImport::SetStatistics: invalid entry");
+ }
+ }
+ }
+ }
+
+ if (nCount)
+ {
+ GetProgressBarHelper()->SetReference(nCount);
+ GetProgressBarHelper()->SetValue(0);
+ }
+}
+
+sal_Int16 ScXMLImport::GetCellType(const OUString& rStrValue) const
+{
+ CellTypeMap::const_iterator itr = aCellTypeMap.find(rStrValue);
+ if (itr != aCellTypeMap.end())
+ return itr->second;
+
+ return util::NumberFormat::UNDEFINED;
+}
+
+XMLShapeImportHelper* ScXMLImport::CreateShapeImport()
+{
+ return new XMLTableShapeImportHelper(*this);
+}
+
+sal_Bool ScXMLImport::GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation)
+{
+ if (pValidations)
+ {
+ sal_Bool bFound(false);
+ ScMyImportValidations::iterator aItr(pValidations->begin());
+ ScMyImportValidations::iterator aEndItr(pValidations->end());
+ while(aItr != aEndItr && !bFound)
+ {
+ if (aItr->sName == sName)
+ {
+ // source position must be set as string,
+ // so sBaseCellAddress no longer has to be converted here
+
+ bFound = sal_True;
+ }
+ else
+ ++aItr;
+ }
+ if (bFound)
+ aValidation = *aItr;
+ return bFound;
+ }
+ return false;
+}
+
+void ScXMLImport::AddNamedExpression(SCTAB nTab, ScMyNamedExpression* pNamedExp)
+{
+ ::std::auto_ptr<ScMyNamedExpression> p(pNamedExp);
+ SheetNamedExpMap::iterator itr = maSheetNamedExpressions.find(nTab);
+ if (itr == maSheetNamedExpressions.end())
+ {
+ // No chain exists for this sheet. Create one.
+ ::std::auto_ptr<ScMyNamedExpressions> pNew(new ScMyNamedExpressions);
+ ::std::pair<SheetNamedExpMap::iterator, bool> r = maSheetNamedExpressions.insert(nTab, pNew);
+ if (!r.second)
+ // insertion failed.
+ return;
+
+ itr = r.first;
+ }
+ ScMyNamedExpressions& r = *itr->second;
+ r.push_back(p);
+}
+
+ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
+{
+ if (!pChangeTrackingImportHelper)
+ pChangeTrackingImportHelper = new ScXMLChangeTrackingImportHelper();
+ return pChangeTrackingImportHelper;
+}
+
+void ScXMLImport::InsertStyles()
+{
+ GetStyles()->CopyStylesToDoc(sal_True);
+
+ // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
+ if ( getImportFlags() & IMPORT_CONTENT )
+ ExamineDefaultStyle();
+}
+
+void ScXMLImport::ExamineDefaultStyle()
+{
+ if (pDoc)
+ {
+ // #i62435# after inserting the styles, check if the default style has a latin-script-only
+ // number format (then, value cells can be pre-initialized with western script type)
+
+ const ScPatternAttr* pDefPattern = pDoc->GetDefPattern();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ if ( pFormatter && pDefPattern )
+ {
+ sal_uInt32 nKey = pDefPattern->GetNumberFormat(pFormatter);
+ const SvNumberformat* pFormat = pFormatter->GetEntry(nKey);
+ if ( pFormat && pFormat->IsStandard() )
+ {
+ // The standard format is all-latin if the decimal separator dosen't
+ // have a different script type
+
+ String aDecSep;
+ LanguageType nFormatLang = pFormat->GetLanguage();
+ if ( nFormatLang == LANGUAGE_SYSTEM )
+ aDecSep = ScGlobal::pLocaleData->getNumDecimalSep();
+ else
+ {
+ LocaleDataWrapper aLocaleData( pDoc->GetServiceManager(),
+ MsLangId::convertLanguageToLocale( nFormatLang ) );
+ aDecSep = aLocaleData.getNumDecimalSep();
+ }
+
+ sal_uInt8 nScript = pDoc->GetStringScriptType( aDecSep );
+ if ( nScript == 0 || nScript == SCRIPTTYPE_LATIN )
+ bLatinDefaultStyle = sal_True;
+ }
+ }
+ }
+}
+
+void ScXMLImport::SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps)
+{
+ if (pDoc)
+ {
+ sal_Int32 nCount(rChangeProps.getLength());
+ if (nCount)
+ {
+ ScXMLImport::MutexGuard aGuard(*this);
+ sal_Int16 nTemp16(0);
+ ScChangeViewSettings* pViewSettings(new ScChangeViewSettings());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(rChangeProps[i].Name);
+ if (sName.compareToAscii("ShowChanges") == 0)
+ pViewSettings->SetShowChanges(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowAcceptedChanges") == 0)
+ pViewSettings->SetShowAccepted(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowRejectedChanges") == 0)
+ pViewSettings->SetShowRejected(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByDatetime") == 0)
+ pViewSettings->SetHasDate(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByDatetimeMode") == 0)
+ {
+ if (rChangeProps[i].Value >>= nTemp16)
+ pViewSettings->SetTheDateMode(ScChgsDateMode(nTemp16));
+ }
+ else if (sName.compareToAscii("ShowChangesByDatetimeFirstDatetime") == 0)
+ {
+ util::DateTime aDateTime;
+ if (rChangeProps[i].Value >>= aDateTime)
+ {
+ DateTime aCoreDateTime;
+ ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime);
+ pViewSettings->SetTheFirstDateTime(aCoreDateTime);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByDatetimeSecondDatetime") == 0)
+ {
+ util::DateTime aDateTime;
+ if (rChangeProps[i].Value >>= aDateTime)
+ {
+ DateTime aCoreDateTime;
+ ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime);
+ pViewSettings->SetTheLastDateTime(aCoreDateTime);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByAuthor") == 0)
+ pViewSettings->SetHasAuthor(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByAuthorName") == 0)
+ {
+ rtl::OUString sOUName;
+ if (rChangeProps[i].Value >>= sOUName)
+ {
+ String sAuthorName(sOUName);
+ pViewSettings->SetTheAuthorToShow(sAuthorName);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByComment") == 0)
+ pViewSettings->SetHasComment(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByCommentText") == 0)
+ {
+ rtl::OUString sOUComment;
+ if (rChangeProps[i].Value >>= sOUComment)
+ {
+ String sComment(sOUComment);
+ pViewSettings->SetTheComment(sComment);
+ }
+ }
+ else if (sName.compareToAscii("ShowChangesByRanges") == 0)
+ pViewSettings->SetHasRange(::cppu::any2bool(rChangeProps[i].Value));
+ else if (sName.compareToAscii("ShowChangesByRangesList") == 0)
+ {
+ rtl::OUString sRanges;
+ if ((rChangeProps[i].Value >>= sRanges) && sRanges.getLength())
+ {
+ ScRangeList aRangeList;
+ ScRangeStringConverter::GetRangeListFromString(
+ aRangeList, sRanges, GetDocument(), FormulaGrammar::CONV_OOO);
+ pViewSettings->SetTheRangeList(aRangeList);
+ }
+ }
+ }
+ pDoc->SetChangeViewSettings(*pViewSettings);
+ }
+ }
+}
+
+void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps)
+{
+ sal_Int32 nCount(aViewProps.getLength());
+ sal_Int32 nHeight(0);
+ sal_Int32 nLeft(0);
+ sal_Int32 nTop(0);
+ sal_Int32 nWidth(0);
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(aViewProps[i].Name);
+ if (sName.compareToAscii("VisibleAreaHeight") == 0)
+ aViewProps[i].Value >>= nHeight;
+ else if (sName.compareToAscii("VisibleAreaLeft") == 0)
+ aViewProps[i].Value >>= nLeft;
+ else if (sName.compareToAscii("VisibleAreaTop") == 0)
+ aViewProps[i].Value >>= nTop;
+ else if (sName.compareToAscii("VisibleAreaWidth") == 0)
+ aViewProps[i].Value >>= nWidth;
+ else if (sName.compareToAscii("TrackedChangesViewSettings") == 0)
+ {
+ uno::Sequence<beans::PropertyValue> aChangeProps;
+ if(aViewProps[i].Value >>= aChangeProps)
+ SetChangeTrackingViewSettings(aChangeProps);
+ }
+ }
+ if (nHeight && nWidth)
+ {
+ if (GetModel().is())
+ {
+ ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() ));
+ if (pDocObj)
+ {
+ SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
+ if (pEmbeddedObj)
+ {
+ Rectangle aRect;
+ aRect.setX( nLeft );
+ aRect.setY( nTop );
+ aRect.setWidth( nWidth );
+ aRect.setHeight( nHeight );
+ pEmbeddedObj->SetVisArea(aRect);
+ }
+ }
+ }
+ }
+}
+
+void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps)
+{
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ sal_Int32 nCount(aConfigProps.getLength());
+ rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey"));
+ rtl::OUString sVBName(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"));
+ rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration"));
+ for (sal_Int32 i = nCount - 1; i >= 0; --i)
+ {
+ if (aConfigProps[i].Name == sCTName)
+ {
+ rtl::OUString sKey;
+ if (aConfigProps[i].Value >>= sKey)
+ {
+ uno::Sequence<sal_Int8> aPass;
+ SvXMLUnitConverter::decodeBase64(aPass, sKey);
+ if (aPass.getLength())
+ {
+ if (pDoc->GetChangeTrack())
+ pDoc->GetChangeTrack()->SetProtection(aPass);
+ else
+ {
+ ScStrCollection aUsers;
+ ScChangeTrack* pTrack = new ScChangeTrack(pDoc, aUsers);
+ pTrack->SetProtection(aPass);
+ pDoc->SetChangeTrack(pTrack);
+ }
+ }
+ }
+ }
+ // store the following items for later use (after document is loaded)
+ else if ((aConfigProps[i].Name == sVBName) || (aConfigProps[i].Name == sSCName))
+ {
+ uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo();
+ if (xImportInfo.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
+ if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name))
+ xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value );
+ }
+ }
+ }
+ uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings")));
+ uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY);
+ if (xProperties.is())
+ SvXMLUnitConverter::convertPropertySet(xProperties, aConfigProps);
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ rtl::OUString sFormatString;
+ try
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey));
+ if (xProperties.is())
+ {
+ lang::Locale aLocale;
+ if (GetDocument() && (xProperties->getPropertyValue(sLocale) >>= aLocale))
+ {
+ {
+ ScXMLImport::MutexGuard aGuard(*this);
+ LocaleDataWrapper aLocaleData( GetDocument()->GetServiceManager(), aLocale );
+ rtl::OUStringBuffer aBuffer(15);
+ aBuffer.appendAscii("#");
+ aBuffer.append( aLocaleData.getNumThousandSep() );
+ aBuffer.appendAscii("##0");
+ aBuffer.append( aLocaleData.getNumDecimalSep() );
+ aBuffer.appendAscii("00 [$");
+ aBuffer.append(rCurrency);
+ aBuffer.appendAscii("]");
+ sFormatString = aBuffer.makeStringAndClear();
+ }
+ sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, sal_True);
+ if (nNewKey == -1)
+ nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale);
+ return nNewKey;
+ }
+ }
+ }
+ catch ( util::MalformedNumberFormatException& rException )
+ {
+ rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Fehler im Formatstring "));
+ sErrorMessage += sFormatString;
+ sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" an Position "));
+ sErrorMessage += rtl::OUString::valueOf(rException.CheckPos);
+ uno::Sequence<rtl::OUString> aSeq(1);
+ aSeq[0] = sErrorMessage;
+ uno::Reference<xml::sax::XLocator> xLocator;
+ SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator);
+ }
+ }
+ }
+ return nKey;
+}
+
+sal_Bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrentCurrency, const rtl::OUString& sBankSymbol)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat));
+ if (xNumberPropertySet.is())
+ {
+ rtl::OUString sTemp;
+ if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURRENCYSYMBOL))) >>= sTemp)
+ {
+ if (sCurrentCurrency.equals(sTemp))
+ return sal_True;
+ // #i61657# This may be a legacy currency symbol that changed in the meantime.
+ if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != NULL)
+ return true;
+ // In the rare case that sCurrentCurrency is not the
+ // currency symbol, but a matching ISO code
+ // abbreviation instead that was obtained through
+ // XMLNumberFormatAttributesExportHelper::GetCellType(),
+ // check with the number format's symbol. This happens,
+ // for example, in the es_BO locale, where a legacy
+ // B$,BOB matched B$->BOP, which leads to
+ // sCurrentCurrency being BOP, and the previous call
+ // with BOP,BOB didn't find an entry, but B$,BOB will.
+ return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != NULL;
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL("Numberformat not found");
+ }
+ }
+ }
+ return false;
+}
+
+void ScXMLImport::SetType(uno::Reference <beans::XPropertySet>& rProperties,
+ sal_Int32& rNumberFormat,
+ const sal_Int16 nCellType,
+ const rtl::OUString& rCurrency)
+{
+ if ((nCellType != util::NumberFormat::TEXT) && (nCellType != util::NumberFormat::UNDEFINED))
+ {
+ if (rNumberFormat == -1)
+ rProperties->getPropertyValue( sNumberFormat ) >>= rNumberFormat;
+ DBG_ASSERT(rNumberFormat != -1, "no NumberFormat");
+ sal_Bool bIsStandard;
+ // sCurrentCurrency may be the ISO code abbreviation if the currency
+ // symbol matches such, or if no match found the symbol itself!
+ rtl::OUString sCurrentCurrency;
+ sal_Int32 nCurrentCellType(
+ GetNumberFormatAttributesExportHelper()->GetCellType(
+ rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED);
+ if ((nCellType != nCurrentCellType) && !((nCellType == util::NumberFormat::NUMBER &&
+ ((nCurrentCellType == util::NumberFormat::SCIENTIFIC) ||
+ (nCurrentCellType == util::NumberFormat::FRACTION) ||
+ (nCurrentCellType == util::NumberFormat::LOGICAL) ||
+ (nCurrentCellType == 0))) || (nCurrentCellType == util::NumberFormat::TEXT)) && !((nCellType == util::NumberFormat::DATETIME) &&
+ (nCurrentCellType == util::NumberFormat::DATE)))
+ {
+ if (!xNumberFormats.is())
+ {
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats());
+ }
+ if (xNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat));
+ if (xNumberFormatProperties.is())
+ {
+ if (nCellType != util::NumberFormat::CURRENCY)
+ {
+ lang::Locale aLocale;
+ if ( xNumberFormatProperties->getPropertyValue(sLocale) >>= aLocale )
+ {
+ if (!xNumberFormatTypes.is())
+ xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY));
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) );
+ }
+ }
+ else if (rCurrency.getLength() && sCurrentCurrency.getLength())
+ {
+ if (!sCurrentCurrency.equals(rCurrency))
+ if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL("Numberformat not found");
+ }
+ }
+ }
+ else
+ {
+ if ((nCellType == util::NumberFormat::CURRENCY) && rCurrency.getLength() && sCurrentCurrency.getLength() &&
+ !sCurrentCurrency.equals(rCurrency) && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+ }
+}
+
+void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange)
+{
+ if (!xSheetCellRanges.is() && GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))), uno::UNO_QUERY));
+ DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+
+ }
+ xSheetCellRanges->addRangeAddress(rCellRange, false);
+}
+
+void ScXMLImport::SetStyleToRanges()
+{
+ if (sPrevStyleName.getLength())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ XMLTableStylesContext *pStyles((XMLTableStylesContext *)GetAutoStyles());
+ XMLTableStyleContext* pStyle( pStyles ? (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName, sal_True) : NULL );
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xProperties);
+ sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+
+ // store first cell of first range for each style, once per sheet
+ uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses());
+ if ( aAddresses.getLength() > 0 )
+ {
+ const table::CellRangeAddress& rRange = aAddresses[0];
+ if ( rRange.Sheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ pSheetData->AddCellStyle( sPrevStyleName,
+ ScAddress( (SCCOL)rRange.StartColumn, (SCROW)rRange.StartRow, (SCTAB)rRange.Sheet ) );
+ pStyle->SetLastSheet(rRange.Sheet);
+ }
+ }
+ }
+ else
+ {
+ xProperties->setPropertyValue(sCellStyle, uno::makeAny(GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName )));
+ sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName));
+ sal_Bool bInsert(nNumberFormat == -1);
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+ if (bInsert)
+ GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat);
+ }
+ }
+ }
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(
+ xMultiServiceFactory->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))),
+ uno::UNO_QUERY));
+ }
+ DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+}
+
+void ScXMLImport::SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName,
+ const sal_Int16 nCellType, const rtl::OUString* pCurrency)
+{
+ if (!sPrevStyleName.getLength())
+ {
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if (sPrevCurrency.getLength())
+ sPrevCurrency = sEmpty;
+ }
+ else if ((nCellType != nPrevCellType) ||
+ ((pStyleName && !pStyleName->equals(sPrevStyleName)) ||
+ (!pStyleName && sPrevStyleName.getLength())) ||
+ ((pCurrency && !pCurrency->equals(sPrevCurrency)) ||
+ (!pCurrency && sPrevCurrency.getLength())))
+ {
+ SetStyleToRanges();
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ else if(sPrevStyleName.getLength())
+ sPrevStyleName = sEmpty;
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if(sPrevCurrency.getLength())
+ sPrevCurrency = sEmpty;
+ }
+ table::CellRangeAddress aCellRange;
+ aCellRange.StartColumn = rRange.aStart.Col();
+ aCellRange.StartRow = rRange.aStart.Row();
+ aCellRange.Sheet = rRange.aStart.Tab();
+ aCellRange.EndColumn = rRange.aEnd.Col();
+ aCellRange.EndRow = rRange.aEnd.Row();
+ AddStyleRange(aCellRange);
+}
+
+sal_Bool ScXMLImport::SetNullDateOnUnitConverter()
+{
+ if (!bNullDateSetted)
+ bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel());
+ DBG_ASSERT(bNullDateSetted, "could not set the null date");
+ return bNullDateSetted;
+}
+
+XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper()
+{
+ if (!pNumberFormatAttributesExportHelper)
+ pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier());
+ return pNumberFormatAttributesExportHelper;
+}
+
+ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats()
+{
+ if (!pStyleNumberFormats)
+ pStyleNumberFormats = new ScMyStyleNumberFormats();
+ return pStyleNumberFormats;
+}
+
+void ScXMLImport::SetStylesToRangesFinished()
+{
+ SetStyleToRanges();
+ sPrevStyleName = sEmpty;
+}
+
+// XImporter
+void SAL_CALL ScXMLImport::setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ SvXMLImport::setTargetDocument( xDoc );
+
+ uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY);
+ pDoc = ScXMLConverter::GetScDocument( xModel );
+ DBG_ASSERT( pDoc, "ScXMLImport::setTargetDocument - no ScDocument!" );
+ if (!pDoc)
+ throw lang::IllegalArgumentException();
+
+ bFromWrapper = pDoc->IsXMLFromWrapper(); // UnlockSolarMutex below still works normally
+
+ uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->addActionLock();
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ScXMLImport::getImplementationName( )
+throw(::com::sun::star::uno::RuntimeException)
+{
+ switch( getImportFlags() )
+ {
+ case IMPORT_ALL:
+ return ScXMLImport_getImplementationName();
+ case (IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_FONTDECLS):
+ return ScXMLImport_Styles_getImplementationName();
+ case (IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS):
+ return ScXMLImport_Content_getImplementationName();
+ case IMPORT_META:
+ return ScXMLImport_Meta_getImplementationName();
+ case IMPORT_SETTINGS:
+ return ScXMLImport_Settings_getImplementationName();
+ default:
+ // generic name for 'unknown' cases
+ return ScXMLImport_getImplementationName();
+ }
+ return SvXMLImport::getImplementationName();
+}
+
+// ::com::sun::star::xml::sax::XDocumentHandler
+void SAL_CALL ScXMLImport::startDocument(void)
+throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ SvXMLImport::startDocument();
+ if (pDoc && !pDoc->IsImportingXML())
+ {
+ ScModelObj::getImplementation(GetModel())->BeforeXMLLoading();
+ bSelfImportingXMLSet = sal_True;
+ }
+
+ // if content and styles are loaded with separate imports,
+ // set bLatinDefaultStyle flag at the start of the content import
+ sal_uInt16 nFlags = getImportFlags();
+ if ( ( nFlags & IMPORT_CONTENT ) && !( nFlags & IMPORT_STYLES ) )
+ ExamineDefaultStyle();
+
+ if (getImportFlags() & IMPORT_CONTENT)
+ {
+ if (GetModel().is())
+ {
+ // store initial namespaces, to find the ones that were added from the file later
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
+ pSheetData->StoreInitialNamespaces(rNamespaces);
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::GetRangeType(const rtl::OUString sRangeType) const
+{
+ sal_Int32 nRangeType(0);
+ rtl::OUStringBuffer sBuffer;
+ sal_Int16 i = 0;
+ while (i <= sRangeType.getLength())
+ {
+ if ((sRangeType[i] == ' ') || (i == sRangeType.getLength()))
+ {
+ rtl::OUString sTemp = sBuffer.makeStringAndClear();
+ if (sTemp.compareToAscii(SC_REPEAT_COLUMN) == 0)
+ nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER;
+ else if (sTemp.compareToAscii(SC_REPEAT_ROW) == 0)
+ nRangeType |= sheet::NamedRangeFlag::ROW_HEADER;
+ else if (sTemp.compareToAscii(SC_FILTER) == 0)
+ nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
+ else if (sTemp.compareToAscii(SC_PRINT_RANGE) == 0)
+ nRangeType |= sheet::NamedRangeFlag::PRINT_AREA;
+ }
+ else if (i < sRangeType.getLength())
+ sBuffer.append(sRangeType[i]);
+ ++i;
+ }
+ return nRangeType;
+}
+
+void ScXMLImport::SetLabelRanges()
+{
+ ScMyLabelRanges* pLabelRanges = GetLabelRanges();
+ if (pLabelRanges)
+ {
+ uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ uno::Any aColAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLLABELRNG)));
+ uno::Any aRowAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ROWLABELRNG)));
+
+ uno::Reference< sheet::XLabelRanges > xColRanges;
+ uno::Reference< sheet::XLabelRanges > xRowRanges;
+
+ if ( ( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges ) )
+ {
+ table::CellRangeAddress aLabelRange;
+ table::CellRangeAddress aDataRange;
+
+ ScMyLabelRanges::iterator aItr = pLabelRanges->begin();
+ while (aItr != pLabelRanges->end())
+ {
+ sal_Int32 nOffset1(0);
+ sal_Int32 nOffset2(0);
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
+
+ if (ScRangeStringConverter::GetRangeFromString( aLabelRange, (*aItr)->sLabelRangeStr, GetDocument(), eConv, nOffset1 ) &&
+ ScRangeStringConverter::GetRangeFromString( aDataRange, (*aItr)->sDataRangeStr, GetDocument(), eConv, nOffset2 ))
+ {
+ if ( (*aItr)->bColumnOrientation )
+ xColRanges->addNew( aLabelRange, aDataRange );
+ else
+ xRowRanges->addNew( aLabelRange, aDataRange );
+ }
+
+ delete *aItr;
+ aItr = pLabelRanges->erase(aItr);
+ }
+ }
+ }
+ }
+}
+
+namespace {
+
+/**
+ * Used to switch off document modify and broadcast while populating named
+ * ranges during import.
+ */
+class NamedRangesSwitch
+{
+public:
+ NamedRangesSwitch(Reference<beans::XPropertySet>& xPropSet) :
+ mxPropSet(xPropSet), maPropName(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MODIFY_BROADCAST))
+ {
+ uno::Any any;
+ any <<= false;
+ mxPropSet->setPropertyValue(maPropName, any);
+ }
+
+ ~NamedRangesSwitch()
+ {
+ uno::Any any;
+ any <<= sal_True;
+ mxPropSet->setPropertyValue(maPropName, any);
+ }
+
+private:
+ Reference<beans::XPropertySet>& mxPropSet;
+ OUString maPropName;
+};
+
+}
+
+void ScXMLImport::SetNamedRanges()
+{
+ ScMyNamedExpressions* pNamedExpressions = GetNamedExpressions();
+ if (!pNamedExpressions)
+ return;
+
+ Reference <beans::XPropertySet> xPropertySet (GetModel(), UNO_QUERY);
+ if (!xPropertySet.is())
+ return;
+
+ Reference <sheet::XNamedRanges> xNamedRanges(
+ xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_NAMEDRANGES))), UNO_QUERY);
+
+ if (!xNamedRanges.is())
+ return;
+
+ Reference<beans::XPropertySet> xPropSet(xNamedRanges, UNO_QUERY);
+ if (!xPropSet.is())
+ return;
+
+ // Turn off broadcasting while adding imported range names.
+ NamedRangesSwitch aSwitch(xPropSet);
+
+ ScMyNamedExpressions::iterator aItr(pNamedExpressions->begin());
+ ScMyNamedExpressions::const_iterator aEndItr(pNamedExpressions->end());
+ table::CellAddress aCellAddress;
+ OUString sTempContent(RTL_CONSTASCII_USTRINGPARAM("0"));
+
+ for (; aItr != aEndItr; ++aItr)
+ {
+ sal_Int32 nOffset = 0;
+ bool bSuccess = ScRangeStringConverter::GetAddressFromString(
+ aCellAddress, aItr->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset);
+
+ if (!bSuccess)
+ // Conversion of base cell address failed. Skip this.
+ continue;
+
+ try
+ {
+ xNamedRanges->addNewByName(
+ aItr->sName, sTempContent, aCellAddress, GetRangeType(aItr->sRangeType));
+ }
+ catch( uno::RuntimeException& )
+ {
+ OSL_FAIL("here are some Named Ranges with the same name");
+ uno::Reference < container::XIndexAccess > xIndex(xNamedRanges, uno::UNO_QUERY);
+ if (xIndex.is())
+ {
+ sal_Int32 nMax = xIndex->getCount();
+ bool bInserted = false;
+ sal_Int32 nCount = 1;
+ OUStringBuffer sName(aItr->sName);
+ sName.append(sal_Unicode('_'));
+ while (!bInserted && nCount <= nMax)
+ {
+ OUStringBuffer sTemp(sName);
+ sTemp.append(OUString::valueOf(nCount));
+ try
+ {
+ xNamedRanges->addNewByName(
+ sTemp.makeStringAndClear(), sTempContent, aCellAddress,
+ GetRangeType(aItr->sRangeType));
+ bInserted = true;
+ }
+ catch( uno::RuntimeException& )
+ {
+ ++nCount;
+ }
+ }
+ UnlockSolarMutex();
+ }
+ }
+ }
+
+ aItr = pNamedExpressions->begin();
+ while (aItr != aEndItr)
+ {
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetAddressFromString(
+ aCellAddress, aItr->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName(aItr->sName), uno::UNO_QUERY);
+ if (xNamedRange.is())
+ {
+ ScXMLImport::MutexGuard aGuard(*this);
+ ScNamedRangeObj* pNamedRangeObj = ScNamedRangeObj::getImplementation( xNamedRange);
+ if (pNamedRangeObj)
+ {
+ sTempContent = aItr->sContent;
+ // Get rid of leading sheet dots in simple ranges.
+ if (!aItr->bIsExpression)
+ ScXMLConverter::ParseFormula( sTempContent, false);
+ pNamedRangeObj->SetContentWithGrammar( sTempContent, aItr->eGrammar);
+ }
+ }
+ }
+ aItr = pNamedExpressions->erase(aItr);
+ }
+}
+
+namespace {
+
+class SheetRangeNameInserter : public ::std::unary_function<ScMyNamedExpression, void>
+{
+ ScDocument* mpDoc;
+ ScRangeName& mrRangeName;
+public:
+ SheetRangeNameInserter(ScDocument* pDoc, ScRangeName& rRangeName) :
+ mpDoc(pDoc), mrRangeName(rRangeName) {}
+
+ void operator() (const ScMyNamedExpression& r) const
+ {
+ using namespace formula;
+
+ if (r.sRangeType.getLength() > 0)
+ // For now, we only accept normal named expressions.
+ return;
+
+ if (mpDoc && !mrRangeName.findByName(r.sName))
+ {
+ // Insert a new name.
+ ScAddress aPos;
+ sal_Int32 nOffset = 0;
+ bool bSuccess = ScRangeStringConverter::GetAddressFromString(
+ aPos, r.sBaseCellAddress, mpDoc, FormulaGrammar::CONV_OOO, nOffset);
+
+ if (bSuccess)
+ {
+ ::rtl::OUString aContent = r.sContent;
+ if (!r.bIsExpression)
+ ScXMLConverter::ParseFormula(aContent, false);
+
+ ScRangeData* pData = new ScRangeData(
+ mpDoc, r.sName, r.sContent, aPos, RT_NAME, r.eGrammar);
+ mrRangeName.insert(pData);
+ }
+ }
+ }
+};
+
+}
+
+void ScXMLImport::SetSheetNamedRanges()
+{
+ if (!pDoc)
+ return;
+
+ SheetNamedExpMap::const_iterator itr = maSheetNamedExpressions.begin(), itrEnd = maSheetNamedExpressions.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ SCTAB nTab = itr->first;
+ ScRangeName* pRangeNames = pDoc->GetRangeName(nTab);
+ if (!pRangeNames)
+ continue;
+
+ const ScMyNamedExpressions& rNames = *itr->second;
+ ::std::for_each(rNames.begin(), rNames.end(), SheetRangeNameInserter(pDoc, *pRangeNames));
+ }
+}
+
+void SAL_CALL ScXMLImport::endDocument(void)
+throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ if (getImportFlags() & IMPORT_CONTENT)
+ {
+ if (GetModel().is())
+ {
+ uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
+ if (xViewDataSupplier.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
+ if (xIndexAccess.is() && xIndexAccess->getCount() > 0)
+ {
+ uno::Sequence< beans::PropertyValue > aSeq;
+ if (xIndexAccess->getByIndex(0) >>= aSeq)
+ {
+ sal_Int32 nCount (aSeq.getLength());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rtl::OUString sName(aSeq[i].Name);
+ if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
+ {
+ rtl::OUString sValue;
+ if(aSeq[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab(0);
+ if (pDoc->GetTable(sTabName, nTab))
+ {
+ pDoc->SetVisibleTab(nTab);
+ i = nCount;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ SetLabelRanges();
+ SetNamedRanges();
+ SetSheetNamedRanges();
+ }
+ GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
+ if (pDoc)
+ pDoc->CompileXML();
+
+ if (pDoc && GetModel().is())
+ {
+ // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
+ // in UpdateRowHeights can already clear the flags again)
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (!pSheetData->IsSheetBlocked( nTab ))
+ pDoc->SetStreamValid( nTab, sal_True );
+ }
+
+ aTables.UpdateRowHeights();
+ aTables.FixupOLEs();
+ }
+ if (GetModel().is())
+ {
+ uno::Reference<document::XActionLockable> xActionLockable(GetModel(), uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->removeActionLock();
+ }
+ SvXMLImport::endDocument();
+
+ if (pDoc && bSelfImportingXMLSet)
+ {
+ ScModelObj::getImplementation(GetModel())->AfterXMLLoading(sal_True);
+ }
+}
+
+// XEventListener
+void ScXMLImport::DisposingModel()
+{
+ SvXMLImport::DisposingModel();
+ pDoc = NULL;
+}
+
+ScXMLImport::MutexGuard::MutexGuard(ScXMLImport& rImport) :
+ mrImport(rImport)
+{
+ mrImport.LockSolarMutex();
+}
+
+ScXMLImport::MutexGuard::~MutexGuard()
+{
+ mrImport.UnlockSolarMutex();
+}
+
+void ScXMLImport::LockSolarMutex()
+{
+ // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
+ // so there's no need to allocate (and later delete) the SolarMutexGuard.
+ if (bFromWrapper)
+ {
+ DBG_TESTSOLARMUTEX();
+ return;
+ }
+
+ if (nSolarMutexLocked == 0)
+ {
+ DBG_ASSERT(!pSolarMutexGuard, "Solar Mutex is locked");
+ pSolarMutexGuard = new SolarMutexGuard();
+ }
+ ++nSolarMutexLocked;
+}
+
+
+void ScXMLImport::UnlockSolarMutex()
+{
+ if (nSolarMutexLocked > 0)
+ {
+ nSolarMutexLocked--;
+ if (nSolarMutexLocked == 0)
+ {
+ DBG_ASSERT(pSolarMutexGuard, "Solar Mutex is always unlocked");
+ delete pSolarMutexGuard;
+ pSolarMutexGuard = NULL;
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::GetByteOffset()
+{
+ sal_Int32 nOffset = -1;
+ uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
+ uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface
+ if ( xSeek.is() )
+ nOffset = (sal_Int32)xSeek->getPosition();
+ return nOffset;
+}
+
+void ScXMLImport::SetRangeOverflowType(sal_uInt32 nType)
+{
+ // #i31130# Overflow is stored in the document, because the ScXMLImport object
+ // isn't available in ScXMLImportWrapper::ImportFromComponent when using the
+ // OOo->Oasis transformation.
+
+ if ( pDoc )
+ pDoc->SetRangeOverflowType( nType );
+}
+
+void ScXMLImport::ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc)
+{
+ nProgressCount += nInc;
+ if (bEditCell || nProgressCount > 100)
+ {
+ GetProgressBarHelper()->Increment(nProgressCount);
+ nProgressCount = 0;
+ }
+}
+
+sal_Int32 ScXMLImport::GetVisibleSheet()
+{
+ // Get the visible sheet number from model's view data (after settings were loaded),
+ // or 0 (default: first sheet) if no settings available.
+
+ uno::Reference<document::XViewDataSupplier> xSupp(GetModel(), uno::UNO_QUERY);
+ if (xSupp.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndex = xSupp->getViewData();
+ if ( xIndex.is() && xIndex->getCount() > 0 )
+ {
+ uno::Any aAny( xIndex->getByIndex(0) );
+ uno::Sequence<beans::PropertyValue> aViewSettings; // settings for (first) view
+ if ( aAny >>= aViewSettings )
+ {
+ sal_Int32 nCount = aViewSettings.getLength();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ if ( aViewSettings[i].Name.compareToAscii(SC_ACTIVETABLE) == 0 )
+ {
+ rtl::OUString sValue;
+ if(aViewSettings[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab = 0;
+ if (pDoc->GetTable(sTabName, nTab))
+ return nTab;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void ScXMLImport::ExtractFormulaNamespaceGrammar(
+ OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
+{
+ // parse the attribute value, extract namespace ID, literal namespace, and formula string
+ rFormulaNmsp = OUString();
+ sal_uInt16 nNsId = GetNamespaceMap()._GetKeyByAttrName( rAttrValue, 0, &rFormula, &rFormulaNmsp, false );
+
+ // check if we have an ODF formula namespace
+ if( !bRestrictToExternalNmsp ) switch( nNsId )
+ {
+ case XML_NAMESPACE_OOOC:
+ rFormulaNmsp = OUString(); // remove namespace string for built-in grammar
+ reGrammar = FormulaGrammar::GRAM_PODF;
+ return;
+ case XML_NAMESPACE_OF:
+ rFormulaNmsp = OUString(); // remove namespace string for built-in grammar
+ reGrammar = FormulaGrammar::GRAM_ODFF;
+ return;
+ }
+
+ /* Find default grammar for formulas without namespace. There may be
+ documents in the wild that stored no namespace in ODF 1.0/1.1. Use
+ GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
+ 1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
+ FormulaGrammar::Grammar eDefaultGrammar =
+ (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ?
+ FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF;
+
+ /* Check if we have no namespace at all. The value XML_NAMESPACE_NONE
+ indicates that there is no colon. If the first character of the
+ attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
+ indicates that there is a colon somewhere in the formula string. */
+ if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) )
+ {
+ rFormula = rAttrValue; // return entire string as formula
+ reGrammar = eDefaultGrammar;
+ return;
+ }
+
+ /* Check if a namespace URL could be resolved from the attribute value.
+ Use that namespace only, if the Calc document knows an associated
+ external formula parser. This prevents that the range operator in
+ conjunction with defined names is confused as namespaces prefix, e.g.
+ in the expression 'table:A1' where 'table' is a named reference. */
+ if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && (rFormulaNmsp.getLength() > 0) &&
+ GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) )
+ {
+ reGrammar = FormulaGrammar::GRAM_EXTERNAL;
+ return;
+ }
+
+ /* All attempts failed (e.g. no namespace and no leading equality sign, or
+ an invalid namespace prefix), continue with the entire attribute value. */
+ rFormula = rAttrValue;
+ rFormulaNmsp = OUString(); // remove any namespace string
+ reGrammar = eDefaultGrammar;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
new file mode 100644
index 000000000000..61565dd5a30e
--- /dev/null
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -0,0 +1,1061 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLIMPRT_HXX
+#define SC_XMLIMPRT_HXX
+
+#include <rsc/rscsfx.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/xmlstyle.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <tools/time.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include "xmlsubti.hxx"
+#include "global.hxx"
+#include "formula/grammar.hxx"
+
+#include "xmlstyle.hxx"
+#include "XMLDetectiveContext.hxx"
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+
+#include <vector>
+#include <boost/unordered_map.hpp>
+#include <boost/ptr_container/ptr_list.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+class ScRangeList;
+class ScMyStyleNumberFormats;
+class XMLNumberFormatAttributesExportHelper;
+
+enum ScXMLDocTokens
+{
+ XML_TOK_DOC_FONTDECLS,
+ XML_TOK_DOC_STYLES,
+ XML_TOK_DOC_AUTOSTYLES,
+ XML_TOK_DOC_MASTERSTYLES,
+ XML_TOK_DOC_META,
+ XML_TOK_DOC_SCRIPTS,
+ XML_TOK_DOC_BODY,
+ XML_TOK_DOC_SETTINGS,
+ XML_TOK_OFFICE_END=XML_TOK_UNKNOWN
+};
+
+enum ScXMLStylesTokens
+{
+ XML_TOK_STYLES_STYLE
+};
+
+enum ScXMLStylesAttrTokens
+{
+ XML_TOK_STYLES_STYLE_NAME,
+ XML_TOK_STYLES_STYLE_FAMILY,
+ XML_TOK_STYLES_STYLE_PARENT_STYLE_NAME
+};
+
+enum ScXMLStyleTokens
+{
+ XML_TOK_STYLE_PROPERTIES
+};
+
+enum ScXMLBodyTokens
+{
+ XML_TOK_BODY_TRACKED_CHANGES,
+ XML_TOK_BODY_CALCULATION_SETTINGS,
+ XML_TOK_BODY_CONTENT_VALIDATIONS,
+ XML_TOK_BODY_LABEL_RANGES,
+ XML_TOK_BODY_TABLE,
+ XML_TOK_BODY_NAMED_EXPRESSIONS,
+ XML_TOK_BODY_DATABASE_RANGES,
+ XML_TOK_BODY_DATABASE_RANGE,
+ XML_TOK_BODY_DATA_PILOT_TABLES,
+ XML_TOK_BODY_CONSOLIDATION,
+ XML_TOK_BODY_DDE_LINKS
+};
+
+enum ScXMLContentValidationsElemTokens
+{
+ XML_TOK_CONTENT_VALIDATION
+};
+
+enum ScXMLContentValidationElemTokens
+{
+ XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE,
+ XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE,
+ XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO,
+ XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS
+};
+
+enum ScXMLContentValidationAttrTokens
+{
+ XML_TOK_CONTENT_VALIDATION_NAME,
+ XML_TOK_CONTENT_VALIDATION_CONDITION,
+ XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS,
+ XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL,
+ XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST
+};
+
+enum ScXMLContentValidationMessageElemTokens
+{
+ XML_TOK_P
+};
+
+enum ScXMLContentValidationHelpMessageAttrTokens
+{
+ XML_TOK_HELP_MESSAGE_ATTR_TITLE,
+ XML_TOK_HELP_MESSAGE_ATTR_DISPLAY
+};
+
+enum ScXMLContentValidationErrorMessageAttrTokens
+{
+ XML_TOK_ERROR_MESSAGE_ATTR_TITLE,
+ XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY,
+ XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE
+};
+
+enum ScXMLContentValidationErrorMacroAttrTokens
+{
+ XML_TOK_ERROR_MACRO_ATTR_NAME,
+ XML_TOK_ERROR_MACRO_ATTR_EXECUTE
+};
+
+enum ScXMLLabelRangesElemTokens
+{
+ XML_TOK_LABEL_RANGE_ELEM
+};
+
+enum ScXMLLabelRangeAttrTokens
+{
+ XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE,
+ XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE,
+ XML_TOK_LABEL_RANGE_ATTR_ORIENTATION
+};
+
+enum ScXMLTableTokens
+{
+ XML_TOK_TABLE_NAMED_EXPRESSIONS,
+ XML_TOK_TABLE_COL_GROUP,
+ XML_TOK_TABLE_HEADER_COLS,
+ XML_TOK_TABLE_COLS,
+ XML_TOK_TABLE_COL,
+ XML_TOK_TABLE_ROW_GROUP,
+ XML_TOK_TABLE_HEADER_ROWS,
+ XML_TOK_TABLE_PROTECTION,
+ XML_TOK_TABLE_ROWS,
+ XML_TOK_TABLE_ROW,
+ XML_TOK_TABLE_SOURCE,
+ XML_TOK_TABLE_SCENARIO,
+ XML_TOK_TABLE_SHAPES,
+ XML_TOK_TABLE_FORMS,
+ XML_TOK_TABLE_EVENT_LISTENERS,
+ XML_TOK_TABLE_EVENT_LISTENERS_EXT
+};
+
+enum ScXMLTokenProtectionTokens
+{
+ XML_TOK_TABLE_SELECT_PROTECTED_CELLS,
+ XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS
+};
+
+enum ScXMLTableRowsTokens
+{
+ XML_TOK_TABLE_ROWS_ROW_GROUP,
+ XML_TOK_TABLE_ROWS_HEADER_ROWS,
+ XML_TOK_TABLE_ROWS_ROWS,
+ XML_TOK_TABLE_ROWS_ROW
+};
+
+enum ScXMLTableColsTokens
+{
+ XML_TOK_TABLE_COLS_COL_GROUP,
+ XML_TOK_TABLE_COLS_HEADER_COLS,
+ XML_TOK_TABLE_COLS_COLS,
+ XML_TOK_TABLE_COLS_COL
+};
+
+enum ScXMLTableAttrTokens
+{
+ XML_TOK_TABLE_NAME,
+ XML_TOK_TABLE_STYLE_NAME,
+ XML_TOK_TABLE_PROTECTED,
+ XML_TOK_TABLE_PRINT_RANGES,
+ XML_TOK_TABLE_PASSWORD,
+ XML_TOK_TABLE_PASSHASH,
+ XML_TOK_TABLE_PASSHASH_2,
+ XML_TOK_TABLE_PRINT
+};
+
+enum ScXMLTableScenarioAttrTokens
+{
+ XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER,
+ XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES,
+ XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS,
+ XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE,
+ XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES,
+ XML_TOK_TABLE_SCENARIO_ATTR_COMMENT,
+ XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED
+};
+
+enum ScXMLTableColAttrTokens
+{
+ XML_TOK_TABLE_COL_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_COL_ATTR_REPEATED,
+ XML_TOK_TABLE_COL_ATTR_VISIBILITY,
+ XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME
+};
+
+enum ScXMLTableRowTokens
+{
+ XML_TOK_TABLE_ROW_CELL,
+ XML_TOK_TABLE_ROW_COVERED_CELL
+};
+
+enum ScXMLTableRowAttrTokens
+{
+ XML_TOK_TABLE_ROW_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_ROW_ATTR_VISIBILITY,
+ XML_TOK_TABLE_ROW_ATTR_REPEATED,
+ XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME
+// XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT
+};
+
+enum ScXMLTableRowCellTokens
+{
+ XML_TOK_TABLE_ROW_CELL_P,
+ XML_TOK_TABLE_ROW_CELL_TABLE,
+ XML_TOK_TABLE_ROW_CELL_ANNOTATION,
+ XML_TOK_TABLE_ROW_CELL_DETECTIVE,
+ XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE
+};
+
+enum ScXMLTableRowCellAttrTokens
+{
+ XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME,
+ XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS,
+ XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED,
+ XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE,
+ XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA,
+ XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY
+};
+
+enum ScXMLAnnotationAttrTokens
+{
+ XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR,
+ XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE,
+ XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING,
+ XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY,
+ XML_TOK_TABLE_ANNOTATION_ATTR_X,
+ XML_TOK_TABLE_ANNOTATION_ATTR_Y
+};
+
+enum ScXMLDetectiveElemTokens
+{
+ XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED,
+ XML_TOK_DETECTIVE_ELEM_OPERATION
+};
+
+enum ScXMLDetectiveHighlightedAttrTokens
+{
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR,
+ XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID
+};
+
+enum ScXMLDetectiveOperationAttrTokens
+{
+ XML_TOK_DETECTIVE_OPERATION_ATTR_NAME,
+ XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX
+};
+
+enum ScXMLCellRangeSourceAttrTokens
+{
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW,
+ XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY
+};
+
+enum ScXMLNamedExpressionsTokens
+{
+ XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE,
+ XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION
+};
+
+enum ScXMLNamedRangeAttrTokens
+{
+ XML_TOK_NAMED_RANGE_ATTR_NAME,
+ XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS,
+ XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS,
+ XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS
+};
+
+enum ScXMLNamedExpressionAttrTokens
+{
+ XML_TOK_NAMED_EXPRESSION_ATTR_NAME,
+ XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS,
+ XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION
+};
+
+enum ScXMLDatabaseRangesTokens
+{
+ XML_TOK_DATABASE_RANGE
+};
+
+enum ScXMLDatabaseRangeTokens
+{
+ XML_TOK_DATABASE_RANGE_SOURCE_SQL,
+ XML_TOK_DATABASE_RANGE_SOURCE_TABLE,
+ XML_TOK_DATABASE_RANGE_SOURCE_QUERY,
+ XML_TOK_FILTER,
+ XML_TOK_SORT,
+ XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES
+};
+
+enum ScXMLDatabaseRangeAttrTokens
+{
+ XML_TOK_DATABASE_RANGE_ATTR_NAME,
+ XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION,
+ XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES,
+ XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE,
+ XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA,
+ XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION,
+ XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER,
+ XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS,
+ XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY
+};
+
+enum ScXMLDatabaseRangeSourceSQLAttrTokens
+{
+ XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_SQL_ATTR_HREF,
+ XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT,
+ XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT
+};
+
+enum ScXMLDatabaseRangeSourceTableAttrTokens
+{
+ XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_TABLE_ATTR_HREF,
+ XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME
+};
+
+enum ScXMLDatabaseRangeSourceQueryAttrTokens
+{
+ XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME,
+ XML_TOK_SOURCE_QUERY_ATTR_HREF,
+ XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE,
+ XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME
+};
+
+enum ScXMLFilterTokens
+{
+ XML_TOK_FILTER_AND,
+ XML_TOK_FILTER_OR,
+ XML_TOK_FILTER_CONDITION
+};
+
+enum ScXMLFilterAttrTokens
+{
+ XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS,
+ XML_TOK_FILTER_ATTR_CONDITION_SOURCE,
+ XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES
+};
+
+enum ScXMLFilterConditionAttrTokens
+{
+ XML_TOK_CONDITION_ATTR_FIELD_NUMBER,
+ XML_TOK_CONDITION_ATTR_CASE_SENSITIVE,
+ XML_TOK_CONDITION_ATTR_DATA_TYPE,
+ XML_TOK_CONDITION_ATTR_VALUE,
+ XML_TOK_CONDITION_ATTR_OPERATOR
+};
+
+enum ScXMLSortTokens
+{
+ XML_TOK_SORT_SORT_BY
+};
+
+enum ScXMLSortAttrTokens
+{
+ XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT,
+ XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_SORT_ATTR_CASE_SENSITIVE,
+ XML_TOK_SORT_ATTR_LANGUAGE,
+ XML_TOK_SORT_ATTR_COUNTRY,
+ XML_TOK_SORT_ATTR_ALGORITHM
+};
+
+enum ScXMLSortSortByAttrTokens
+{
+ XML_TOK_SORT_BY_ATTR_FIELD_NUMBER,
+ XML_TOK_SORT_BY_ATTR_DATA_TYPE,
+ XML_TOK_SORT_BY_ATTR_ORDER
+};
+
+enum ScXMLDatabaseRangeSubTotalRulesTokens
+{
+ XML_TOK_SUBTOTAL_RULES_SORT_GROUPS,
+ XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE
+};
+
+enum ScXMLDatabaseRangeSubTotalRulesAttrTokens
+{
+ XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT,
+ XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE,
+ XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE
+};
+
+enum ScXMLSubTotalRulesSortGroupsAttrTokens
+{
+ XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE,
+ XML_TOK_SORT_GROUPS_ATTR_ORDER
+};
+
+enum ScXMLSubTotalRulesSubTotalRuleTokens
+{
+ XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD
+};
+
+enum ScXMLSubTotalRulesSubTotalRuleAttrTokens
+{
+ XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER
+};
+
+enum ScXMLSubTotalRuleSubTotalField
+{
+ XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER,
+ XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION
+};
+
+enum ScXMLDataPilotTablesElemTokens
+{
+ XML_TOK_DATA_PILOT_TABLE
+};
+
+enum ScXMLDataPilotTableAttrTokens
+{
+ XML_TOK_DATA_PILOT_TABLE_ATTR_NAME,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN,
+ XML_TOK_DATA_PILOT_TABLE_ATTR_HEADER_GRID_LAYOUT
+};
+
+enum ScXMLDataPilotTableElemTokens
+{
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD
+};
+
+enum ScXMLDataPilotTableSourceServiceAttrTokens
+{
+ XML_TOK_SOURCE_SERVICE_ATTR_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME,
+ XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD
+};
+
+enum ScXMLDataPilotGrandTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT
+};
+
+enum ScXMLDataPilotTableSourceCellRangeElemTokens
+{
+ XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER
+};
+
+enum ScXMLDataPilotTableSourceCellRangeAttrTokens
+{
+ XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS,
+ XML_TOK_SOURCE_CELL_RANGE_ATTR_NAME
+};
+
+enum ScXMLDataPilotFieldAttrTokens
+{
+ XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY
+};
+
+enum ScXMLDataPilotFieldElemTokens
+{
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS
+};
+
+enum ScXMLDataPilotLevelAttrTokens
+{
+ XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY
+};
+
+enum ScXMLDataPilotLevelElemTokens
+{
+ XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS,
+ XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO,
+ XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO
+};
+
+enum ScXMLDataPilotSubTotalsElemTokens
+{
+ XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL
+};
+
+enum ScXMLDataPilotSubTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT
+};
+
+enum ScXMLDataPilotMembersElemTokens
+{
+ XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER
+};
+
+enum ScXMLDataPilotMemberAttrTokens
+{
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS
+};
+
+enum ScXMLConsolidationAttrTokens
+{
+ XML_TOK_CONSOLIDATION_ATTR_FUNCTION,
+ XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES,
+ XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS,
+ XML_TOK_CONSOLIDATION_ATTR_USE_LABEL,
+ XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE
+};
+
+
+class SvI18NMap;
+class SvXMLTokenMap;
+//class SvXMLImportItemMapper;
+class SvXMLStyleContext;
+class SfxItemSet;
+class SvXMLNumFmtHelper;
+class XMLShapeImportHelper;
+class ScXMLChangeTrackingImportHelper;
+class SolarMutexGuard;
+
+struct tScMyCellRange
+{
+ sal_Int16 Sheet;
+ sal_Int32 StartColumn, EndColumn;
+ sal_Int32 StartRow, EndRow;
+};
+
+struct ScMyNamedExpression
+{
+ rtl::OUString sName;
+ rtl::OUString sContent;
+ rtl::OUString sContentNmsp;
+ rtl::OUString sBaseCellAddress;
+ rtl::OUString sRangeType;
+ formula::FormulaGrammar::Grammar eGrammar;
+ sal_Bool bIsExpression;
+};
+
+typedef ::boost::ptr_list<ScMyNamedExpression> ScMyNamedExpressions;
+
+struct ScMyLabelRange
+{
+ rtl::OUString sLabelRangeStr;
+ rtl::OUString sDataRangeStr;
+ sal_Bool bColumnOrientation;
+};
+
+typedef std::list<const ScMyLabelRange*> ScMyLabelRanges;
+
+struct ScMyImportValidation
+{
+ rtl::OUString sName;
+ rtl::OUString sImputTitle;
+ rtl::OUString sImputMessage;
+ rtl::OUString sErrorTitle;
+ rtl::OUString sErrorMessage;
+ rtl::OUString sFormula1;
+ rtl::OUString sFormula2;
+ rtl::OUString sFormulaNmsp1;
+ rtl::OUString sFormulaNmsp2;
+ rtl::OUString sBaseCellAddress; // string is used directly
+ com::sun::star::sheet::ValidationAlertStyle aAlertStyle;
+ com::sun::star::sheet::ValidationType aValidationType;
+ com::sun::star::sheet::ConditionOperator aOperator;
+ formula::FormulaGrammar::Grammar eGrammar1;
+ formula::FormulaGrammar::Grammar eGrammar2;
+ sal_Int16 nShowList;
+ sal_Bool bShowErrorMessage;
+ sal_Bool bShowImputMessage;
+ sal_Bool bIgnoreBlanks;
+};
+
+typedef std::vector<ScMyImportValidation> ScMyImportValidations;
+typedef std::list<SvXMLImportContext*> ScMyViewContextList;
+class ScMyStylesImportHelper;
+
+class ScXMLImport: public SvXMLImport
+{
+ typedef ::boost::unordered_map< ::rtl::OUString, sal_Int16, ::rtl::OUStringHash > CellTypeMap;
+ typedef ::boost::ptr_map<SCTAB, ScMyNamedExpressions> SheetNamedExpMap;
+
+ CellTypeMap aCellTypeMap;
+
+ ScDocument* pDoc;
+ ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
+ ScMyViewContextList aViewContextList;
+ ScMyStylesImportHelper* pStylesImportHelper;
+ rtl::OUString sNumberFormat;
+ rtl::OUString sLocale;
+ rtl::OUString sCellStyle;
+ rtl::OUString sStandardFormat;
+ rtl::OUString sType;
+
+ UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory;
+ UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper;
+ UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper;
+
+ SvXMLTokenMap *pDocElemTokenMap;
+ SvXMLTokenMap *pStylesElemTokenMap;
+ SvXMLTokenMap *pStylesAttrTokenMap;
+ SvXMLTokenMap *pStyleElemTokenMap;
+ SvXMLTokenMap *pBodyElemTokenMap;
+ SvXMLTokenMap *pContentValidationsElemTokenMap;
+ SvXMLTokenMap *pContentValidationElemTokenMap;
+ SvXMLTokenMap *pContentValidationAttrTokenMap;
+ SvXMLTokenMap *pContentValidationMessageElemTokenMap;
+ SvXMLTokenMap *pContentValidationHelpMessageAttrTokenMap;
+ SvXMLTokenMap *pContentValidationErrorMessageAttrTokenMap;
+ SvXMLTokenMap *pContentValidationErrorMacroAttrTokenMap;
+ SvXMLTokenMap *pLabelRangesElemTokenMap;
+ SvXMLTokenMap *pLabelRangeAttrTokenMap;
+ SvXMLTokenMap *pTableElemTokenMap;
+ SvXMLTokenMap *pTableProtectionElemTokenMap;
+ SvXMLTokenMap *pTableRowsElemTokenMap;
+ SvXMLTokenMap *pTableColsElemTokenMap;
+ SvXMLTokenMap *pTableScenarioAttrTokenMap;
+ SvXMLTokenMap *pTableAttrTokenMap;
+ SvXMLTokenMap *pTableColAttrTokenMap;
+ SvXMLTokenMap *pTableRowElemTokenMap;
+ SvXMLTokenMap *pTableRowAttrTokenMap;
+ SvXMLTokenMap *pTableRowCellElemTokenMap;
+ SvXMLTokenMap *pTableRowCellAttrTokenMap;
+ SvXMLTokenMap *pTableAnnotationAttrTokenMap;
+ SvXMLTokenMap *pDetectiveElemTokenMap;
+ SvXMLTokenMap *pDetectiveHighlightedAttrTokenMap;
+ SvXMLTokenMap *pDetectiveOperationAttrTokenMap;
+ SvXMLTokenMap *pTableCellRangeSourceAttrTokenMap;
+ SvXMLTokenMap *pNamedExpressionsElemTokenMap;
+ SvXMLTokenMap *pNamedRangeAttrTokenMap;
+ SvXMLTokenMap *pNamedExpressionAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangesElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceSQLAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceTableAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSourceQueryAttrTokenMap;
+ SvXMLTokenMap *pFilterElemTokenMap;
+ SvXMLTokenMap *pFilterAttrTokenMap;
+ SvXMLTokenMap *pFilterConditionAttrTokenMap;
+ SvXMLTokenMap *pSortElemTokenMap;
+ SvXMLTokenMap *pSortAttrTokenMap;
+ SvXMLTokenMap *pSortSortByAttrTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSubTotalRulesElemTokenMap;
+ SvXMLTokenMap *pDatabaseRangeSubTotalRulesAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSortGroupsAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSubTotalRuleElemTokenMap;
+ SvXMLTokenMap *pSubTotalRulesSubTotalRuleAttrTokenMap;
+ SvXMLTokenMap *pSubTotalRuleSubTotalFieldAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTablesElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTableElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap;
+ SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap;
+ SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap;
+ SvXMLTokenMap *pDataPilotFieldAttrTokenMap;
+ SvXMLTokenMap *pDataPilotFieldElemTokenMap;
+ SvXMLTokenMap *pDataPilotLevelAttrTokenMap;
+ SvXMLTokenMap *pDataPilotLevelElemTokenMap;
+ SvXMLTokenMap *pDataPilotSubTotalsElemTokenMap;
+ SvXMLTokenMap *pDataPilotSubTotalAttrTokenMap;
+ SvXMLTokenMap *pDataPilotMembersElemTokenMap;
+ SvXMLTokenMap *pDataPilotMemberAttrTokenMap;
+ SvXMLTokenMap *pConsolidationAttrTokenMap;
+
+ ScMyTables aTables;
+
+ ScMyNamedExpressions* pMyNamedExpressions;
+ SheetNamedExpMap maSheetNamedExpressions;
+
+ ScMyLabelRanges* pMyLabelRanges;
+ ScMyImportValidations* pValidations;
+ ScMyImpDetectiveOpArray* pDetectiveOpArray;
+ SolarMutexGuard* pSolarMutexGuard;
+
+ std::vector<rtl::OUString> aTableStyles;
+ XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper;
+ ScMyStyleNumberFormats* pStyleNumberFormats;
+ com::sun::star::uno::Reference <com::sun::star::util::XNumberFormats> xNumberFormats;
+ com::sun::star::uno::Reference <com::sun::star::util::XNumberFormatTypes> xNumberFormatTypes;
+
+ com::sun::star::uno::Reference <com::sun::star::sheet::XSheetCellRangeContainer> xSheetCellRanges;
+
+ rtl::OUString sEmpty;
+ rtl::OUString sPrevStyleName;
+ rtl::OUString sPrevCurrency;
+ sal_uInt32 nSolarMutexLocked;
+ sal_Int32 nProgressCount;
+ sal_uInt16 nStyleFamilyMask;// Mask of styles to load
+ sal_Int16 nPrevCellType;
+ sal_Bool bLoadDoc; // Load doc or styles only
+ sal_Bool bRemoveLastChar;
+ sal_Bool bNullDateSetted;
+ sal_Bool bSelfImportingXMLSet;
+ sal_Bool bLatinDefaultStyle; // latin-only number format in default style?
+ sal_Bool bFromWrapper; // called from ScDocShell / ScXMLImportWrapper?
+
+
+protected:
+
+ // This method is called after the namespace map has been updated, but
+ // before a context for the current element has been pushed.
+ virtual SvXMLImportContext *CreateContext(sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+ virtual XMLShapeImportHelper* CreateShapeImport();
+
+public:
+ // #110680#
+ ScXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const sal_uInt16 nImportFlag);
+
+ ~ScXMLImport() throw();
+
+ // namespace office
+ // NB: in contrast to other CreateFooContexts, this particular one handles
+ // the root element (i.e. office:document-meta)
+ SvXMLImportContext *CreateMetaContext(
+ const ::rtl::OUString& rLocalName );
+ SvXMLImportContext *CreateFontDeclsContext(const sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
+ const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList);
+ SvXMLImportContext *CreateScriptContext(
+ const ::rtl::OUString& rLocalName );
+ SvXMLImportContext *CreateStylesContext(const ::rtl::OUString& rLocalName,
+ const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList, sal_Bool bAutoStyles );
+ SvXMLImportContext *CreateBodyContext(
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void SetStatistics(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue> & i_rStats);
+
+ inline ScDocument* GetDocument() { return pDoc; }
+ inline const ScDocument* GetDocument() const { return pDoc; }
+
+ ScMyTables& GetTables() { return aTables; }
+
+ sal_uInt16 GetStyleFamilyMask() const { return nStyleFamilyMask; }
+ sal_Bool IsStylesOnlyMode() const { return !bLoadDoc; }
+
+ sal_Bool IsLatinDefaultStyle() const { return bLatinDefaultStyle; }
+
+ sal_Int16 GetCellType(const ::rtl::OUString& rStrValue) const;
+
+ UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() const { return xCellStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetColumnStylesPropertySetMapper() const { return xColumnStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetRowStylesPropertySetMapper() const { return xRowStylesPropertySetMapper; }
+ UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() const { return xTableStylesPropertySetMapper; }
+
+ const SvXMLTokenMap& GetDocElemTokenMap();
+ const SvXMLTokenMap& GetBodyElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationsElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationMessageElemTokenMap();
+ const SvXMLTokenMap& GetContentValidationHelpMessageAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationErrorMessageAttrTokenMap();
+ const SvXMLTokenMap& GetContentValidationErrorMacroAttrTokenMap();
+ const SvXMLTokenMap& GetLabelRangesElemTokenMap();
+ const SvXMLTokenMap& GetLabelRangeAttrTokenMap();
+ const SvXMLTokenMap& GetTableElemTokenMap();
+ const SvXMLTokenMap& GetTableProtectionAttrTokenMap();
+ const SvXMLTokenMap& GetTableRowsElemTokenMap();
+ const SvXMLTokenMap& GetTableColsElemTokenMap();
+ const SvXMLTokenMap& GetTableAttrTokenMap();
+ const SvXMLTokenMap& GetTableScenarioAttrTokenMap();
+ const SvXMLTokenMap& GetTableColAttrTokenMap();
+ const SvXMLTokenMap& GetTableRowElemTokenMap();
+ const SvXMLTokenMap& GetTableRowAttrTokenMap();
+ const SvXMLTokenMap& GetTableRowCellElemTokenMap();
+ const SvXMLTokenMap& GetTableRowCellAttrTokenMap();
+ const SvXMLTokenMap& GetTableAnnotationAttrTokenMap();
+ const SvXMLTokenMap& GetDetectiveElemTokenMap();
+ const SvXMLTokenMap& GetDetectiveHighlightedAttrTokenMap();
+ const SvXMLTokenMap& GetDetectiveOperationAttrTokenMap();
+ const SvXMLTokenMap& GetTableCellRangeSourceAttrTokenMap();
+ const SvXMLTokenMap& GetNamedExpressionsElemTokenMap();
+ const SvXMLTokenMap& GetNamedRangeAttrTokenMap();
+ const SvXMLTokenMap& GetNamedExpressionAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangesElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceSQLAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceTableAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSourceQueryAttrTokenMap();
+ const SvXMLTokenMap& GetFilterElemTokenMap();
+ const SvXMLTokenMap& GetFilterAttrTokenMap();
+ const SvXMLTokenMap& GetFilterConditionAttrTokenMap();
+ const SvXMLTokenMap& GetSortElemTokenMap();
+ const SvXMLTokenMap& GetSortAttrTokenMap();
+ const SvXMLTokenMap& GetSortSortByAttrTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesElemTokenMap();
+ const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSortGroupsAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleElemTokenMap();
+ const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleAttrTokenMap();
+ const SvXMLTokenMap& GetSubTotalRuleSubTotalFieldAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTablesElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotFieldElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotLevelAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotLevelElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotSubTotalsElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotSubTotalAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotMembersElemTokenMap();
+ const SvXMLTokenMap& GetDataPilotMemberAttrTokenMap();
+ const SvXMLTokenMap& GetConsolidationAttrTokenMap();
+
+ void AddNamedExpression(ScMyNamedExpression* pMyNamedExpression)
+ {
+ if (!pMyNamedExpressions)
+ pMyNamedExpressions = new ScMyNamedExpressions();
+ pMyNamedExpressions->push_back(pMyNamedExpression);
+ }
+
+ ScMyNamedExpressions* GetNamedExpressions() { return pMyNamedExpressions; }
+
+ void AddNamedExpression(SCTAB nTab, ScMyNamedExpression* pNamedExp);
+
+ void AddLabelRange(const ScMyLabelRange* pMyLabelRange) {
+ if (!pMyLabelRanges)
+ pMyLabelRanges = new ScMyLabelRanges();
+ pMyLabelRanges->push_back(pMyLabelRange); }
+ ScMyLabelRanges* GetLabelRanges() { return pMyLabelRanges; }
+
+ void AddValidation(const ScMyImportValidation& rValidation) {
+ if (!pValidations)
+ pValidations = new ScMyImportValidations();
+ pValidations->push_back(rValidation); }
+ sal_Bool GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation);
+
+ inline ScMyImpDetectiveOpArray* GetDetectiveOpArray() {
+ if (!pDetectiveOpArray)
+ pDetectiveOpArray = new ScMyImpDetectiveOpArray();
+ return pDetectiveOpArray; }
+
+ void SetRemoveLastChar(sal_Bool bValue) { bRemoveLastChar = bValue; }
+ sal_Bool GetRemoveLastChar() { return bRemoveLastChar; }
+
+ ScXMLChangeTrackingImportHelper* GetChangeTrackingImportHelper();
+ void AddViewContext(SvXMLImportContext* pContext) { aViewContextList.push_back(pContext); }
+ void InsertStyles();
+
+ void SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps);
+ virtual void SetViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps);
+ virtual void SetConfigurationSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aConfigProps);
+
+ void SetTableStyle(const rtl::OUString& rValue) { aTableStyles.push_back(rValue); }
+ std::vector<rtl::OUString> GetTableStyle() { return aTableStyles; }
+ ScMyStylesImportHelper* GetStylesImportHelper() { return pStylesImportHelper; }
+ sal_Int32 SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency);
+ sal_Bool IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrencySymbol, const rtl::OUString& sBankSymbol);
+ void SetType(com::sun::star::uno::Reference <com::sun::star::beans::XPropertySet>& rProperties,
+ sal_Int32& rNumberFormat,
+ const sal_Int16 nCellType,
+ const rtl::OUString& rCurrency);
+
+ void ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc = 1);
+
+private:
+ void AddStyleRange(const com::sun::star::table::CellRangeAddress& rCellRange);
+ void SetStyleToRanges();
+
+ void ExamineDefaultStyle();
+public:
+ void SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName,
+ const sal_Int16 nCellType, const rtl::OUString* pCurrency);
+ sal_Bool SetNullDateOnUnitConverter();
+ XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper();
+ ScMyStyleNumberFormats* GetStyleNumberFormats();
+
+ void SetStylesToRangesFinished();
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL startDocument(void)
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL endDocument(void)
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ virtual void DisposingModel();
+
+ /**
+ * Use this class to manage solar mutex locking instead of calling
+ * LockSolarMutex() and UnlockSolarMutex() directly.
+ */
+ class MutexGuard
+ {
+ public:
+ explicit MutexGuard(ScXMLImport& rImport);
+ ~MutexGuard();
+ private:
+ ScXMLImport& mrImport;
+ };
+ void LockSolarMutex();
+ void UnlockSolarMutex();
+
+ sal_Int32 GetByteOffset();
+
+ void SetRangeOverflowType(sal_uInt32 nType);
+
+ sal_Int32 GetRangeType(const rtl::OUString sRangeType) const;
+ void SetNamedRanges();
+ void SetSheetNamedRanges();
+ void SetLabelRanges();
+ void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
+
+ sal_Int32 GetVisibleSheet();
+ /** Extracts the formula string, the formula grammar namespace URL, and a
+ grammar enum value from the passed formula attribute value.
+
+ @param rFormula
+ (out-parameter) Returns the plain formula string with the leading
+ equality sign if existing.
+
+ @param rFormulaNmsp
+ (out-parameter) Returns the URL of the formula grammar namespace if
+ the attribute value contains the prefix of an unknown namespace.
+
+ @param reGrammar
+ (out-parameter) Returns the exact formula grammar if the formula
+ is in a supported ODF format (e.g. FormulaGrammar::GRAM_PODF for
+ ODF 1.0/1.1 formulas, or FormulaGrammar::GRAM_ODFF for ODF 1.2
+ formulas a.k.a. OpenFormula). Returns the default storage grammar,
+ if the attribute value does not contain a namespace prefix. Returns
+ the special value FormulaGrammar::GRAM_EXTERNAL, if an unknown
+ namespace could be extracted from the formula which will be
+ contained in the parameter rFormulaNmsp then.
+
+ @param rAttrValue
+ The value of the processed formula attribute.
+
+ @param bRestrictToExternalNmsp
+ If set to sal_True, only namespaces of external formula grammars will
+ be recognized. Internal namespace prefixes (e.g. 'oooc:' or 'of:'
+ will be considered to be part of the formula, e.g. an expression
+ with range operator.
+ */
+ void ExtractFormulaNamespaceGrammar(
+ ::rtl::OUString& rFormula,
+ ::rtl::OUString& rFormulaNmsp,
+ ::formula::FormulaGrammar::Grammar& reGrammar,
+ const ::rtl::OUString& rAttrValue,
+ bool bRestrictToExternalNmsp = false ) const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmllabri.cxx b/sc/source/filter/xml/xmllabri.cxx
new file mode 100644
index 000000000000..e0aadfc9a384
--- /dev/null
+++ b/sc/source/filter/xml/xmllabri.cxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//___________________________________________________________________
+#include "xmllabri.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include "xmlimprt.hxx"
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+using namespace xmloff::token;
+
+
+//___________________________________________________________________
+
+ScXMLLabelRangesContext::ScXMLLabelRangesContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ ):
+ SvXMLImportContext( rImport, nPrefix, rLName )
+{
+ rImport.LockSolarMutex();
+}
+
+ScXMLLabelRangesContext::~ScXMLLabelRangesContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext* ScXMLLabelRangesContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList )
+{
+ SvXMLImportContext* pContext(NULL);
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetLabelRangesElemTokenMap());
+
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_LABEL_RANGE_ELEM:
+ pContext = new ScXMLLabelRangeContext( GetScImport(), nPrefix, rLName, xAttrList );
+ break;
+ }
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLLabelRangesContext::EndElement()
+{
+}
+
+
+//___________________________________________________________________
+
+ScXMLLabelRangeContext::ScXMLLabelRangeContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ bColumnOrientation( false )
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetLabelRangeAttrTokenMap());
+
+ for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
+ {
+ const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
+ const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix (GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE:
+ sLabelRangeStr = sValue;
+ break;
+ case XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE:
+ sDataRangeStr = sValue;
+ break;
+ case XML_TOK_LABEL_RANGE_ATTR_ORIENTATION:
+ bColumnOrientation = IsXMLToken(sValue, XML_COLUMN );
+ break;
+ }
+ }
+}
+
+ScXMLLabelRangeContext::~ScXMLLabelRangeContext()
+{
+}
+
+SvXMLImportContext* ScXMLLabelRangeContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLLabelRangeContext::EndElement()
+{
+ // Label ranges must be stored as strings until all sheets are loaded
+ // (like named expressions).
+
+ ScMyLabelRange* pLabelRange = new ScMyLabelRange;
+
+ pLabelRange->sLabelRangeStr = sLabelRangeStr;
+ pLabelRange->sDataRangeStr = sDataRangeStr;
+ pLabelRange->bColumnOrientation = bColumnOrientation;
+
+ GetScImport().AddLabelRange(pLabelRange);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmllabri.hxx b/sc/source/filter/xml/xmllabri.hxx
new file mode 100644
index 000000000000..7e325b93eb3c
--- /dev/null
+++ b/sc/source/filter/xml/xmllabri.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLLABRI_HXX
+#define SC_XMLLABRI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+
+class ScXMLImport;
+
+
+//___________________________________________________________________
+
+class ScXMLLabelRangesContext : public SvXMLImportContext
+{
+private:
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLLabelRangesContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual ~ScXMLLabelRangesContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual void EndElement();
+};
+
+
+//___________________________________________________________________
+
+class ScXMLLabelRangeContext : public SvXMLImportContext
+{
+private:
+ ::rtl::OUString sLabelRangeStr;
+ ::rtl::OUString sDataRangeStr;
+ sal_Bool bColumnOrientation;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScXMLLabelRangeContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual ~ScXMLLabelRangeContext();
+
+ virtual SvXMLImportContext* CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList
+ );
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx
new file mode 100644
index 000000000000..9e8239aaf310
--- /dev/null
+++ b/sc/source/filter/xml/xmlnexpi.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include <rtl/ustrbuf.hxx>
+
+#include "xmlnexpi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include "docuno.hxx"
+#include "document.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+ScXMLNamedExpressionsContext::GlobalInserter::GlobalInserter(ScXMLImport& rImport) : mrImport(rImport) {}
+
+void ScXMLNamedExpressionsContext::GlobalInserter::insert(ScMyNamedExpression* pExp)
+{
+ if (pExp)
+ mrImport.AddNamedExpression(pExp);
+}
+
+ScXMLNamedExpressionsContext::SheetLocalInserter::SheetLocalInserter(ScXMLImport& rImport, SCTAB nTab) :
+ mrImport(rImport), mnTab(nTab) {}
+
+void ScXMLNamedExpressionsContext::SheetLocalInserter::insert(ScMyNamedExpression* pExp)
+{
+ mrImport.AddNamedExpression(mnTab, pExp);
+}
+
+ScXMLNamedExpressionsContext::ScXMLNamedExpressionsContext(
+ ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */,
+ Inserter* pInserter ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ mpInserter(pInserter)
+{
+ rImport.LockSolarMutex();
+}
+
+ScXMLNamedExpressionsContext::~ScXMLNamedExpressionsContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLNamedExpressionsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetNamedExpressionsElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE:
+ pContext = new ScXMLNamedRangeContext(
+ GetScImport(), nPrefix, rLName, xAttrList, mpInserter.get() );
+ break;
+ case XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION:
+ pContext = new ScXMLNamedExpressionContext(
+ GetScImport(), nPrefix, rLName, xAttrList, mpInserter.get() );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLNamedExpressionsContext::EndElement()
+{
+ // happends in ScXMLImport::EndDocument()
+ // because it has to be set after the Database Ranges
+}
+
+ScXMLNamedRangeContext::ScXMLNamedRangeContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLNamedExpressionsContext::Inserter* pInserter ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ mpInserter(pInserter)
+{
+ if (!mpInserter)
+ return;
+
+ ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
+ // A simple table:cell-range-address is not a formula expression, stored
+ // without [] brackets but with dot, .A1
+ pNamedExpression->eGrammar = formula::FormulaGrammar::mergeToGrammar(
+ GetScImport().GetDocument()->GetStorageGrammar(),
+ formula::FormulaGrammar::CONV_OOO);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetNamedRangeAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_NAMED_RANGE_ATTR_NAME :
+ {
+ pNamedExpression->sName = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS :
+ {
+ pNamedExpression->sContent = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS :
+ {
+ pNamedExpression->sBaseCellAddress = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS :
+ {
+ pNamedExpression->sRangeType = sValue;
+ }
+ break;
+ }
+ }
+ pNamedExpression->bIsExpression = sal_False;
+ mpInserter->insert(pNamedExpression);
+}
+
+ScXMLNamedRangeContext::~ScXMLNamedRangeContext()
+{
+}
+
+SvXMLImportContext *ScXMLNamedRangeContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLNamedRangeContext::EndElement()
+{
+}
+
+ScXMLNamedExpressionContext::ScXMLNamedExpressionContext(
+ ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLNamedExpressionsContext::Inserter* pInserter ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ mpInserter(pInserter)
+{
+ if (!mpInserter)
+ return;
+
+ ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetNamedExpressionAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_NAMED_EXPRESSION_ATTR_NAME :
+ {
+ pNamedExpression->sName = sValue;
+ }
+ break;
+ case XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION :
+ {
+ GetScImport().ExtractFormulaNamespaceGrammar(
+ pNamedExpression->sContent, pNamedExpression->sContentNmsp,
+ pNamedExpression->eGrammar, sValue );
+ }
+ break;
+ case XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS :
+ {
+ pNamedExpression->sBaseCellAddress = sValue;
+ }
+ break;
+ }
+ }
+ pNamedExpression->bIsExpression = sal_True;
+ mpInserter->insert(pNamedExpression);
+}
+
+ScXMLNamedExpressionContext::~ScXMLNamedExpressionContext()
+{
+}
+
+SvXMLImportContext *ScXMLNamedExpressionContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );;
+}
+
+void ScXMLNamedExpressionContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlnexpi.hxx b/sc/source/filter/xml/xmlnexpi.hxx
new file mode 100644
index 000000000000..d480e78786ed
--- /dev/null
+++ b/sc/source/filter/xml/xmlnexpi.hxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLNEXPI_HXX
+#define SC_XMLNEXPI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include "address.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+class ScXMLImport;
+struct ScMyNamedExpression;
+class ScRangeName;
+class ScDocument;
+
+class ScXMLNamedExpressionsContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ class Inserter
+ {
+ public:
+ virtual void insert(ScMyNamedExpression* pExp) = 0;
+ };
+
+ /**
+ * Global named expressions are inserted into ScXMLImport, which does the
+ * bulk insertion at the end of the import.
+ */
+ class GlobalInserter : public Inserter
+ {
+ public:
+ GlobalInserter(ScXMLImport& rImport);
+ virtual void insert(ScMyNamedExpression* pExp);
+ private:
+ ScXMLImport& mrImport;
+ };
+
+ /**
+ * Sheet local named expressions are inserted directly into ScRangeName
+ * instance of that sheet. TODO: the global ones should be inserted the
+ * same way for efficiency.
+ */
+ class SheetLocalInserter : public Inserter
+ {
+ public:
+ SheetLocalInserter(ScXMLImport& rImport, SCTAB nTab);
+ virtual void insert(ScMyNamedExpression* pExp);
+ private:
+ ScXMLImport& mrImport;
+ SCTAB mnTab;
+ };
+
+ ScXMLNamedExpressionsContext(
+ ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ Inserter* pInserter );
+
+ virtual ~ScXMLNamedExpressionsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+private:
+ ::boost::shared_ptr<Inserter> mpInserter;
+};
+
+class ScXMLNamedRangeContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLNamedRangeContext(
+ ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLNamedExpressionsContext::Inserter* pInserter );
+
+ virtual ~ScXMLNamedRangeContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+private:
+ ScXMLNamedExpressionsContext::Inserter* mpInserter;
+};
+
+class ScXMLNamedExpressionContext : public SvXMLImportContext
+{
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLNamedExpressionContext(
+ ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLNamedExpressionsContext::Inserter* pInserter );
+
+ virtual ~ScXMLNamedExpressionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+private:
+ ScXMLNamedExpressionsContext::Inserter* mpInserter;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx
new file mode 100644
index 000000000000..b36b2f812d46
--- /dev/null
+++ b/sc/source/filter/xml/xmlrowi.cxx
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlrowi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlcelli.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "sheetdata.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+
+#include <com/sun/star/table/CellAddress.hpp>
+
+#define SC_ISVISIBLE "IsVisible"
+#define SC_OPTIMALHEIGHT "OptimalHeight"
+#define SC_ISFILTERED "IsFiltered"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLTableRowContext::ScXMLTableRowContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ sVisibility(GetXMLToken(XML_VISIBLE)),
+ nRepeatedRows(1),
+ bHasCell(false)
+{
+ rtl::OUString sCellStyleName;
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableRowAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_ROW_ATTR_STYLE_NAME:
+ {
+ sStyleName = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_VISIBILITY:
+ {
+ sVisibility = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_REPEATED:
+ {
+ nRepeatedRows = std::max( sValue.toInt32(), (sal_Int32) 1 );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME:
+ {
+ sCellStyleName = sValue;
+ }
+ break;
+ /*case XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT:
+ {
+ sOptimalHeight = sValue;
+ }
+ break;*/
+ }
+ }
+ GetScImport().GetTables().AddRow();
+ GetScImport().GetTables().SetRowStyle(sCellStyleName);
+}
+
+ScXMLTableRowContext::~ScXMLTableRowContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROW_CELL:
+// if( IsInsertCellPossible() )
+ {
+ bHasCell = sal_True;
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList, false, nRepeatedRows
+ //this
+ );
+ }
+ break;
+ case XML_TOK_TABLE_ROW_COVERED_CELL:
+// if( IsInsertCellPossible() )
+ {
+ bHasCell = sal_True;
+ pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
+ rLName, xAttrList, sal_True, nRepeatedRows
+ //this
+ );
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableRowContext::EndElement()
+{
+ ScXMLImport& rXMLImport(GetScImport());
+ if (!bHasCell && nRepeatedRows > 1)
+ {
+ for (sal_Int32 i = 0; i < nRepeatedRows - 1; ++i) //one row is always added
+ GetScImport().GetTables().AddRow();
+ DBG_ERRORFILE("it seems here is a nonvalid file; possible missing of table:table-cell element");
+ }
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ sal_Int32 nCurrentRow(rXMLImport.GetTables().GetCurrentRow());
+ uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
+ if(xSheet.is())
+ {
+ sal_Int32 nFirstRow(nCurrentRow - nRepeatedRows + 1);
+ if (nFirstRow > MAXROW)
+ nFirstRow = MAXROW;
+ if (nCurrentRow > MAXROW)
+ nCurrentRow = MAXROW;
+ uno::Reference <table::XCellRange> xCellRange(xSheet->getCellRangeByPosition(0, nFirstRow, 0, nCurrentRow));
+ if (xCellRange.is())
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xCellRange, uno::UNO_QUERY);
+ if (xColumnRowRange.is())
+ {
+ uno::Reference <beans::XPropertySet> xRowProperties(xColumnRowRange->getRows(), uno::UNO_QUERY);
+ if (xRowProperties.is())
+ {
+ if (sStyleName.getLength())
+ {
+ XMLTableStylesContext *pStyles((XMLTableStylesContext *)rXMLImport.GetAutoStyles());
+ if ( pStyles )
+ {
+ XMLTableStyleContext* pStyle((XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_ROW, sStyleName, sal_True));
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xRowProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddRowStyle( sStyleName, ScAddress( 0, (SCROW)nFirstRow, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
+ }
+ }
+ sal_Bool bVisible (sal_True);
+ sal_Bool bFiltered (false);
+ if (IsXMLToken(sVisibility, XML_COLLAPSE))
+ {
+ bVisible = false;
+ }
+ else if (IsXMLToken(sVisibility, XML_FILTER))
+ {
+ bVisible = false;
+ bFiltered = sal_True;
+ }
+ if (!bVisible)
+ xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISVISIBLE)), uno::makeAny(bVisible));
+ if (bFiltered)
+ xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISFILTERED)), uno::makeAny(bFiltered));
+ }
+ }
+ }
+ }
+}
+
+ScXMLTableRowsContext::ScXMLTableRowsContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempHeader, const sal_Bool bTempGroup ) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ nHeaderStartRow(0),
+ nHeaderEndRow(0),
+ nGroupStartRow(0),
+ nGroupEndRow(0),
+ bHeader(bTempHeader),
+ bGroup(bTempGroup),
+ bGroupDisplay(sal_True)
+{
+ // don't have any attributes
+ if (bHeader)
+ {
+ nHeaderStartRow = rImport.GetTables().GetCurrentRow();
+ ++nHeaderStartRow;
+ }
+ else if (bGroup)
+ {
+ nGroupStartRow = rImport.GetTables().GetCurrentRow();
+ ++nGroupStartRow;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_DISPLAY))
+ bGroupDisplay = IsXMLToken(sValue, XML_TRUE);
+ }
+ }
+}
+
+ScXMLTableRowsContext::~ScXMLTableRowsContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableRowsContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowsElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_TABLE_ROWS_ROW_GROUP:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, sal_True );
+ break;
+ case XML_TOK_TABLE_ROWS_HEADER_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, false );
+ break;
+ case XML_TOK_TABLE_ROWS_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, false );
+ break;
+ case XML_TOK_TABLE_ROWS_ROW:
+ pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableRowsContext::EndElement()
+{
+ ScXMLImport& rXMLImport(GetScImport());
+ if (bHeader)
+ {
+ nHeaderEndRow = rXMLImport.GetTables().GetCurrentRow();
+ if (nHeaderStartRow <= nHeaderEndRow)
+ {
+ uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY);
+ if (xPrintAreas.is())
+ {
+ if (!xPrintAreas->getPrintTitleRows())
+ {
+ xPrintAreas->setPrintTitleRows(sal_True);
+ table::CellRangeAddress aRowHeaderRange;
+ aRowHeaderRange.StartRow = nHeaderStartRow;
+ aRowHeaderRange.EndRow = nHeaderEndRow;
+ xPrintAreas->setTitleRows(aRowHeaderRange);
+ }
+ else
+ {
+ table::CellRangeAddress aRowHeaderRange(xPrintAreas->getTitleRows());
+ aRowHeaderRange.EndRow = nHeaderEndRow;
+ xPrintAreas->setTitleRows(aRowHeaderRange);
+ }
+ }
+ }
+ }
+ else if (bGroup)
+ {
+ nGroupEndRow = rXMLImport.GetTables().GetCurrentRow();
+ sal_Int32 nSheet(rXMLImport.GetTables().GetCurrentSheet());
+ if (nGroupStartRow <= nGroupEndRow)
+ {
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (pDoc)
+ {
+ ScXMLImport::MutexGuard aGuard(GetScImport());
+ ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True));
+ ScOutlineArray* pRowArray(pOutlineTable->GetRowArray());
+ sal_Bool bResized;
+ pRowArray->Insert(static_cast<SCROW>(nGroupStartRow), static_cast<SCROW>(nGroupEndRow), bResized, !bGroupDisplay, sal_True);
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlrowi.hxx b/sc/source/filter/xml/xmlrowi.hxx
new file mode 100644
index 000000000000..c41644bcf041
--- /dev/null
+++ b/sc/source/filter/xml/xmlrowi.hxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLROWI_HXX
+#define SC_XMLROWI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+class ScXMLImport;
+
+class ScXMLTableRowContext : public SvXMLImportContext
+{
+ rtl::OUString sStyleName;
+ rtl::OUString sVisibility;
+ sal_Int32 nRepeatedRows;
+ sal_Bool bHasCell;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableRowContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableRowContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+class ScXMLTableRowsContext : public SvXMLImportContext
+{
+ sal_Int32 nHeaderStartRow;
+ sal_Int32 nHeaderEndRow;
+ sal_Int32 nGroupStartRow;
+ sal_Int32 nGroupEndRow;
+ sal_Bool bHeader;
+ sal_Bool bGroup;
+ sal_Bool bGroupDisplay;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableRowsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bHeader, const sal_Bool bGroup);
+
+ virtual ~ScXMLTableRowsContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsceni.cxx b/sc/source/filter/xml/xmlsceni.cxx
new file mode 100644
index 000000000000..b20d60bc74f5
--- /dev/null
+++ b/sc/source/filter/xml/xmlsceni.cxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "document.hxx"
+#include "xmlimprt.hxx"
+#include "xmlsceni.hxx"
+#include "docuno.hxx"
+#include "attrib.hxx"
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::rtl::OUString;
+
+using rtl::OUString;
+
+//------------------------------------------------------------------
+
+ScXMLTableScenarioContext::ScXMLTableScenarioContext(
+ ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& xAttrList ):
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ aBorderColor( COL_BLACK ),
+ bDisplayBorder( sal_True ),
+ bCopyBack( sal_True ),
+ bCopyStyles( sal_True ),
+ bCopyFormulas( sal_True ),
+ bIsActive( false ),
+ bProtected( false )
+{
+ rImport.LockSolarMutex();
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableScenarioAttrTokenMap());
+ for( sal_Int16 i = 0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER:
+ {
+ bDisplayBorder = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR:
+ {
+ SvXMLUnitConverter::convertColor(aBorderColor, sValue);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK:
+ {
+ bCopyBack = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES:
+ {
+ bCopyStyles = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS:
+ {
+ bCopyFormulas = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE:
+ {
+ bIsActive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES:
+ {
+ ScRangeStringConverter::GetRangeListFromString(
+ aScenarioRanges, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO );
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_COMMENT:
+ {
+ sComment = sValue;
+ }
+ break;
+ case XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED:
+ {
+ bProtected = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ }
+ }
+}
+
+ScXMLTableScenarioContext::~ScXMLTableScenarioContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+SvXMLImportContext *ScXMLTableScenarioContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLTableScenarioContext::EndElement()
+{
+ SCTAB nCurrTable( sal::static_int_cast<SCTAB>( GetScImport().GetTables().GetCurrentSheet() ) );
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (pDoc)
+ {
+ pDoc->SetScenario( nCurrTable, sal_True );
+ sal_uInt16 nFlags( 0 );
+ if( bDisplayBorder )
+ nFlags |= SC_SCENARIO_SHOWFRAME;
+ if( bCopyBack )
+ nFlags |= SC_SCENARIO_TWOWAY;
+ if( bCopyStyles )
+ nFlags |= SC_SCENARIO_ATTRIB;
+ if( !bCopyFormulas )
+ nFlags |= SC_SCENARIO_VALUE;
+ if( bProtected )
+ nFlags |= SC_SCENARIO_PROTECT;
+ pDoc->SetScenarioData( nCurrTable, String( sComment ), aBorderColor, nFlags );
+ for( size_t i = 0; i < aScenarioRanges.size(); ++i )
+ {
+ ScRange* pRange(aScenarioRanges[ i ]);
+ if( pRange )
+ pDoc->ApplyFlagsTab( pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row(), nCurrTable, SC_MF_SCENARIO );
+ }
+ pDoc->SetActiveScenario( nCurrTable, bIsActive );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsceni.hxx b/sc/source/filter/xml/xmlsceni.hxx
new file mode 100644
index 000000000000..f6dd8d74b09b
--- /dev/null
+++ b/sc/source/filter/xml/xmlsceni.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSCENI_HXX
+#define SC_XMLSCENI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <tools/color.hxx>
+#include "rangelst.hxx"
+
+class ScXMLImport;
+
+class ScXMLTableScenarioContext : public SvXMLImportContext
+{
+private:
+ rtl::OUString sComment;
+ Color aBorderColor;
+ ScRangeList aScenarioRanges;
+ sal_Bool bDisplayBorder;
+ sal_Bool bCopyBack;
+ sal_Bool bCopyStyles;
+ sal_Bool bCopyFormulas;
+ sal_Bool bIsActive;
+ sal_Bool bProtected;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableScenarioContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableScenarioContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsorti.cxx b/sc/source/filter/xml/xmlsorti.cxx
new file mode 100644
index 000000000000..0826b58313b1
--- /dev/null
+++ b/sc/source/filter/xml/xmlsorti.cxx
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmlsorti.hxx"
+#include "xmlimprt.hxx"
+#include "docuno.hxx"
+#include "convuno.hxx"
+#include "XMLConverter.hxx"
+#include "unonames.hxx"
+#include "rangeutl.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <comphelper/extract.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#define SC_USERLIST "UserList"
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+//------------------------------------------------------------------
+
+ScXMLSortContext::ScXMLSortContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pDatabaseRangeContext(pTempDatabaseRangeContext),
+ sCountry(),
+ sLanguage(),
+ sAlgorithm(),
+ nUserListIndex(0),
+ bCopyOutputData(false),
+ bBindFormatsToContent(sal_True),
+ bIsCaseSensitive(false),
+ bEnabledUserList(false)
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT :
+ {
+ bBindFormatsToContent = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS :
+ {
+ ScRange aScRange;
+ sal_Int32 nOffset(0);
+ if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ))
+ {
+ ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart );
+ bCopyOutputData = sal_True;
+ }
+ }
+ break;
+ case XML_TOK_SORT_ATTR_CASE_SENSITIVE :
+ {
+ bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
+ }
+ break;
+ case XML_TOK_SORT_ATTR_LANGUAGE :
+ sLanguage = sValue;
+ break;
+ case XML_TOK_SORT_ATTR_COUNTRY :
+ sCountry = sValue;
+ break;
+ case XML_TOK_SORT_ATTR_ALGORITHM :
+ sAlgorithm = sValue;
+ break;
+ }
+ }
+}
+
+ScXMLSortContext::~ScXMLSortContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ SvXMLImportContext *pContext(0);
+
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetSortElemTokenMap());
+ switch( rTokenMap.Get( nPrefix, rLName ) )
+ {
+ case XML_TOK_SORT_SORT_BY :
+ {
+ pContext = new ScXMLSortByContext( GetScImport(), nPrefix,
+ rLName, xAttrList, this);
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLSortContext::EndElement()
+{
+ sal_Int32 nLangLength(sLanguage.getLength());
+ sal_Int32 nCountryLength(sCountry.getLength());
+ sal_Int32 nAlgoLength(sAlgorithm.getLength());
+ sal_uInt8 i (0);
+ if (nLangLength || nCountryLength)
+ ++i;
+ if (nAlgoLength)
+ ++i;
+ uno::Sequence <beans::PropertyValue> aSortDescriptor(7 + i);
+ aSortDescriptor[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT));
+ aSortDescriptor[0].Value = ::cppu::bool2any(bBindFormatsToContent);
+ aSortDescriptor[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT));
+ aSortDescriptor[1].Value = ::cppu::bool2any(bCopyOutputData);
+ aSortDescriptor[2].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE));
+ aSortDescriptor[2].Value = ::cppu::bool2any(bIsCaseSensitive);
+ aSortDescriptor[3].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISULIST));
+ aSortDescriptor[3].Value = ::cppu::bool2any(bEnabledUserList);
+ aSortDescriptor[4].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS));
+ aSortDescriptor[4].Value <<= aOutputPosition;
+ aSortDescriptor[5].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_UINDEX));
+ aSortDescriptor[5].Value <<= nUserListIndex;
+ aSortDescriptor[6].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SORTFLD));
+ aSortDescriptor[6].Value <<= aSortFields;
+ if (nLangLength || nCountryLength)
+ {
+ lang::Locale aLocale;
+ aLocale.Language = sLanguage;
+ aLocale.Country = sCountry;
+ aSortDescriptor[7].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLLOC));
+ aSortDescriptor[7].Value <<= aLocale;
+ }
+ if (nAlgoLength)
+ {
+ aSortDescriptor[6 + i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLALG));
+ aSortDescriptor[6 + i].Value <<= sAlgorithm;
+ }
+ pDatabaseRangeContext->SetSortSequence(aSortDescriptor);
+}
+
+void ScXMLSortContext::AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder)
+{
+ util::SortField aSortField;
+ aSortField.Field = sFieldNumber.toInt32();
+ if (IsXMLToken(sOrder, XML_ASCENDING))
+ aSortField.SortAscending = sal_True;
+ else
+ aSortField.SortAscending = false;
+ if (sDataType.getLength() > 8)
+ {
+ rtl::OUString sTemp = sDataType.copy(0, 8);
+ if (sTemp.compareToAscii(SC_USERLIST) == 0)
+ {
+ bEnabledUserList = sal_True;
+ sTemp = sDataType.copy(8);
+ nUserListIndex = static_cast<sal_Int16>(sTemp.toInt32());
+ }
+ else
+ {
+ if (IsXMLToken(sDataType, XML_AUTOMATIC))
+ aSortField.FieldType = util::SortFieldType_AUTOMATIC;
+ }
+ }
+ else
+ {
+ if (IsXMLToken(sDataType, XML_TEXT))
+ aSortField.FieldType = util::SortFieldType_ALPHANUMERIC;
+ else if (IsXMLToken(sDataType, XML_NUMBER))
+ aSortField.FieldType = util::SortFieldType_NUMERIC;
+ }
+ aSortFields.realloc(aSortFields.getLength() + 1);
+ aSortFields[aSortFields.getLength() - 1] = aSortField;
+}
+
+ScXMLSortByContext::ScXMLSortByContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSortContext* pTempSortContext) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pSortContext(pTempSortContext),
+ sDataType(GetXMLToken(XML_AUTOMATIC)),
+ sOrder(GetXMLToken(XML_ASCENDING))
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortSortByAttrTokenMap());
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_SORT_BY_ATTR_FIELD_NUMBER :
+ {
+ sFieldNumber = sValue;
+ }
+ break;
+ case XML_TOK_SORT_BY_ATTR_DATA_TYPE :
+ {
+ sDataType = sValue;
+ }
+ break;
+ case XML_TOK_SORT_BY_ATTR_ORDER :
+ {
+ sOrder = sValue;
+ }
+ break;
+ }
+ }
+}
+
+ScXMLSortByContext::~ScXMLSortByContext()
+{
+}
+
+SvXMLImportContext *ScXMLSortByContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
+{
+ return new SvXMLImportContext( GetImport(), nPrefix, rLName );
+}
+
+void ScXMLSortByContext::EndElement()
+{
+ pSortContext->AddSortField(sFieldNumber, sDataType, sOrder);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsorti.hxx b/sc/source/filter/xml/xmlsorti.hxx
new file mode 100644
index 000000000000..7ccc82053905
--- /dev/null
+++ b/sc/source/filter/xml/xmlsorti.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSORTI_HXX
+#define SC_XMLSORTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/util/SortField.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include "xmldrani.hxx"
+
+class ScXMLImport;
+
+class ScXMLSortContext : public SvXMLImportContext
+{
+ ScXMLDatabaseRangeContext* pDatabaseRangeContext;
+
+ com::sun::star::uno::Sequence <com::sun::star::util::SortField> aSortFields;
+ com::sun::star::table::CellAddress aOutputPosition;
+ rtl::OUString sCountry;
+ rtl::OUString sLanguage;
+ rtl::OUString sAlgorithm;
+ sal_Int16 nUserListIndex;
+ sal_Bool bCopyOutputData;
+ sal_Bool bBindFormatsToContent;
+ sal_Bool bIsCaseSensitive;
+ sal_Bool bEnabledUserList;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDatabaseRangeContext* pTempDatabaseRangeContext);
+
+ virtual ~ScXMLSortContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+
+ void AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder);
+};
+
+class ScXMLSortByContext : public SvXMLImportContext
+{
+ ScXMLSortContext* pSortContext;
+
+ rtl::OUString sFieldNumber;
+ rtl::OUString sDataType;
+ rtl::OUString sOrder;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLSortByContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLSortContext* pTempSortContext);
+
+ virtual ~ScXMLSortByContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlstyle.cxx b/sc/source/filter/xml/xmlstyle.cxx
new file mode 100644
index 000000000000..f2e62d6d9d51
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyle.cxx
@@ -0,0 +1,1952 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "xmlstyle.hxx"
+#include "xmlexprt.hxx"
+#include "xmlimprt.hxx"
+
+#include "XMLConverter.hxx"
+#include "rangeutl.hxx"
+#include "unonames.hxx"
+
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltypes.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmlnumfe.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/attrlist.hxx>
+#include <xmloff/contextid.hxx>
+#include <xmloff/txtprmap.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/util/CellProtection.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellVertJustify2.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellJustifyMethod.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <comphelper/extract.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+using namespace com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
+
+#define MAP(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 }
+#define MAP_EXT(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_LATEST }
+#define MAP_END() { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0, SvtSaveOptions::ODFVER_010 }
+
+const XMLPropertyMapEntry aXMLScCellStylesProperties[] =
+{
+ MAP( "AsianVerticalMode", XML_NAMESPACE_STYLE, XML_GLYPH_ORIENTATION_VERTICAL, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTICAL, 0),
+ MAP( "BottomBorder", XML_NAMESPACE_FO, XML_BORDER_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_BOTTOMBORDER ),
+ MAP( "BottomBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_BOTTOMBORDERWIDTH ),
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_CELL_PROTECT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_CELLPROTECTION|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_PRINT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_PRINTCONTENT|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "CellStyle", XML_NAMESPACE_STYLE, XML_STYLE, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING, CTF_SC_CELLSTYLE ),
+ MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_IMPORT_MAP ),
+ MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MAP ),
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALBLTR ),
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTH ), // #i102690# for old files
+ MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTHS ),
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALTLBR ),
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTH ), // #i102690# for old files
+ MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTHS ),
+ MAP( "HoriJustify", XML_NAMESPACE_FO, XML_TEXT_ALIGN, XML_TYPE_PROP_PARAGRAPH|XML_SC_TYPE_HORIJUSTIFY|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_TEXT_ALIGN_SOURCE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYSOURCE|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_REPEAT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYREPEAT|MID_FLAG_MERGE_PROPERTY, 0 ),
+ MAP( SC_UNONAME_CELLHJUS_METHOD, XML_NAMESPACE_CSS3TEXT, XML_TEXT_JUSTIFY, XML_TYPE_PROP_PARAGRAPH|XML_SC_TYPE_HORIJUSTIFY_METHOD, 0 ),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsTextWrapped", XML_NAMESPACE_FO, XML_WRAP_OPTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_ISTEXTWRAPPED, 0 ),
+ MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_ALLBORDER ),
+ MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_LEFTBORDER ),
+ MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_ALLBORDERWIDTH ),
+ MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_LEFTBORDERWIDTH ),
+ MAP( "NumberFormat", XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER|MID_FLAG_SPECIAL_ITEM, CTF_SC_NUMBERFORMAT),
+ MAP( "Orientation", XML_NAMESPACE_STYLE, XML_DIRECTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ORIENTATION, 0 ),
+ MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_ALLPADDING ),
+ MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_BOTTOMPADDING ),
+ MAP( "ParaIndent", XML_NAMESPACE_FO, XML_MARGIN_LEFT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_MEASURE16, 0 ),
+ MAP( "ParaLeftMargin", XML_NAMESPACE_FO, XML_PADDING_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_LEFTPADDING ),
+ MAP( "ParaRightMargin", XML_NAMESPACE_FO, XML_PADDING_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_RIGHTPADDING ),
+ MAP( "ParaTopMargin", XML_NAMESPACE_FO, XML_PADDING_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_TOPPADDING ),
+ MAP( "RightBorder", XML_NAMESPACE_FO, XML_BORDER_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_RIGHTBORDER ),
+ MAP( "RightBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_RIGHTBORDERWIDTH ),
+ MAP( "RotateAngle", XML_NAMESPACE_STYLE, XML_ROTATION_ANGLE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEANGLE, 0 ),
+ MAP( "RotateReference", XML_NAMESPACE_STYLE, XML_ROTATION_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEREFERENCE, 0),
+ MAP( "ShadowFormat", XML_NAMESPACE_STYLE, XML_SHADOW, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_TEXT_SHADOW, 0 ),
+ MAP( "ShrinkToFit", XML_NAMESPACE_STYLE, XML_SHRINK_TO_FIT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BOOL, 0 ),
+ MAP( "StandardDecimals", XML_NAMESPACE_STYLE, XML_DECIMAL_PLACES, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER16, 0 ),
+ MAP( "TopBorder", XML_NAMESPACE_FO, XML_BORDER_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_TOPBORDER ),
+ MAP( "TopBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_TOPBORDERWIDTH ),
+ MAP( "UserDefinedAttributes", XML_NAMESPACE_TEXT, XML_XMLNS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ),
+ MAP( "ValidationXML", XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BUILDIN_CMP_ONLY, CTF_SC_VALIDATION ),
+ MAP( "VertJustify", XML_NAMESPACE_STYLE, XML_VERTICAL_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTJUSTIFY, 0),
+ MAP( SC_UNONAME_CELLVJUS_METHOD, XML_NAMESPACE_STYLE, XML_VERTICAL_JUSTIFY, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTJUSTIFY_METHOD, 0 ),
+
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScColumnStylesProperties[] =
+{
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_BREAKBEFORE, 0),
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_EQUAL|MID_FLAG_SPECIAL_ITEM, CTF_SC_ISVISIBLE ),
+ MAP( "Width", XML_NAMESPACE_STYLE, XML_COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_MEASURE, 0 ),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScRowStylesImportProperties[] =
+{
+ // #i57867# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only.
+ // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries,
+ // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0.
+ // If this is changed (not for 2.0.x), a single map can be used again.
+
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE),
+ MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScRowStylesProperties[] =
+{
+ MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT),
+ MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE),
+ MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScTableStylesImportProperties[] =
+{
+ // #i57869# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only.
+ // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries,
+ // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0.
+ // If this is changed (not for 2.0.x), a single map can be used again.
+
+ MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ),
+ MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ),
+ MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ),
+ MAP( "TabColor", XML_NAMESPACE_TABLE, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_END()
+};
+
+const XMLPropertyMapEntry aXMLScTableStylesProperties[] =
+{
+ MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ),
+ MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ),
+ MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ),
+ MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ),
+ MAP_END()
+};
+
+ScXMLCellExportPropertyMapper::ScXMLCellExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLCellExportPropertyMapper::~ScXMLCellExportPropertyMapper()
+{
+}
+
+void ScXMLCellExportPropertyMapper::ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ uno::Reference< beans::XPropertySet > rPropSet ) const
+{
+ XMLPropertyState* pPadding = NULL;
+ XMLPropertyState* pPadding_Bottom = NULL;
+ XMLPropertyState* pPadding_Left = NULL;
+ XMLPropertyState* pPadding_Right = NULL;
+ XMLPropertyState* pPadding_Top = NULL;
+
+ XMLPropertyState* pBorder = NULL;
+ XMLPropertyState* pBorder_Bottom = NULL;
+ XMLPropertyState* pBorder_Left = NULL;
+ XMLPropertyState* pBorder_Right = NULL;
+ XMLPropertyState* pBorder_Top = NULL;
+ XMLPropertyState* pSWBorder = NULL;
+ XMLPropertyState* pSWBorder_Bottom = NULL;
+ XMLPropertyState* pSWBorder_Left = NULL;
+ XMLPropertyState* pSWBorder_Right = NULL;
+ XMLPropertyState* pSWBorder_Top = NULL;
+
+ XMLPropertyState* pAllBorderWidthState = NULL;
+ XMLPropertyState* pLeftBorderWidthState = NULL;
+ XMLPropertyState* pRightBorderWidthState = NULL;
+ XMLPropertyState* pTopBorderWidthState = NULL;
+ XMLPropertyState* pBottomBorderWidthState = NULL;
+ XMLPropertyState* pSWAllBorderWidthState = NULL;
+ XMLPropertyState* pSWLeftBorderWidthState = NULL;
+ XMLPropertyState* pSWRightBorderWidthState = NULL;
+ XMLPropertyState* pSWTopBorderWidthState = NULL;
+ XMLPropertyState* pSWBottomBorderWidthState = NULL;
+ XMLPropertyState* pDiagonalTLBRWidthState = NULL;
+ XMLPropertyState* pDiagonalBLTRWidthState = NULL;
+
+ XMLPropertyState* pParaMarginLeft = NULL;
+ XMLPropertyState* pParaMarginLeftRel = NULL;
+ XMLPropertyState* pParaMarginRight = NULL;
+ XMLPropertyState* pParaMarginRightRel = NULL;
+ XMLPropertyState* pParaMarginTop = NULL;
+ XMLPropertyState* pParaMarginTopRel = NULL;
+ XMLPropertyState* pParaMarginBottom = NULL;
+ XMLPropertyState* pParaMarginBottomRel = NULL;
+
+ XMLPropertyState* pParaAdjust = NULL;
+ XMLPropertyState* pParaAdjustLast = NULL;
+
+ ::std::vector< XMLPropertyState >::iterator aEndIter(rProperties.end());
+ for( ::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != aEndIter; ++aIter )
+ {
+ XMLPropertyState* propertie = &(*aIter);
+ if (propertie->mnIndex != -1)
+ {
+ switch( getPropertySetMapper()->GetEntryContextId( propertie->mnIndex ) )
+ {
+ case CTF_SC_ALLPADDING: pPadding = propertie; break;
+ case CTF_SC_BOTTOMPADDING: pPadding_Bottom = propertie; break;
+ case CTF_SC_LEFTPADDING: pPadding_Left = propertie; break;
+ case CTF_SC_RIGHTPADDING: pPadding_Right = propertie; break;
+ case CTF_SC_TOPPADDING: pPadding_Top = propertie; break;
+ case CTF_SC_ALLBORDER: pBorder = propertie; break;
+ case CTF_SC_LEFTBORDER: pBorder_Left = propertie; break;
+ case CTF_SC_RIGHTBORDER: pBorder_Right = propertie; break;
+ case CTF_SC_BOTTOMBORDER: pBorder_Bottom = propertie; break;
+ case CTF_SC_TOPBORDER: pBorder_Top = propertie; break;
+ case CTF_SC_ALLBORDERWIDTH: pAllBorderWidthState = propertie; break;
+ case CTF_SC_LEFTBORDERWIDTH: pLeftBorderWidthState = propertie; break;
+ case CTF_SC_RIGHTBORDERWIDTH: pRightBorderWidthState = propertie; break;
+ case CTF_SC_TOPBORDERWIDTH: pTopBorderWidthState = propertie; break;
+ case CTF_SC_BOTTOMBORDERWIDTH: pBottomBorderWidthState = propertie; break;
+ case CTF_ALLBORDER: pSWBorder = propertie; break;
+ case CTF_LEFTBORDER: pSWBorder_Left = propertie; break;
+ case CTF_RIGHTBORDER: pSWBorder_Right = propertie; break;
+ case CTF_BOTTOMBORDER: pSWBorder_Bottom = propertie; break;
+ case CTF_TOPBORDER: pSWBorder_Top = propertie; break;
+ case CTF_ALLBORDERWIDTH: pSWAllBorderWidthState = propertie; break;
+ case CTF_LEFTBORDERWIDTH: pSWLeftBorderWidthState = propertie; break;
+ case CTF_RIGHTBORDERWIDTH: pSWRightBorderWidthState = propertie; break;
+ case CTF_TOPBORDERWIDTH: pSWTopBorderWidthState = propertie; break;
+ case CTF_BOTTOMBORDERWIDTH: pSWBottomBorderWidthState = propertie; break;
+ case CTF_SC_DIAGONALTLBR: break; //old diagonal line attribute names without "s" are only read, not written
+ case CTF_SC_DIAGONALTLBRWIDTH: pDiagonalTLBRWidthState = propertie; break;
+ case CTF_SC_DIAGONALBLTR: break; //old diagonal line attribute names without "s" are only read, not written
+ case CTF_SC_DIAGONALBLTRWIDTH: pDiagonalBLTRWidthState = propertie; break;
+ case CTF_SD_SHAPE_PARA_ADJUST: pParaAdjust = propertie; break;
+ case CTF_PARA_ADJUSTLAST: pParaAdjustLast = propertie; break;
+ case CTF_PARALEFTMARGIN: pParaMarginLeft = propertie; break;
+ case CTF_PARALEFTMARGIN_REL: pParaMarginLeftRel = propertie; break;
+ case CTF_PARARIGHTMARGIN: pParaMarginRight = propertie; break;
+ case CTF_PARARIGHTMARGIN_REL: pParaMarginRightRel = propertie; break;
+ case CTF_PARATOPMARGIN: pParaMarginTop = propertie; break;
+ case CTF_PARATOPMARGIN_REL: pParaMarginTopRel = propertie; break;
+ case CTF_PARABOTTOMMARGIN: pParaMarginBottom = propertie; break;
+ case CTF_PARABOTTOMMARGIN_REL: pParaMarginBottomRel = propertie; break;
+ }
+ }
+ }
+
+ if (pPadding && pPadding_Bottom && pPadding_Left && pPadding_Right && pPadding_Top)
+ {
+ sal_Int32 nBottom = 0, nTop = 0, nLeft = 0, nRight = 0;
+ if ((pPadding_Bottom->maValue >>= nBottom) &&
+ (pPadding_Left->maValue >>= nLeft) &&
+ (pPadding_Right->maValue >>= nRight) &&
+ (pPadding_Top->maValue >>= nTop))
+ {
+ if ((nBottom == nTop) && (nLeft == nRight) && (nTop == nLeft))
+ {
+ pPadding_Bottom->mnIndex = -1;
+ pPadding_Bottom->maValue.clear();
+ pPadding_Left->mnIndex = -1;
+ pPadding_Left->maValue.clear();
+ pPadding_Right->mnIndex = -1;
+ pPadding_Right->maValue.clear();
+ pPadding_Top->mnIndex = -1;
+ pPadding_Top->maValue.clear();
+ }
+ else
+ {
+ pPadding->mnIndex = -1;
+ pPadding->maValue.clear();
+ }
+ }
+ }
+ if( pBorder )
+ {
+ if( pBorder_Left && pBorder_Right && pBorder_Top && pBorder_Bottom )
+ {
+ table::BorderLine2 aLeft, aRight, aTop, aBottom;
+
+ pBorder_Left->maValue >>= aLeft;
+ pBorder_Right->maValue >>= aRight;
+ pBorder_Top->maValue >>= aTop;
+ pBorder_Bottom->maValue >>= aBottom;
+ if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
+ aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
+ aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+ aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+ aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
+ aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance &&
+ aLeft.LineStyle == aRight.LineStyle && aLeft.LineStyle == aTop.LineStyle &&
+ aLeft.LineStyle == aBottom.LineStyle && aLeft.LineWidth == aRight.LineWidth &&
+ aLeft.LineWidth == aTop.LineWidth && aLeft.LineWidth == aBottom.LineWidth )
+ {
+ pBorder_Left->mnIndex = -1;
+ pBorder_Left->maValue.clear();
+ pBorder_Right->mnIndex = -1;
+ pBorder_Right->maValue.clear();
+ pBorder_Top->mnIndex = -1;
+ pBorder_Top->maValue.clear();
+ pBorder_Bottom->mnIndex = -1;
+ pBorder_Bottom->maValue.clear();
+ }
+ else
+ {
+ pBorder->mnIndex = -1;
+ pBorder->maValue.clear();
+ }
+ }
+ else
+ {
+ pBorder->mnIndex = -1;
+ pBorder->maValue.clear();
+ }
+ }
+ if( pAllBorderWidthState )
+ {
+ if( pLeftBorderWidthState && pRightBorderWidthState && pTopBorderWidthState && pBottomBorderWidthState )
+ {
+ table::BorderLine2 aLeft, aRight, aTop, aBottom;
+
+ pLeftBorderWidthState->maValue >>= aLeft;
+ pRightBorderWidthState->maValue >>= aRight;
+ pTopBorderWidthState->maValue >>= aTop;
+ pBottomBorderWidthState->maValue >>= aBottom;
+ if( aLeft.InnerLineWidth == aRight.InnerLineWidth && aLeft.OuterLineWidth == aRight.OuterLineWidth &&
+ aLeft.LineDistance == aRight.LineDistance && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+ aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+ aLeft.InnerLineWidth == aBottom.InnerLineWidth && aLeft.OuterLineWidth == aBottom.OuterLineWidth &&
+ aLeft.LineDistance == aBottom.LineDistance && aLeft.LineWidth == aRight.LineWidth &&
+ aLeft.LineWidth == aTop.LineWidth && aLeft.LineWidth == aBottom.LineWidth )
+ {
+ pLeftBorderWidthState->mnIndex = -1;
+ pLeftBorderWidthState->maValue.clear();
+ pRightBorderWidthState->mnIndex = -1;
+ pRightBorderWidthState->maValue.clear();
+ pTopBorderWidthState->mnIndex = -1;
+ pTopBorderWidthState->maValue.clear();
+ pBottomBorderWidthState->mnIndex = -1;
+ pBottomBorderWidthState->maValue.clear();
+ }
+ else
+ {
+ pAllBorderWidthState->mnIndex = -1;
+ pAllBorderWidthState->maValue.clear();
+ }
+ }
+ else
+ {
+ pAllBorderWidthState->mnIndex = -1;
+ pAllBorderWidthState->maValue.clear();
+ }
+ }
+
+ if (pParaAdjust)
+ {
+ pParaAdjust->mnIndex = -1;
+ pParaAdjust->maValue.clear();
+ }
+ if (pParaAdjustLast)
+ {
+ pParaAdjustLast->mnIndex = -1;
+ pParaAdjustLast->maValue.clear();
+ }
+ if (pSWBorder)
+ {
+ pSWBorder->mnIndex = -1;
+ pSWBorder->maValue.clear();
+ }
+ if (pSWBorder_Left)
+ {
+ pSWBorder_Left->mnIndex = -1;
+ pSWBorder_Left->maValue.clear();
+ }
+ if (pSWBorder_Right)
+ {
+ pSWBorder_Right->mnIndex = -1;
+ pSWBorder_Right->maValue.clear();
+ }
+ if (pSWBorder_Bottom)
+ {
+ pSWBorder_Bottom->mnIndex = -1;
+ pSWBorder_Bottom->maValue.clear();
+ }
+ if (pSWBorder_Top)
+ {
+ pSWBorder_Top->mnIndex = -1;
+ pSWBorder_Top->maValue.clear();
+ }
+ if (pSWAllBorderWidthState)
+ {
+ pSWAllBorderWidthState->mnIndex = -1;
+ pSWAllBorderWidthState->maValue.clear();
+ }
+ if (pSWLeftBorderWidthState)
+ {
+ pSWLeftBorderWidthState->mnIndex = -1;
+ pSWLeftBorderWidthState->maValue.clear();
+ }
+ if (pSWRightBorderWidthState)
+ {
+ pSWRightBorderWidthState->mnIndex = -1;
+ pSWRightBorderWidthState->maValue.clear();
+ }
+ if (pSWTopBorderWidthState)
+ {
+ pSWTopBorderWidthState->mnIndex = -1;
+ pSWTopBorderWidthState->maValue.clear();
+ }
+ if (pSWBottomBorderWidthState)
+ {
+ pSWBottomBorderWidthState->mnIndex = -1;
+ pSWBottomBorderWidthState->maValue.clear();
+ }
+
+ if (pParaMarginLeft)
+ {
+ pParaMarginLeft->mnIndex = -1;
+ pParaMarginLeft->maValue.clear();
+ }
+ if (pParaMarginLeftRel)
+ {
+ pParaMarginLeftRel->mnIndex = -1;
+ pParaMarginLeftRel->maValue.clear();
+ }
+ if (pParaMarginRight)
+ {
+ pParaMarginRight->mnIndex = -1;
+ pParaMarginRight->maValue.clear();
+ }
+ if (pParaMarginRightRel)
+ {
+ pParaMarginRightRel->mnIndex = -1;
+ pParaMarginRightRel->maValue.clear();
+ }
+ if (pParaMarginTop)
+ {
+ pParaMarginTop->mnIndex = -1;
+ pParaMarginTop->maValue.clear();
+ }
+ if (pParaMarginTopRel)
+ {
+ pParaMarginTopRel->mnIndex = -1;
+ pParaMarginTopRel->maValue.clear();
+ }
+ if (pParaMarginBottom)
+ {
+ pParaMarginBottom->mnIndex = -1;
+ pParaMarginBottom->maValue.clear();
+ }
+ if (pParaMarginBottomRel)
+ {
+ pParaMarginBottomRel->mnIndex = -1;
+ pParaMarginBottomRel->maValue.clear();
+ }
+
+ // #i102690# old diagonal line attribute names without "s" are only read, not written
+ if (pDiagonalTLBRWidthState)
+ {
+ pDiagonalTLBRWidthState->mnIndex = -1;
+ pDiagonalTLBRWidthState->maValue.clear();
+ }
+ if (pDiagonalBLTRWidthState)
+ {
+ pDiagonalBLTRWidthState->mnIndex = -1;
+ pDiagonalBLTRWidthState->maValue.clear();
+ }
+
+ SvXMLExportPropertyMapper::ContextFilter(rProperties, rPropSet);
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLCellExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem NumberFormat must not be handled by this method
+ // the SpecialItem ConditionlaFormat must not be handled by this method
+ // the SpecialItem CharBackColor must not be handled by this method
+}
+
+ScXMLRowExportPropertyMapper::ScXMLRowExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLRowExportPropertyMapper::~ScXMLRowExportPropertyMapper()
+{
+}
+
+void ScXMLRowExportPropertyMapper::ContextFilter(
+ ::std::vector< XMLPropertyState >& /* rProperties */,
+ uno::Reference< beans::XPropertySet > /* rPropSet */ ) const
+{
+ //#108550#; don't filter the height, so other applications know the calculated height
+}
+
+ScXMLColumnExportPropertyMapper::ScXMLColumnExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLColumnExportPropertyMapper::~ScXMLColumnExportPropertyMapper()
+{
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLColumnExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem IsVisible must not be handled by this method
+}
+
+ScXMLTableExportPropertyMapper::ScXMLTableExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper )
+ : SvXMLExportPropertyMapper(rMapper)
+{
+}
+
+ScXMLTableExportPropertyMapper::~ScXMLTableExportPropertyMapper()
+{
+}
+
+/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+void ScXMLTableExportPropertyMapper::handleSpecialItem(
+ SvXMLAttributeList& /* rAttrList */,
+ const XMLPropertyState& /* rProperty */,
+ const SvXMLUnitConverter& /* rUnitConverter */,
+ const SvXMLNamespaceMap& /* rNamespaceMap */,
+ const ::std::vector< XMLPropertyState > * /* pProperties */,
+ sal_uInt32 /* nIdx */ ) const
+{
+ // the SpecialItem PageStyle must not be handled by this method
+}
+
+void ScXMLAutoStylePoolP::exportStyleAttributes(
+ SvXMLAttributeList& rAttrList,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const
+{
+ SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap );
+ if (nFamily == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while (i != endi)
+ {
+ UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetCellStylesPropertySetMapper());
+ sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex));
+ switch (nContextID)
+ {
+ case CTF_SC_NUMBERFORMAT :
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (i->maValue >>= nNumberFormat)
+ {
+ rtl::OUString sAttrValue(rScXMLExport.getDataStyleName(nNumberFormat));
+ if (sAttrValue.getLength())
+ {
+ GetExport().AddAttribute(
+ aPropMapper->GetEntryNameSpace(i->mnIndex),
+ aPropMapper->GetEntryXMLName(i->mnIndex),
+ sAttrValue );
+ }
+ }
+ }
+ break;
+ }
+ ++i;
+ }
+ }
+ else if (nFamily == XML_STYLE_FAMILY_TABLE_TABLE)
+ {
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while(i != endi)
+ {
+ UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetTableStylesPropertySetMapper());
+ sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex));
+ switch (nContextID)
+ {
+ case CTF_SC_MASTERPAGENAME :
+ {
+ rtl::OUString sName;
+ if (i->maValue >>= sName)
+ {
+ GetExport().AddAttribute(
+ aPropMapper->GetEntryNameSpace(i->mnIndex),
+ aPropMapper->GetEntryXMLName(i->mnIndex),
+ GetExport().EncodeStyleName( sName ));
+ }
+ }
+ break;
+ }
+ ++i;
+ }
+ }
+}
+
+void ScXMLAutoStylePoolP::exportStyleContent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
+ sal_Int32 nFamily,
+ const std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const
+{
+ SvXMLAutoStylePoolP::exportStyleContent( rHandler, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap );
+ if (nFamily == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ sal_Bool bNotFound = sal_True;
+ ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin());
+ ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end());
+ while ((i != endi) && bNotFound)
+ {
+ if (i->mnIndex != -1)
+ {
+ sal_Int16 nContextID = rScXMLExport.GetCellStylesPropertySetMapper()->GetEntryContextId(i->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_MAP :
+ {
+ uno::Reference<container::XIndexAccess> xIndex( i->maValue, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ sal_Int32 nConditionCount(xIndex->getCount());
+ for (sal_Int32 nCondition = 0; nCondition < nConditionCount; ++nCondition)
+ {
+ uno::Reference <sheet::XSheetConditionalEntry> xSheetConditionalEntry(xIndex->getByIndex(nCondition), uno::UNO_QUERY);
+ if (xSheetConditionalEntry.is())
+ {
+ rtl::OUString sStyleName(xSheetConditionalEntry->getStyleName());
+ uno::Reference <sheet::XSheetCondition> xSheetCondition(xSheetConditionalEntry, uno::UNO_QUERY);
+ if (xSheetCondition.is())
+ {
+ sheet::ConditionOperator aOperator = xSheetCondition->getOperator();
+ if (aOperator != sheet::ConditionOperator_NONE)
+ {
+ if (aOperator == sheet::ConditionOperator_FORMULA)
+ {
+ rtl::OUString sCondition(RTL_CONSTASCII_USTRINGPARAM("is-true-formula("));
+ sCondition += xSheetCondition->getFormula1();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition);
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName ));
+ OUString sOUBaseAddress;
+ ScDocument* pDoc = rScXMLExport.GetDocument();
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress,
+ xSheetCondition->getSourcePosition(), pDoc, FormulaGrammar::CONV_OOO );
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress);
+ SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True);
+ }
+ else
+ {
+ rtl::OUString sCondition;
+ if (aOperator == sheet::ConditionOperator_BETWEEN ||
+ aOperator == sheet::ConditionOperator_NOT_BETWEEN)
+ {
+ if (aOperator == sheet::ConditionOperator_BETWEEN)
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between("));
+ else
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between("));
+ sCondition += xSheetCondition->getFormula1();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ sCondition += xSheetCondition->getFormula2();
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+ else
+ {
+ sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()"));
+ switch (aOperator)
+ {
+ case sheet::ConditionOperator_LESS:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ break;
+ case sheet::ConditionOperator_GREATER:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ break;
+ case sheet::ConditionOperator_LESS_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ break;
+ case sheet::ConditionOperator_GREATER_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ break;
+ case sheet::ConditionOperator_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+ break;
+ case sheet::ConditionOperator_NOT_EQUAL:
+ sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ sCondition += xSheetCondition->getFormula1();
+ }
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition);
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName ));
+ OUString sOUBaseAddress;
+ ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress,
+ xSheetCondition->getSourcePosition(), rScXMLExport.GetDocument(), FormulaGrammar::CONV_OOO );
+ rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress);
+ SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ ++i;
+ }
+ }
+}
+
+ScXMLAutoStylePoolP::ScXMLAutoStylePoolP(ScXMLExport& rTempScXMLExport):
+ SvXMLAutoStylePoolP(rTempScXMLExport),
+ rScXMLExport(rTempScXMLExport)
+{
+}
+
+ScXMLAutoStylePoolP::~ScXMLAutoStylePoolP()
+{
+}
+
+
+void ScXMLStyleExport::exportStyleAttributes(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle )
+{
+ uno::Reference< beans::XPropertySet > xPropSet( rStyle, uno::UNO_QUERY );
+ if (xPropSet.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo(xPropSet->getPropertySetInfo());
+ rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"));
+ if( xPropSetInfo->hasPropertyByName( sNumberFormat ) )
+ {
+ uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
+ if( xPropState.is() && (beans::PropertyState_DIRECT_VALUE ==
+ xPropState->getPropertyState( sNumberFormat )) )
+ {
+ sal_Int32 nNumberFormat = 0;
+ if (xPropSet->getPropertyValue( sNumberFormat ) >>= nNumberFormat)
+ GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME,
+ GetExport().getDataStyleName(nNumberFormat) );
+ }
+ }
+ }
+}
+
+void ScXMLStyleExport::exportStyleContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & /* rStyle */ )
+{
+}
+
+ScXMLStyleExport::ScXMLStyleExport(
+ SvXMLExport& rExp,
+ const ::rtl::OUString& rPoolStyleName,
+ SvXMLAutoStylePoolP *pAutoStyleP )
+ : XMLStyleExport(rExp, rPoolStyleName, pAutoStyleP)
+{
+}
+
+ScXMLStyleExport::~ScXMLStyleExport()
+{
+}
+
+XMLScPropHdlFactory::XMLScPropHdlFactory()
+ : XMLPropertyHandlerFactory()
+{
+}
+
+XMLScPropHdlFactory::~XMLScPropHdlFactory()
+{
+}
+
+const XMLPropertyHandler* XMLScPropHdlFactory::GetPropertyHandler( sal_Int32 nType ) const
+{
+ nType &= MID_FLAG_MASK;
+
+ XMLPropertyHandler* pHdl((XMLPropertyHandler*)XMLPropertyHandlerFactory::GetPropertyHandler( nType ));
+ if(!pHdl)
+ {
+ switch(nType)
+ {
+ case XML_SC_TYPE_CELLPROTECTION :
+ {
+ pHdl = new XmlScPropHdl_CellProtection;
+ }
+ break;
+ case XML_SC_TYPE_PRINTCONTENT :
+ {
+ pHdl = new XmlScPropHdl_PrintContent;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFY_METHOD:
+ case XML_SC_TYPE_VERTJUSTIFY_METHOD:
+ {
+ pHdl = new XmlScPropHdl_JustifyMethod;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFY :
+ {
+ pHdl = new XmlScPropHdl_HoriJustify;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFYSOURCE :
+ {
+ pHdl = new XmlScPropHdl_HoriJustifySource;
+ }
+ break;
+ case XML_SC_TYPE_HORIJUSTIFYREPEAT :
+ {
+ pHdl = new XmlScPropHdl_HoriJustifyRepeat;
+ }
+ break;
+ case XML_SC_TYPE_ORIENTATION :
+ {
+ pHdl = new XmlScPropHdl_Orientation;
+ }
+ break;
+ case XML_SC_TYPE_ROTATEANGLE :
+ {
+ pHdl = new XmlScPropHdl_RotateAngle;
+ }
+ break;
+ case XML_SC_TYPE_ROTATEREFERENCE :
+ {
+ pHdl = new XmlScPropHdl_RotateReference;
+ }
+ break;
+ case XML_SC_TYPE_VERTJUSTIFY :
+ {
+ pHdl = new XmlScPropHdl_VertJustify;
+ }
+ break;
+ case XML_SC_TYPE_BREAKBEFORE :
+ {
+ pHdl = new XmlScPropHdl_BreakBefore;
+ }
+ break;
+ case XML_SC_ISTEXTWRAPPED :
+ {
+ pHdl = new XmlScPropHdl_IsTextWrapped;
+ }
+ break;
+ case XML_SC_TYPE_EQUAL :
+ {
+ pHdl = new XmlScPropHdl_IsEqual;
+ }
+ break;
+ case XML_SC_TYPE_VERTICAL :
+ {
+ pHdl = new XmlScPropHdl_Vertical;
+ }
+ break;
+ }
+
+ if(pHdl)
+ PutHdlCache(nType, pHdl);
+ }
+
+ return pHdl;
+}
+
+XmlScPropHdl_CellProtection::~XmlScPropHdl_CellProtection()
+{
+}
+
+bool XmlScPropHdl_CellProtection::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ util::CellProtection aCellProtection1, aCellProtection2;
+
+ if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2))
+ {
+ return ((aCellProtection1.IsHidden == aCellProtection2.IsHidden) &&
+ (aCellProtection1.IsLocked == aCellProtection2.IsLocked) &&
+ (aCellProtection1.IsFormulaHidden == aCellProtection2.IsFormulaHidden));
+ }
+ return false;
+}
+
+sal_Bool XmlScPropHdl_CellProtection::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ util::CellProtection aCellProtection;
+ sal_Bool bDefault(false);
+ if (!rValue.hasValue())
+ {
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = sal_True;
+ aCellProtection.IsFormulaHidden = false;
+ aCellProtection.IsPrintHidden = false;
+ bDefault = sal_True;
+ }
+ if ((rValue >>= aCellProtection) || bDefault)
+ {
+ if (!IsXMLToken(rStrImpValue, XML_NONE))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_HIDDEN_AND_PROTECTED))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_PROTECTED))
+ {
+ if (!IsXMLToken(rStrImpValue, XML_FORMULA_HIDDEN))
+ {
+ sal_Int16 i(0);
+ while (i < rStrImpValue.getLength() && rStrImpValue[i] != ' ')
+ ++i;
+ rtl::OUString sFirst(rStrImpValue.copy(0, i));
+ rtl::OUString sSecond(rStrImpValue.copy(i + 1));
+ aCellProtection.IsFormulaHidden = false;
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = false;
+ if ((IsXMLToken(sFirst, XML_PROTECTED)) || (IsXMLToken(sSecond, XML_PROTECTED)))
+ aCellProtection.IsLocked = sal_True;
+ if ((IsXMLToken(sFirst, XML_FORMULA_HIDDEN)) || (IsXMLToken(sSecond, XML_FORMULA_HIDDEN)))
+ aCellProtection.IsFormulaHidden = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_True;
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = false;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = false;
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = sal_True;
+ aCellProtection.IsHidden = sal_True;
+ aCellProtection.IsLocked = sal_True;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+ else
+ {
+ aCellProtection.IsFormulaHidden = false;
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = false;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_CellProtection::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+ util::CellProtection aCellProtection;
+
+ if(rValue >>= aCellProtection)
+ {
+ if (!(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden || aCellProtection.IsLocked))
+ {
+ rStrExpValue = GetXMLToken(XML_NONE);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsHidden)
+ {
+ // #i105964# "Hide all" implies "Protected" in the UI, so it must be saved as "hidden-and-protected"
+ // even if "IsLocked" is not set in the CellProtection struct.
+ rStrExpValue = GetXMLToken(XML_HIDDEN_AND_PROTECTED);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsLocked && !(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden))
+ {
+ rStrExpValue = GetXMLToken(XML_PROTECTED);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsFormulaHidden && !(aCellProtection.IsLocked || aCellProtection.IsHidden))
+ {
+ rStrExpValue = GetXMLToken(XML_FORMULA_HIDDEN);
+ bRetval = sal_True;
+ }
+ else if (aCellProtection.IsFormulaHidden && aCellProtection.IsLocked)
+ {
+ rStrExpValue = GetXMLToken(XML_PROTECTED);
+ rStrExpValue += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
+ rStrExpValue += GetXMLToken(XML_FORMULA_HIDDEN);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_PrintContent::~XmlScPropHdl_PrintContent()
+{
+}
+
+bool XmlScPropHdl_PrintContent::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ util::CellProtection aCellProtection1, aCellProtection2;
+
+ if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2))
+ {
+ return (aCellProtection1.IsPrintHidden == aCellProtection2.IsPrintHidden);
+ }
+ return false;
+}
+
+sal_Bool XmlScPropHdl_PrintContent::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+ util::CellProtection aCellProtection;
+ sal_Bool bDefault(false);
+ if (!rValue.hasValue())
+ {
+ aCellProtection.IsHidden = false;
+ aCellProtection.IsLocked = sal_True;
+ aCellProtection.IsFormulaHidden = false;
+ aCellProtection.IsPrintHidden = false;
+ bDefault = sal_True;
+ }
+ if ((rValue >>= aCellProtection) || bDefault)
+ {
+ bool bValue;
+ if (SvXMLUnitConverter::convertBool(bValue, rStrImpValue))
+ {
+ aCellProtection.IsPrintHidden = !bValue;
+ rValue <<= aCellProtection;
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_PrintContent::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ util::CellProtection aCellProtection;
+ if(rValue >>= aCellProtection)
+ {
+ rtl::OUStringBuffer sValue;
+ SvXMLUnitConverter::convertBool(sValue, !aCellProtection.IsPrintHidden);
+ rStrExpValue = sValue.makeStringAndClear();
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+
+XmlScPropHdl_JustifyMethod::~XmlScPropHdl_JustifyMethod()
+{
+}
+
+bool XmlScPropHdl_JustifyMethod::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Int32 nVal1(0), nVal2(0);
+
+ if((r1 >>= nVal1) && (r2 >>= nVal2))
+ return (nVal1 == nVal2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_JustifyMethod::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ bool bRetval = false;
+
+ sal_Int32 nValue = table::CellJustifyMethod::AUTO;
+ if (IsXMLToken(rStrImpValue, XML_AUTO))
+ {
+ nValue = table::CellJustifyMethod::AUTO;
+ rValue <<= nValue;
+ bRetval = true;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_DISTRIBUTE))
+ {
+ nValue = table::CellJustifyMethod::DISTRIBUTE;
+ rValue <<= nValue;
+ bRetval = true;
+ }
+ else
+ bRetval = true;
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_JustifyMethod::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Int32 nVal(0);
+ bool bRetval = false;
+
+ if (rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellJustifyMethod::AUTO:
+ {
+ rStrExpValue = GetXMLToken(XML_AUTO);
+ bRetval = true;
+ }
+ break;
+ case table::CellJustifyMethod::DISTRIBUTE:
+ {
+ rStrExpValue = GetXMLToken(XML_DISTRIBUTE);
+ bRetval = true;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustify::~XmlScPropHdl_HoriJustify()
+{
+}
+
+bool XmlScPropHdl_HoriJustify::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_HoriJustify::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ table::CellHoriJustify nValue = table::CellHoriJustify_LEFT;
+ rValue >>= nValue;
+ if (nValue != table::CellHoriJustify_REPEAT)
+ {
+ if (IsXMLToken(rStrImpValue, XML_START))
+ {
+ nValue = table::CellHoriJustify_LEFT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_END))
+ {
+ nValue = table::CellHoriJustify_RIGHT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_CENTER))
+ {
+ nValue = table::CellHoriJustify_CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_JUSTIFY))
+ {
+ nValue = table::CellHoriJustify_BLOCK;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ }
+ else
+ bRetval = sal_True;
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustify::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellHoriJustify_REPEAT:
+ case table::CellHoriJustify_LEFT:
+ {
+ rStrExpValue = GetXMLToken(XML_START);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_RIGHT:
+ {
+ rStrExpValue = GetXMLToken(XML_END);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_CENTER:
+ {
+ rStrExpValue = GetXMLToken(XML_CENTER);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellHoriJustify_BLOCK:
+ {
+ rStrExpValue = GetXMLToken(XML_JUSTIFY);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustifySource::~XmlScPropHdl_HoriJustifySource()
+{
+}
+
+bool XmlScPropHdl_HoriJustifySource::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifySource::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (IsXMLToken(rStrImpValue, XML_FIX))
+ {
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_VALUE_TYPE))
+ {
+ table::CellHoriJustify nValue(table::CellHoriJustify_STANDARD);
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifySource::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ if (nVal == table::CellHoriJustify_STANDARD)
+ {
+ rStrExpValue = GetXMLToken(XML_VALUE_TYPE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_FIX);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_HoriJustifyRepeat::~XmlScPropHdl_HoriJustifyRepeat()
+{
+}
+
+bool XmlScPropHdl_HoriJustifyRepeat::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellHoriJustify aHoriJustify1, aHoriJustify2;
+
+ if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2))
+ return (aHoriJustify1 == aHoriJustify2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifyRepeat::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (IsXMLToken(rStrImpValue, XML_FALSE))
+ {
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TRUE))
+ {
+ table::CellHoriJustify nValue = table::CellHoriJustify_REPEAT;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_HoriJustifyRepeat::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellHoriJustify nVal;
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ if (nVal == table::CellHoriJustify_REPEAT)
+ {
+ rStrExpValue = GetXMLToken(XML_TRUE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_FALSE);
+ bRetval = sal_True;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_Orientation::~XmlScPropHdl_Orientation()
+{
+}
+
+bool XmlScPropHdl_Orientation::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ table::CellOrientation aOrientation1, aOrientation2;
+
+ if((r1 >>= aOrientation1) && (r2 >>= aOrientation2))
+ return (aOrientation1 == aOrientation2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_Orientation::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ table::CellOrientation nValue;
+ if (IsXMLToken(rStrImpValue, XML_LTR))
+ {
+ nValue = table::CellOrientation_STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TTB))
+ {
+ nValue = table::CellOrientation_STACKED;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_Orientation::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ table::CellOrientation nVal;
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellOrientation_STACKED :
+ {
+ rStrExpValue = GetXMLToken(XML_TTB);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ rStrExpValue = GetXMLToken(XML_LTR);
+ bRetval = sal_True;
+ }
+ break;
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_RotateAngle::~XmlScPropHdl_RotateAngle()
+{
+}
+
+bool XmlScPropHdl_RotateAngle::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Int32 aAngle1 = 0, aAngle2 = 0;
+
+ if((r1 >>= aAngle1) && (r2 >>= aAngle2))
+ return (aAngle1 == aAngle2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_RotateAngle::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ sal_Int32 nValue;
+ if (SvXMLUnitConverter::convertNumber(nValue, rStrImpValue))
+ {
+ nValue *= 100;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_RotateAngle::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Int32 nVal = 0;
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ rtl::OUStringBuffer sValue;
+ SvXMLUnitConverter::convertNumber(sValue, sal_Int32(nVal / 100));
+ rStrExpValue = sValue.makeStringAndClear();
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_RotateReference::~XmlScPropHdl_RotateReference()
+{
+}
+
+bool XmlScPropHdl_RotateReference::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Int32 aReference1(0), aReference2(0);
+
+ if((r1 >>= aReference1) && (r2 >>= aReference2))
+ return (aReference1 == aReference2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_RotateReference::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ sal_Int32 nValue;
+ if (IsXMLToken(rStrImpValue, XML_NONE))
+ {
+ nValue = table::CellVertJustify2::STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_BOTTOM))
+ {
+ nValue = table::CellVertJustify2::BOTTOM;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TOP))
+ {
+ nValue = table::CellVertJustify2::TOP;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_CENTER))
+ {
+ nValue = table::CellVertJustify2::CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_RotateReference::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Int32 nVal(0);
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellVertJustify2::BOTTOM :
+ {
+ rStrExpValue = GetXMLToken(XML_BOTTOM);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::CENTER :
+ {
+ rStrExpValue = GetXMLToken(XML_CENTER);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::STANDARD :
+ {
+ rStrExpValue = GetXMLToken(XML_NONE);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::TOP :
+ {
+ rStrExpValue = GetXMLToken(XML_TOP);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_VertJustify::~XmlScPropHdl_VertJustify()
+{
+}
+
+bool XmlScPropHdl_VertJustify::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Int32 aReference1(0), aReference2(0);
+
+ if((r1 >>= aReference1) && (r2 >>= aReference2))
+ return (aReference1 == aReference2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_VertJustify::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ sal_Int32 nValue;
+ if (IsXMLToken(rStrImpValue, XML_AUTOMATIC))
+ {
+ nValue = table::CellVertJustify2::STANDARD;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_BOTTOM))
+ {
+ nValue = table::CellVertJustify2::BOTTOM;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_TOP))
+ {
+ nValue = table::CellVertJustify2::TOP;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_MIDDLE))
+ {
+ nValue = table::CellVertJustify2::CENTER;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_JUSTIFY))
+ {
+ nValue = table::CellVertJustify2::BLOCK;
+ rValue <<= nValue;
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_VertJustify::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Int32 nVal(0);
+ sal_Bool bRetval(false);
+
+ if(rValue >>= nVal)
+ {
+ switch (nVal)
+ {
+ case table::CellVertJustify2::BOTTOM :
+ {
+ rStrExpValue = GetXMLToken(XML_BOTTOM);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::CENTER :
+ {
+ rStrExpValue = GetXMLToken(XML_MIDDLE);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::STANDARD :
+ {
+ rStrExpValue = GetXMLToken(XML_AUTOMATIC);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::TOP :
+ {
+ rStrExpValue = GetXMLToken(XML_TOP);
+ bRetval = sal_True;
+ }
+ break;
+ case table::CellVertJustify2::BLOCK :
+ {
+ rStrExpValue = GetXMLToken(XML_JUSTIFY);
+ bRetval = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_BreakBefore::~XmlScPropHdl_BreakBefore()
+{
+}
+
+bool XmlScPropHdl_BreakBefore::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ sal_Bool aBreak1 = 0, aBreak2 = 0;
+
+ if((r1 >>= aBreak1) && (r2 >>= aBreak2))
+ return (aBreak1 == aBreak2);
+ return false;
+}
+
+sal_Bool XmlScPropHdl_BreakBefore::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ sal_Bool bValue;
+ if (IsXMLToken(rStrImpValue, XML_AUTO))
+ {
+ bValue = false;
+ rValue = ::cppu::bool2any(bValue);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_PAGE))
+ {
+ bValue = sal_True;
+ rValue = ::cppu::bool2any(bValue);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_BreakBefore::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if(::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_PAGE);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_AUTO);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+XmlScPropHdl_IsTextWrapped::~XmlScPropHdl_IsTextWrapped()
+{
+}
+
+bool XmlScPropHdl_IsTextWrapped::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ return (::cppu::any2bool(r1) == ::cppu::any2bool(r2));
+}
+
+sal_Bool XmlScPropHdl_IsTextWrapped::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (IsXMLToken(rStrImpValue, XML_WRAP))
+ {
+ rValue = ::cppu::bool2any(sal_True);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_NO_WRAP))
+ {
+ rValue = ::cppu::bool2any(false);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_IsTextWrapped::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_WRAP);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_NO_WRAP);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_IsEqual::importXML( const ::rtl::OUString& /* rStrImpValue */,
+ ::com::sun::star::uno::Any& /* rValue */,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ OSL_FAIL("should never be called");
+ return false;
+}
+
+sal_Bool XmlScPropHdl_IsEqual::exportXML( ::rtl::OUString& /* rStrExpValue */,
+ const ::com::sun::star::uno::Any& /* rValue */,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ OSL_FAIL("should never be called");
+ return false;
+}
+
+XmlScPropHdl_Vertical::~XmlScPropHdl_Vertical()
+{
+}
+
+bool XmlScPropHdl_Vertical::equals(
+ const ::com::sun::star::uno::Any& r1,
+ const ::com::sun::star::uno::Any& r2 ) const
+{
+ return (::cppu::any2bool(r1) == ::cppu::any2bool(r2));
+}
+
+sal_Bool XmlScPropHdl_Vertical::importXML(
+ const ::rtl::OUString& rStrImpValue,
+ ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (IsXMLToken(rStrImpValue, XML_AUTO))
+ {
+ rValue = ::cppu::bool2any(sal_True);
+ bRetval = sal_True;
+ }
+ else if (IsXMLToken(rStrImpValue, XML_0))
+ {
+ rValue = ::cppu::bool2any(false);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+sal_Bool XmlScPropHdl_Vertical::exportXML(
+ ::rtl::OUString& rStrExpValue,
+ const ::com::sun::star::uno::Any& rValue,
+ const SvXMLUnitConverter& /* rUnitConverter */ ) const
+{
+ sal_Bool bRetval(false);
+
+ if (::cppu::any2bool(rValue))
+ {
+ rStrExpValue = GetXMLToken(XML_AUTO);
+ bRetval = sal_True;
+ }
+ else
+ {
+ rStrExpValue = GetXMLToken(XML_0);
+ bRetval = sal_True;
+ }
+
+ return bRetval;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlstyle.hxx b/sc/source/filter/xml/xmlstyle.hxx
new file mode 100644
index 000000000000..07a4d307a2c3
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyle.hxx
@@ -0,0 +1,363 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLE_HXX
+#define SC_XMLSTYLE_HXX
+
+#include <xmloff/maptype.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/xmltypes.hxx>
+#include <xmloff/xmlprmap.hxx>
+#include <xmloff/prhdlfac.hxx>
+#include <xmloff/styleexp.hxx>
+#include <xmloff/xmlexppr.hxx>
+#include <xmloff/contextid.hxx>
+
+extern const XMLPropertyMapEntry aXMLScCellStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScColumnStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScRowStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScRowStylesImportProperties[];
+extern const XMLPropertyMapEntry aXMLScTableStylesProperties[];
+extern const XMLPropertyMapEntry aXMLScTableStylesImportProperties[];
+
+//CellStyles
+#define XML_SC_TYPE_CELLPROTECTION (XML_SC_TYPES_START + 1)
+#define XML_SC_TYPE_PRINTCONTENT (XML_SC_TYPES_START + 2)
+#define XML_SC_TYPE_HORIJUSTIFY (XML_SC_TYPES_START + 3)
+#define XML_SC_TYPE_HORIJUSTIFY_METHOD (XML_SC_TYPES_START + 4)
+#define XML_SC_TYPE_HORIJUSTIFYSOURCE (XML_SC_TYPES_START + 5)
+#define XML_SC_TYPE_HORIJUSTIFYREPEAT (XML_SC_TYPES_START + 6)
+#define XML_SC_TYPE_ORIENTATION (XML_SC_TYPES_START + 7)
+#define XML_SC_TYPE_ROTATEANGLE (XML_SC_TYPES_START + 8)
+#define XML_SC_TYPE_ROTATEREFERENCE (XML_SC_TYPES_START + 9)
+#define XML_SC_TYPE_BORDERLEFT (XML_SC_TYPES_START + 10)
+#define XML_SC_TYPE_BORDERRIGHT (XML_SC_TYPES_START + 11)
+#define XML_SC_TYPE_BORDERTOP (XML_SC_TYPES_START + 12)
+#define XML_SC_TYPE_BORDERBOTTOM (XML_SC_TYPES_START + 13)
+#define XML_SC_TYPE_VERTJUSTIFY (XML_SC_TYPES_START + 14)
+#define XML_SC_TYPE_VERTJUSTIFY_METHOD (XML_SC_TYPES_START + 15)
+#define XML_SC_ISTEXTWRAPPED (XML_SC_TYPES_START + 16)
+#define XML_SC_TYPE_EQUAL (XML_SC_TYPES_START + 17)
+#define XML_SC_TYPE_VERTICAL (XML_SC_TYPES_START + 18)
+
+#define CTF_SC_HORIJUSTIFY (XML_SC_CTF_START + 1)
+#define CTF_SC_HORIJUSTIFY_SOURCE (XML_SC_CTF_START + 2)
+#define CTF_SC_ALLPADDING (XML_SC_CTF_START + 3)
+#define CTF_SC_BOTTOMPADDING (XML_SC_CTF_START + 4)
+#define CTF_SC_LEFTPADDING (XML_SC_CTF_START + 5)
+#define CTF_SC_RIGHTPADDING (XML_SC_CTF_START + 6)
+#define CTF_SC_TOPPADDING (XML_SC_CTF_START + 7)
+#define CTF_SC_ALLBORDER (XML_SC_CTF_START + 8)
+#define CTF_SC_LEFTBORDER (XML_SC_CTF_START + 9)
+#define CTF_SC_RIGHTBORDER (XML_SC_CTF_START + 10)
+#define CTF_SC_TOPBORDER (XML_SC_CTF_START + 11)
+#define CTF_SC_BOTTOMBORDER (XML_SC_CTF_START + 12)
+#define CTF_SC_ALLBORDERWIDTH (XML_SC_CTF_START + 13)
+#define CTF_SC_LEFTBORDERWIDTH (XML_SC_CTF_START + 14)
+#define CTF_SC_RIGHTBORDERWIDTH (XML_SC_CTF_START + 15)
+#define CTF_SC_TOPBORDERWIDTH (XML_SC_CTF_START + 16)
+#define CTF_SC_BOTTOMBORDERWIDTH (XML_SC_CTF_START + 17)
+#define CTF_SC_NUMBERFORMAT (XML_SC_CTF_START + 18)
+#define CTF_SC_MAP (XML_SC_CTF_START + 19)
+#define CTF_SC_PARAINDENT (XML_SC_CTF_START + 20)
+#define CTF_SC_OLDTEXTBACKGROUND (XML_SC_CTF_START + 21)
+#define CTF_SC_IMPORT_MAP (XML_SC_CTF_START + 22)
+#define CTF_SC_CELLSTYLE (XML_SC_CTF_START + 23)
+#define CTF_SC_VALIDATION (XML_SC_CTF_START + 24)
+#define CTF_SC_DIAGONALTLBR (XML_SC_CTF_START + 25)
+#define CTF_SC_DIAGONALTLBRWIDTH (XML_SC_CTF_START + 26)
+#define CTF_SC_DIAGONALBLTR (XML_SC_CTF_START + 27)
+#define CTF_SC_DIAGONALBLTRWIDTH (XML_SC_CTF_START + 28)
+#define CTF_SC_DIAGONALTLBRWIDTHS (XML_SC_CTF_START + 29)
+#define CTF_SC_DIAGONALBLTRWIDTHS (XML_SC_CTF_START + 30)
+
+#define CTF_SC_ROWHEIGHT (XML_SC_CTF_START + 50)
+#define CTF_SC_ROWOPTIMALHEIGHT (XML_SC_CTF_START + 51)
+#define CTF_SC_ROWBREAKBEFORE (XML_SC_CTF_START + 52)
+#define CTF_SC_ISVISIBLE (XML_SC_CTF_START + 53)
+
+#define CTF_SC_MASTERPAGENAME (XML_SC_CTF_START + 53)
+
+//ColumnStyles
+#define XML_SC_TYPE_BREAKBEFORE (XML_SC_TYPES_START + 50)
+
+class ScXMLExport;
+class ScXMLImport;
+
+class ScXMLCellExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+ /** Application-specific filter. By default do nothing. */
+ virtual void ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > rPropSet ) const;
+public:
+ ScXMLCellExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLCellExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLRowExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+ /** Application-specific filter. By default do nothing. */
+ virtual void ContextFilter(
+ ::std::vector< XMLPropertyState >& rProperties,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > rPropSet ) const;
+public:
+ ScXMLRowExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLRowExportPropertyMapper();
+};
+
+class ScXMLColumnExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+public:
+ ScXMLColumnExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLColumnExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLTableExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+protected:
+public:
+ ScXMLTableExportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper );
+ virtual ~ScXMLTableExportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
+ virtual void handleSpecialItem(
+ SvXMLAttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties = 0,
+ sal_uInt32 nIdx = 0 ) const;
+};
+
+class ScXMLAutoStylePoolP : public SvXMLAutoStylePoolP
+{
+ ScXMLExport& rScXMLExport;
+
+ virtual void exportStyleAttributes(
+ SvXMLAttributeList& rAttrList,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const;
+
+ virtual void exportStyleContent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler,
+ sal_Int32 nFamily,
+ const ::std::vector< XMLPropertyState >& rProperties,
+ const SvXMLExportPropertyMapper& rPropExp
+ , const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap
+ ) const;
+
+public:
+ ScXMLAutoStylePoolP(ScXMLExport& rScXMLExport);
+ virtual ~ScXMLAutoStylePoolP();
+};
+
+class ScXMLStyleExport : public XMLStyleExport
+{
+ virtual void exportStyleAttributes(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle );
+ virtual void exportStyleContent(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::style::XStyle > & rStyle );
+public:
+ ScXMLStyleExport(
+ SvXMLExport& rExp,
+ const ::rtl::OUString& rPoolStyleName,
+ SvXMLAutoStylePoolP *pAutoStyleP=0 );
+ virtual ~ScXMLStyleExport();
+};
+
+class XMLScPropHdlFactory : public XMLPropertyHandlerFactory
+{
+public:
+ XMLScPropHdlFactory();
+ virtual ~XMLScPropHdlFactory();
+ virtual const XMLPropertyHandler* GetPropertyHandler( sal_Int32 nType ) const;
+};
+
+class XmlScPropHdl_CellProtection : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_CellProtection();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_PrintContent : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_PrintContent();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_JustifyMethod : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_JustifyMethod();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustify : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustify();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustifySource : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustifySource();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_HoriJustifyRepeat : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_HoriJustifyRepeat();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_Orientation : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_Orientation();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_RotateAngle : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_RotateAngle();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_RotateReference : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_RotateReference();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_VertJustify : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_VertJustify();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_BreakBefore : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_BreakBefore();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_IsTextWrapped : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_IsTextWrapped();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_IsEqual : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_IsEqual() {}
+ virtual bool equals( const ::com::sun::star::uno::Any& /* r1 */, const ::com::sun::star::uno::Any& /* r2 */ ) const { return sal_True; }
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+class XmlScPropHdl_Vertical : public XMLPropertyHandler
+{
+public:
+ virtual ~XmlScPropHdl_Vertical();
+ virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+ virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
new file mode 100644
index 000000000000..19dc029e4efb
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -0,0 +1,1092 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "xmlstyli.hxx"
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include <xmloff/XMLGraphicsDefaultStyle.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <comphelper/extract.hxx>
+#include <xmloff/xmlprcon.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <tools/debug.hxx>
+#include "XMLTableHeaderFooterContext.hxx"
+#include "XMLConverter.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "xmlannoi.hxx"
+#include "textuno.hxx"
+#include "cellsuno.hxx"
+
+#include "docuno.hxx"
+#include "unonames.hxx"
+#include "document.hxx"
+
+#define XML_LINE_LEFT 0
+#define XML_LINE_RIGHT 1
+#define XML_LINE_TOP 2
+#define XML_LINE_BOTTOM 3
+
+#define XML_LINE_TLBR 0
+#define XML_LINE_BLTR 1
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace xmloff::token;
+using namespace ::formula;
+
+using rtl::OUString;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::UNO_QUERY;
+
+ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImportP) :
+ SvXMLImportPropertyMapper( rMapper, rImportP )
+{
+}
+
+ScXMLCellImportPropertyMapper::~ScXMLCellImportPropertyMapper()
+{
+}
+
+void ScXMLCellImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
+{
+ static const sal_Int16 aPaddingCTF[4] = { CTF_SC_LEFTPADDING, CTF_SC_RIGHTPADDING,
+ CTF_SC_TOPPADDING, CTF_SC_BOTTOMPADDING };
+ static const sal_Int16 aBorderCTF[4] = { CTF_SC_LEFTBORDER, CTF_SC_RIGHTBORDER,
+ CTF_SC_TOPBORDER, CTF_SC_BOTTOMBORDER };
+
+ SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
+ XMLPropertyState* pAllPaddingProperty(NULL);
+ XMLPropertyState* pPadding[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pNewPadding[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pAllBorderProperty = NULL;
+ XMLPropertyState* pBorders[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pNewBorders[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pAllBorderWidthProperty = NULL;
+ XMLPropertyState* pBorderWidths[4] = { NULL, NULL, NULL, NULL };
+ XMLPropertyState* pDiagBorders[2] = { 0 };
+ XMLPropertyState* pOldDiagBorderWidths[2] = { 0 }; // old attribute names without "s"
+ XMLPropertyState* pDiagBorderWidths[2] = { 0 };
+
+ ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end());
+ for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != endproperty; ++aIter)
+ {
+ XMLPropertyState*property = &(*aIter);
+ if (property->mnIndex != -1)
+ {
+ sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_ALLPADDING : pAllPaddingProperty = &*property; break;
+ case CTF_SC_LEFTPADDING : pPadding[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTPADDING : pPadding[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPPADDING : pPadding[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMPADDING : pPadding[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_ALLBORDER : pAllBorderProperty = &*property; break;
+ case CTF_SC_LEFTBORDER : pBorders[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTBORDER : pBorders[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPBORDER : pBorders[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMBORDER : pBorders[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_ALLBORDERWIDTH : pAllBorderWidthProperty = &*property; break;
+ case CTF_SC_LEFTBORDERWIDTH : pBorderWidths[XML_LINE_LEFT] = &*property; break;
+ case CTF_SC_RIGHTBORDERWIDTH : pBorderWidths[XML_LINE_RIGHT] = &*property; break;
+ case CTF_SC_TOPBORDERWIDTH : pBorderWidths[XML_LINE_TOP] = &*property; break;
+ case CTF_SC_BOTTOMBORDERWIDTH : pBorderWidths[XML_LINE_BOTTOM] = &*property; break;
+ case CTF_SC_DIAGONALTLBR : pDiagBorders[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALBLTR : pDiagBorders[XML_LINE_BLTR] = &*property; break;
+ case CTF_SC_DIAGONALTLBRWIDTH : pOldDiagBorderWidths[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALTLBRWIDTHS : pDiagBorderWidths[XML_LINE_TLBR] = &*property; break;
+ case CTF_SC_DIAGONALBLTRWIDTH : pOldDiagBorderWidths[XML_LINE_BLTR] = &*property; break;
+ case CTF_SC_DIAGONALBLTRWIDTHS : pDiagBorderWidths[XML_LINE_BLTR] = &*property; break;
+ }
+ }
+ }
+ sal_uInt16 i;
+
+ // #i27594#; copy Value, but don't insert
+ if (pAllBorderWidthProperty)
+ pAllBorderWidthProperty->mnIndex = -1;
+ if (pAllBorderProperty)
+ pAllBorderProperty->mnIndex = -1;
+ if (pAllPaddingProperty)
+ pAllPaddingProperty->mnIndex = -1;
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (pAllPaddingProperty && !pPadding[i])
+ pNewPadding[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aPaddingCTF[i]), pAllPaddingProperty->maValue);
+ if (pAllBorderProperty && !pBorders[i])
+ {
+ pNewBorders[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aBorderCTF[i]), pAllBorderProperty->maValue);
+ pBorders[i] = pNewBorders[i];
+ }
+ if( !pBorderWidths[i] )
+ pBorderWidths[i] = pAllBorderWidthProperty;
+ else
+ pBorderWidths[i]->mnIndex = -1;
+ if( pBorders[i] )
+ {
+ table::BorderLine2 aBorderLine;
+ pBorders[i]->maValue >>= aBorderLine;
+ if( pBorderWidths[i] )
+ {
+ table::BorderLine2 aBorderLineWidth;
+ pBorderWidths[i]->maValue >>= aBorderLineWidth;
+ aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
+ aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
+ aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
+ aBorderLine.LineWidth = aBorderLineWidth.LineWidth;
+ pBorders[i]->maValue <<= aBorderLine;
+ }
+ }
+ }
+ for( i = 0; i < 2; ++i )
+ {
+ if( pDiagBorders[i] && ( pDiagBorderWidths[i] || pOldDiagBorderWidths[i] ) )
+ {
+ table::BorderLine2 aBorderLine;
+ pDiagBorders[i]->maValue >>= aBorderLine;
+ table::BorderLine2 aBorderLineWidth;
+ if (pDiagBorderWidths[i])
+ pDiagBorderWidths[i]->maValue >>= aBorderLineWidth; // prefer new attribute
+ else
+ pOldDiagBorderWidths[i]->maValue >>= aBorderLineWidth;
+ aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
+ aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
+ aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
+ aBorderLine.LineWidth = aBorderLineWidth.LineWidth;
+ pDiagBorders[i]->maValue <<= aBorderLine;
+ if (pDiagBorderWidths[i])
+ pDiagBorderWidths[i]->mnIndex = -1;
+ if (pOldDiagBorderWidths[i])
+ pOldDiagBorderWidths[i]->mnIndex = -1; // reset mnIndex for old and new attribute if both are present
+ }
+ }
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (pNewPadding[i])
+ {
+ rProperties.push_back(*pNewPadding[i]);
+ delete pNewPadding[i];
+ }
+ if (pNewBorders[i])
+ {
+ rProperties.push_back(*pNewBorders[i]);
+ delete pNewBorders[i];
+ }
+ }
+}
+
+ScXMLRowImportPropertyMapper::ScXMLRowImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImportP) :
+ SvXMLImportPropertyMapper( rMapper, rImportP )
+{
+}
+
+ScXMLRowImportPropertyMapper::~ScXMLRowImportPropertyMapper()
+{
+}
+
+void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
+{
+ SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
+ XMLPropertyState* pHeight(NULL);
+ XMLPropertyState* pOptimalHeight(NULL);
+ XMLPropertyState* pPageBreak(NULL);
+ ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end());
+ for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin();
+ aIter != endproperty; ++aIter)
+ {
+ XMLPropertyState* property = &(*aIter);
+ if (property->mnIndex != -1)
+ {
+ sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
+ switch (nContextID)
+ {
+ case CTF_SC_ROWHEIGHT : pHeight = property; break;
+ case CTF_SC_ROWOPTIMALHEIGHT : pOptimalHeight = property; break;
+ case CTF_SC_ROWBREAKBEFORE : pPageBreak = property; break;
+ }
+ }
+ }
+ if (pPageBreak)
+ {
+ if(!(::cppu::any2bool(pPageBreak->maValue)))
+ pPageBreak->mnIndex = -1;
+ }
+ if (pOptimalHeight)
+ {
+ if (::cppu::any2bool(pOptimalHeight->maValue))
+ {
+ if (pHeight)
+ {
+ // set the stored height, but keep "optimal" flag:
+ // pass the height value as OptimalHeight property (only allowed while loading!)
+ pOptimalHeight->maValue = pHeight->maValue;
+ pHeight->mnIndex = -1;
+ }
+ else
+ pOptimalHeight->mnIndex = -1;
+ }
+ }
+ else if (pHeight)
+ {
+ rProperties.push_back(XMLPropertyState(maPropMapper->FindEntryIndex(CTF_SC_ROWOPTIMALHEIGHT), ::cppu::bool2any( false )));
+ }
+ // don't access pointers to rProperties elements after push_back!
+}
+
+class ScXMLMapContext : public SvXMLImportContext
+{
+ rtl::OUString sApplyStyle;
+ rtl::OUString sCondition;
+ rtl::OUString sBaseCell;
+public:
+
+ ScXMLMapContext(
+ SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const rtl::OUString& rLName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+ virtual ~ScXMLMapContext();
+
+ const rtl::OUString& GetApplyStyle() const { return sApplyStyle; }
+ const rtl::OUString& GetCondition() const { return sCondition; }
+ const rtl::OUString& GetBaseCell() const { return sBaseCell; }
+};
+
+ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName, const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+ : SvXMLImportContext( rImport, nPrfx, rLName )
+{
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ OUString aLocalName;
+ sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ const OUString& rValue(xAttrList->getValueByIndex( i ));
+
+ // TODO: use a map here
+ if( XML_NAMESPACE_STYLE == nPrefix )
+ {
+ if( IsXMLToken(aLocalName, XML_CONDITION ) )
+ sCondition = rValue;
+ else if( IsXMLToken(aLocalName, XML_APPLY_STYLE_NAME ) )
+ sApplyStyle = GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, rValue);
+ else if ( IsXMLToken(aLocalName, XML_BASE_CELL_ADDRESS ) )
+ sBaseCell = rValue;
+ }
+ }
+}
+
+ScXMLMapContext::~ScXMLMapContext()
+{
+}
+
+namespace {
+
+template< typename Type >
+inline void lclAppendProperty( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rPropName, const Type& rValue )
+{
+ sal_Int32 nLength = rProps.getLength();
+ rProps.realloc( nLength + 1 );
+ rProps[ nLength ].Name = rPropName;
+ rProps[ nLength ].Value <<= rValue;
+}
+
+} // namespace
+
+void XMLTableStyleContext::SetOperator( uno::Sequence< beans::PropertyValue >& rProps, sheet::ConditionOperator eOp ) const
+{
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_OPERATOR ) ), eOp );
+}
+
+void XMLTableStyleContext::SetBaseCellAddress( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rBaseCell ) const
+{
+ /* Source position must be set as string, because it may refer
+ to a sheet that hasn't been loaded yet. */
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SOURCESTR ) ), rBaseCell );
+}
+
+void XMLTableStyleContext::SetStyle( uno::Sequence<beans::PropertyValue>& rProps, const OUString& rApplyStyle ) const
+{
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_STYLENAME ) ), rApplyStyle );
+}
+
+void XMLTableStyleContext::SetFormula( uno::Sequence< beans::PropertyValue >& rProps,
+ sal_Int32 nFormulaIdx, const OUString& rFormula, const OUString& rFormulaNmsp,
+ FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const
+{
+ OUString aFormula, aFormulaNmsp;
+ FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
+ {
+ // the entire attribute contains a namespace: internal namespace not allowed
+ aFormula = rFormula;
+ aFormulaNmsp = rFormulaNmsp;
+ eNewGrammar = eGrammar;
+ }
+ else
+ {
+ // the attribute does not contain a namespace: try to find a namespace of an external grammar
+ GetScImport().ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eNewGrammar, rFormula, true );
+ if( eNewGrammar != FormulaGrammar::GRAM_EXTERNAL )
+ eNewGrammar = eGrammar;
+ }
+
+ // add formula, formula namespace, and grammar with appropriate property names
+ sal_Int32 nGrammar = static_cast< sal_Int32 >( eNewGrammar );
+ switch( nFormulaIdx )
+ {
+ case 1:
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA1 ) ), aFormula );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP1 ) ), aFormulaNmsp );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR1 ) ), nGrammar );
+ break;
+ case 2:
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA2 ) ), aFormula );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP2 ) ), aFormulaNmsp );
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR2 ) ), nGrammar );
+ break;
+ default:
+ OSL_FAIL( "XMLTableStyleContext::SetFormula - invalid formula index" );
+ }
+}
+
+void XMLTableStyleContext::GetConditionalFormat(uno::Any& aAny,
+ const rtl::OUString& sTempCondition,
+ const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const
+{
+ if (sTempCondition.getLength() && sApplyStyle.getLength())
+ {
+ uno::Reference<sheet::XSheetConditionalEntries> xConditionalEntries(aAny, uno::UNO_QUERY);
+ if (xConditionalEntries.is())
+ {
+ uno::Sequence<beans::PropertyValue> aProps;
+ if (sBaseCell.getLength())
+ SetBaseCellAddress(aProps, sBaseCell);
+ SetStyle(aProps, sApplyStyle);
+
+ // extract leading namespace from condition string
+ OUString aCondition, aConditionNmsp;
+ FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sTempCondition );
+ bool bHasNmsp = aCondition.getLength() < sTempCondition.getLength();
+
+ // parse a condition from the attribute string
+ ScXMLConditionParseResult aParseResult;
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
+
+ /* Check the result. A valid value in aParseResult.meToken implies
+ that the other members of aParseResult are filled with valid
+ data for that token. */
+ switch( aParseResult.meToken )
+ {
+ case XML_COND_CELLCONTENT: // condition is 'cell-content()<operator><expression>'
+ case XML_COND_ISTRUEFORMULA: // condition is 'is-true-formula(<expression>)'
+ case XML_COND_ISBETWEEN: // condition is 'cell-content-is-between(<expression1>,<expression2>)'
+ case XML_COND_ISNOTBETWEEN: // condition is 'cell-content-is-not-between(<expression1>,<expression2>)'
+ SetOperator( aProps, aParseResult.meOperator );
+ SetFormula( aProps, 1, aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp );
+ SetFormula( aProps, 2, aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp );
+ break;
+
+ default:; // unacceptable or unknown condition
+ }
+
+ xConditionalEntries->addNew( aProps );
+ aAny <<= xConditionalEntries;
+ }
+ }
+}
+
+void XMLTableStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
+ const OUString& rLocalName,
+ const OUString& rValue )
+{
+ // TODO: use a map here
+ if( IsXMLToken(rLocalName, XML_DATA_STYLE_NAME ) )
+ sDataStyleName = rValue;
+ else if ( IsXMLToken(rLocalName, XML_MASTER_PAGE_NAME ) )
+ sPageStyle = rValue;
+ else
+ XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
+}
+
+struct ScXMLMapContent
+{
+ rtl::OUString sCondition;
+ rtl::OUString sApplyStyle;
+ rtl::OUString sBaseCell;
+};
+
+TYPEINIT1( XMLTableStyleContext, XMLPropStyleContext );
+
+XMLTableStyleContext::XMLTableStyleContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) :
+ XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
+ sDataStyleName(),
+ sNumberFormat(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))),
+ pStyles(&rStyles),
+ nNumberFormat(-1),
+ nLastSheet(-1),
+ bConditionalFormatCreated(false),
+ bParentSet(false)
+{
+}
+
+XMLTableStyleContext::~XMLTableStyleContext()
+{
+}
+
+SvXMLImportContext *XMLTableStyleContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ SvXMLImportContext *pContext(NULL);
+
+ if( (XML_NAMESPACE_STYLE == nPrefix) &&
+ IsXMLToken(rLocalName, XML_MAP ) )
+ {
+ pContext = new ScXMLMapContext(GetImport(), nPrefix, rLocalName, xAttrList);
+
+ ScXMLMapContent aMap;
+ aMap.sCondition = ((ScXMLMapContext*)pContext)->GetCondition();
+ aMap.sApplyStyle = ((ScXMLMapContext*)pContext)->GetApplyStyle();
+ aMap.sBaseCell = ((ScXMLMapContext*)pContext)->GetBaseCell();
+ aMaps.push_back(aMap);
+ }
+ if (!pContext)
+ pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
+ xAttrList );
+ return pContext;
+}
+
+void XMLTableStyleContext::FillPropertySet(
+ const uno::Reference< XPropertySet > & rPropSet )
+{
+ if (!IsDefaultStyle())
+ {
+ if (GetFamily() == XML_STYLE_FAMILY_TABLE_CELL)
+ {
+ if (!bParentSet)
+ {
+ AddProperty(CTF_SC_CELLSTYLE, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, GetParentName() )));
+ bParentSet = sal_True;
+ }
+ sal_Int32 nNumFmt = GetNumberFormat();
+ if (nNumFmt >= 0)
+ AddProperty(CTF_SC_NUMBERFORMAT, uno::makeAny(nNumFmt));
+ if (!bConditionalFormatCreated && (aMaps.size() > 0))
+ {
+ aConditionalFormat = rPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONDXML)));
+ std::vector<ScXMLMapContent>::iterator aItr(aMaps.begin());
+ std::vector<ScXMLMapContent>::iterator aEndItr(aMaps.end());
+ while(aItr != aEndItr)
+ {
+ //rPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CONDITIONALFORMAT)),
+ GetConditionalFormat(aConditionalFormat, aItr->sCondition, aItr->sApplyStyle, aItr->sBaseCell);
+
+ ++aItr;
+ }
+ AddProperty(CTF_SC_IMPORT_MAP, aConditionalFormat);
+ bConditionalFormatCreated = sal_True;
+ }
+ }
+ else if (GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE)
+ {
+ if (sPageStyle.getLength())
+ AddProperty(CTF_SC_MASTERPAGENAME, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle )));
+ }
+ }
+ XMLPropStyleContext::FillPropertySet(rPropSet);
+}
+
+void XMLTableStyleContext::SetDefaults()
+{
+ if ((GetFamily() == XML_STYLE_FAMILY_TABLE_CELL) && GetImport().GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetImport().GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY);
+ if (xProperties.is())
+ FillPropertySet(xProperties);
+ }
+ }
+}
+
+void XMLTableStyleContext::AddProperty(const sal_Int16 nContextID, const uno::Any& rValue)
+{
+ XMLPropertyState* property = FindProperty(nContextID);
+ if (property)
+ property->mnIndex = -1; // #i46996# remove old property, so it isn't double
+ sal_Int32 nIndex(static_cast<XMLTableStylesContext *>(pStyles)->GetIndex(nContextID));
+ DBG_ASSERT(nIndex != -1, "Property not found in Map");
+ XMLPropertyState aPropState(nIndex, rValue);
+ GetProperties().push_back(aPropState); // has to be insertes in a sort order later
+}
+
+XMLPropertyState* XMLTableStyleContext::FindProperty(const sal_Int16 nContextID)
+{
+ XMLPropertyState* pRet = NULL;
+ UniReference < XMLPropertySetMapper > xPrMap;
+ UniReference < SvXMLImportPropertyMapper > xImpPrMap =
+ pStyles->GetImportPropertyMapper( GetFamily() );
+ DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" );
+ if( xImpPrMap.is() )
+ xPrMap = xImpPrMap->getPropertySetMapper();
+ if( xPrMap.is() )
+ {
+ ::std::vector< XMLPropertyState >::iterator endproperty(GetProperties().end());
+ ::std::vector< XMLPropertyState >::iterator aIter(GetProperties().begin());
+ while(!pRet && aIter != endproperty)
+ {
+ XMLPropertyState* property = &(*aIter);
+ if (property->mnIndex != -1 && xPrMap->GetEntryContextId(property->mnIndex) == nContextID)
+ {
+ pRet = property;
+ }
+ else
+ ++aIter;
+ }
+ }
+ return pRet;
+}
+
+sal_Int32 XMLTableStyleContext::GetNumberFormat()
+{
+ if (nNumberFormat < 0 && sDataStyleName.getLength())
+ {
+ const SvXMLNumFormatContext* pStyle = static_cast<const SvXMLNumFormatContext*>(
+ pStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True));
+
+ if (!pStyle)
+ {
+ XMLTableStylesContext* pMyStyles = static_cast<XMLTableStylesContext*>(GetScImport().GetStyles());
+ if (pMyStyles)
+ pStyle = static_cast<const SvXMLNumFormatContext*>(
+ pMyStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True));
+ else
+ {
+ OSL_FAIL("not possible to get style");
+ }
+ }
+ if (pStyle)
+ nNumberFormat = const_cast<SvXMLNumFormatContext*>(pStyle)->GetKey();
+ }
+ return nNumberFormat;
+}
+
+// ----------------------------------------------------------------------------
+
+SvXMLStyleContext *XMLTableStylesContext::CreateStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pStyle;
+ // use own wrapper for text and paragraph, to record style usage
+ if (nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH || nFamily == XML_STYLE_FAMILY_TEXT_TEXT)
+ pStyle = new ScCellTextStyleContext( GetImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily );
+ else
+ pStyle = SvXMLStylesContext::CreateStyleStyleChildContext(
+ nFamily, nPrefix, rLocalName, xAttrList );
+
+ if (!pStyle)
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily );
+ break;
+ }
+ }
+
+ return pStyle;
+}
+
+SvXMLStyleContext *XMLTableStylesContext::CreateDefaultStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pStyle(SvXMLStylesContext::CreateDefaultStyleStyleChildContext( nFamily, nPrefix,
+ rLocalName,
+ xAttrList ));
+ if (!pStyle)
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily, sal_True);
+ break;
+ case XML_STYLE_FAMILY_SD_GRAPHICS_ID:
+ pStyle = new XMLGraphicsDefaultStyle( GetScImport(), nPrefix, rLocalName,
+ xAttrList, *this);
+ break;
+ }
+ }
+
+ return pStyle;
+}
+
+XMLTableStylesContext::XMLTableStylesContext( SvXMLImport& rImport,
+ sal_uInt16 nPrfx ,
+ const OUString& rLName ,
+ const uno::Reference< XAttributeList > & xAttrList,
+ const sal_Bool bTempAutoStyles ) :
+ SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
+ sCellStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CellStyle" ) )),
+ sColumnStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME ))),
+ sRowStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME ))),
+ sTableStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME ))),
+ nNumberFormatIndex(-1),
+ nConditionalFormatIndex(-1),
+ nCellStyleIndex(-1),
+ nMasterPageNameIndex(-1),
+ bAutoStyles(bTempAutoStyles)
+{
+}
+
+XMLTableStylesContext::~XMLTableStylesContext()
+{
+}
+
+void XMLTableStylesContext::EndElement()
+{
+ SvXMLStylesContext::EndElement();
+ if (bAutoStyles)
+ GetImport().GetTextImport()->SetAutoStyles( this );
+ else
+ ((ScXMLImport&)GetImport()).InsertStyles();
+}
+
+UniReference < SvXMLImportPropertyMapper >
+ XMLTableStylesContext::GetImportPropertyMapper(
+ sal_uInt16 nFamily ) const
+{
+ UniReference < SvXMLImportPropertyMapper > xMapper(SvXMLStylesContext::GetImportPropertyMapper(nFamily));
+
+ if (!xMapper.is())
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ {
+ if( !xCellImpPropMapper.is() )
+ {
+ ((XMLTableStylesContext *)this)->xCellImpPropMapper =
+ new ScXMLCellImportPropertyMapper( GetScImport().GetCellStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xCellImpPropMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(const_cast<SvXMLImport&>(GetImport()), const_cast<XMLFontStylesContext*>(GetScImport().GetFontDecls())));
+ }
+ xMapper = xCellImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ {
+ if( !xColumnImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xColumnImpPropMapper =
+ new SvXMLImportPropertyMapper( GetScImport().GetColumnStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xColumnImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ {
+ if( !xRowImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xRowImpPropMapper =
+ new ScXMLRowImportPropertyMapper( GetScImport().GetRowStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xRowImpPropMapper;
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ {
+ if( !xTableImpPropMapper.is() )
+ ((XMLTableStylesContext *)this)->xTableImpPropMapper =
+ new SvXMLImportPropertyMapper( GetScImport().GetTableStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
+ xMapper = xTableImpPropMapper;
+ }
+ break;
+ }
+ }
+
+ return xMapper;
+}
+
+uno::Reference < XNameContainer >
+ XMLTableStylesContext::GetStylesContainer( sal_uInt16 nFamily ) const
+{
+ uno::Reference < XNameContainer > xStyles(SvXMLStylesContext::GetStylesContainer(nFamily));
+ if (!xStyles.is())
+ {
+ OUString sName;
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ {
+ if( xTableStyles.is() )
+ xStyles.set(xTableStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "TableStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ {
+ if( xCellStyles.is() )
+ xStyles.set(xCellStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CellStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ {
+ if( xColumnStyles.is() )
+ xStyles.set(xColumnStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnStyles" ) ));
+ }
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ {
+ if( xRowStyles.is() )
+ xStyles.set(xRowStyles);
+ else
+ sName =
+ OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowStyles" ) ));
+ }
+ break;
+ }
+ if( !xStyles.is() && sName.getLength() && GetScImport().GetModel().is() )
+ {
+ uno::Reference< XStyleFamiliesSupplier > xFamiliesSupp(
+ GetScImport().GetModel(), UNO_QUERY );
+ if (xFamiliesSupp.is())
+ {
+ uno::Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies());
+
+ try
+ {
+ xStyles.set(xFamilies->getByName( sName ), uno::UNO_QUERY);
+ }
+ catch ( uno::Exception& )
+ {
+ // #i97680# Named table/column/row styles aren't supported, getByName will throw an exception.
+ // For better interoperability, these styles should then be handled as automatic styles.
+ // For now, NULL is returned (and the style is ignored).
+ }
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ ((XMLTableStylesContext *)this)->xTableStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ ((XMLTableStylesContext *)this)->xCellStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ ((XMLTableStylesContext *)this)->xColumnStyles.set(xStyles);
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ ((XMLTableStylesContext *)this)->xRowStyles.set(xStyles);
+ break;
+ }
+ }
+ }
+ }
+
+ return xStyles;
+}
+
+OUString XMLTableStylesContext::GetServiceName( sal_uInt16 nFamily ) const
+{
+ rtl::OUString sServiceName(SvXMLStylesContext::GetServiceName(nFamily));
+ if (!sServiceName.getLength())
+ {
+ switch( nFamily )
+ {
+ case XML_STYLE_FAMILY_TABLE_COLUMN:
+ sServiceName = sColumnStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_ROW:
+ sServiceName = sRowStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_CELL:
+ sServiceName = sCellStyleServiceName;
+ break;
+ case XML_STYLE_FAMILY_TABLE_TABLE:
+ sServiceName = sTableStyleServiceName;
+ break;
+ }
+ }
+ return sServiceName;
+}
+
+sal_Int32 XMLTableStylesContext::GetIndex(const sal_Int16 nContextID)
+{
+ if (nContextID == CTF_SC_CELLSTYLE)
+ {
+ if (nCellStyleIndex == -1)
+ nCellStyleIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nCellStyleIndex;
+ }
+ else if (nContextID == CTF_SC_NUMBERFORMAT)
+ {
+ if (nNumberFormatIndex == -1)
+ nNumberFormatIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nNumberFormatIndex;
+ }
+ else if (nContextID == CTF_SC_IMPORT_MAP)
+ {
+ if (nConditionalFormatIndex == -1)
+ nConditionalFormatIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nConditionalFormatIndex;
+ }
+ else if (nContextID == CTF_SC_MASTERPAGENAME)
+ {
+ if (nMasterPageNameIndex == -1)
+ nMasterPageNameIndex =
+ GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_TABLE)->getPropertySetMapper()->FindEntryIndex(nContextID);
+ return nMasterPageNameIndex;
+ }
+ else
+ return -1;
+}
+
+// ---------------------------------------------------------------------------
+TYPEINIT1( ScXMLMasterStylesContext, SvXMLStylesContext );
+
+sal_Bool ScXMLMasterStylesContext::InsertStyleFamily( sal_uInt16 ) const
+{
+ return sal_True;
+}
+
+ScXMLMasterStylesContext::ScXMLMasterStylesContext(
+ SvXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList ) :
+ SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList )
+{
+}
+
+ScXMLMasterStylesContext::~ScXMLMasterStylesContext()
+{
+}
+
+SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ SvXMLStyleContext *pContext(0);
+
+ if( (XML_NAMESPACE_STYLE == nPrefix) &&
+ IsXMLToken(rLocalName, XML_MASTER_PAGE) &&
+ InsertStyleFamily( XML_STYLE_FAMILY_MASTER_PAGE ) )
+ pContext = new ScMasterPageContext(
+ GetImport(), nPrefix, rLocalName, xAttrList,
+ !GetImport().GetTextImport()->IsInsertMode() );
+
+ // any other style will be ignored here!
+
+ return pContext;
+}
+
+SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleStyleChildContext(
+ sal_uInt16 /* nFamily */,
+ sal_uInt16 /* nPrefix */,
+ const OUString& /* rLocalName */,
+ const uno::Reference< XAttributeList > & /* xAttrList */ )
+{
+ return 0;
+}
+
+void ScXMLMasterStylesContext::EndElement()
+{
+ FinishStyles(sal_True);
+}
+
+TYPEINIT1( ScMasterPageContext, XMLTextMasterPageContext );
+
+ScMasterPageContext::ScMasterPageContext( SvXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const uno::Reference< XAttributeList > & xAttrList,
+ sal_Bool bOverwrite ) :
+ XMLTextMasterPageContext( rImport, nPrfx, rLName, xAttrList, bOverwrite ),
+ bContainsRightHeader(false),
+ bContainsRightFooter(false)
+{
+}
+
+ScMasterPageContext::~ScMasterPageContext()
+{
+}
+
+SvXMLImportContext *ScMasterPageContext::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< XAttributeList > & xAttrList )
+{
+ return XMLTextMasterPageContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
+}
+
+SvXMLImportContext *ScMasterPageContext::CreateHeaderFooterContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bFooter,
+ const sal_Bool bLeft )
+{
+ if (!bLeft)
+ {
+ if (bFooter)
+ bContainsRightFooter = sal_True;
+ else
+ bContainsRightHeader = sal_True;
+ }
+ if (!xPropSet.is())
+ xPropSet.set(GetStyle(), UNO_QUERY );
+ return new XMLTableHeaderFooterContext( GetImport(),
+ nPrefix, rLocalName,
+ xAttrList,
+ xPropSet,
+ bFooter, bLeft );
+}
+
+void ScMasterPageContext::ClearContent(const rtl::OUString& rContent)
+{
+ if (!xPropSet.is())
+ xPropSet.set(GetStyle(), UNO_QUERY );
+
+ if (xPropSet.is())
+ {
+ uno::Reference < sheet::XHeaderFooterContent > xHeaderFooterContent(xPropSet->getPropertyValue( rContent ), uno::UNO_QUERY);
+ if (xHeaderFooterContent.is())
+ {
+ xHeaderFooterContent->getLeftText()->setString(sEmpty);
+ xHeaderFooterContent->getCenterText()->setString(sEmpty);
+ xHeaderFooterContent->getRightText()->setString(sEmpty);
+ xPropSet->setPropertyValue( rContent, uno::makeAny(xHeaderFooterContent) );
+ }
+ }
+}
+
+void ScMasterPageContext::Finish( sal_Bool bOverwrite )
+{
+ XMLTextMasterPageContext::Finish(bOverwrite);
+ if (!bContainsRightFooter)
+ ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTFTRCON)));
+ if (!bContainsRightHeader)
+ ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTHDRCON)));
+}
+
+// ---------------------------------------------------------------------------
+
+ScCellTextStyleContext::ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const rtl::OUString& rLName, const uno::Reference<xml::sax::XAttributeList> & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) :
+ XMLTextStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
+ nLastSheet(-1)
+{
+}
+
+ScCellTextStyleContext::~ScCellTextStyleContext()
+{
+}
+
+void ScCellTextStyleContext::FillPropertySet( const uno::Reference<beans::XPropertySet>& xPropSet )
+{
+ XMLTextStyleContext::FillPropertySet( xPropSet );
+
+ ScXMLImport& rXMLImport = GetScImport();
+
+ ScCellTextCursor* pCellImp = ScCellTextCursor::getImplementation( xPropSet );
+ if (pCellImp)
+ {
+ ScAddress aPos = pCellImp->GetCellObj().GetPosition();
+ if ( static_cast<sal_Int32>(aPos.Tab()) != nLastSheet )
+ {
+ ESelection aSel = pCellImp->GetSelection();
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->AddTextStyle( GetName(), aPos, aSel );
+
+ nLastSheet = static_cast<sal_Int32>(aPos.Tab());
+ }
+ }
+ else if ( rXMLImport.GetTables().GetCurrentSheet() != nLastSheet )
+ {
+ ScDrawTextCursor* pDrawImp = ScDrawTextCursor::getImplementation( xPropSet );
+ if (pDrawImp)
+ {
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ ScXMLAnnotationContext* pAnnotationContext = pTableShapeImport->GetAnnotationContext();
+ if (pAnnotationContext)
+ {
+ pAnnotationContext->AddContentStyle( GetFamily(), GetName(), pDrawImp->GetSelection() );
+ nLastSheet = rXMLImport.GetTables().GetCurrentSheet();
+ }
+ }
+
+ // if it's a different shape, BlockSheet is called from XMLTableShapeImportHelper::finishShape
+ // formatted text in page headers/footers can be ignored
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx
new file mode 100644
index 000000000000..9f69acca9d51
--- /dev/null
+++ b/sc/source/filter/xml/xmlstyli.hxx
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_XMLSTYLI_HXX
+#define SC_XMLSTYLI_HXX
+
+#include <rtl/ustring.hxx>
+#include <vector>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/maptype.hxx>
+#include <xmloff/prstylei.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/XMLTextMasterPageContext.hxx>
+#include <xmloff/XMLTextMasterStylesContext.hxx>
+#include <xmloff/txtstyli.hxx>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include "xmlimprt.hxx"
+
+class ScSheetSaveData;
+
+class ScXMLCellImportPropertyMapper : public SvXMLImportPropertyMapper
+{
+protected:
+
+public:
+
+ ScXMLCellImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImport);
+ virtual ~ScXMLCellImportPropertyMapper();
+
+ /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
+/* virtual sal_Bool handleSpecialItem(
+ XMLPropertyState& rProperty,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const ::rtl::OUString& rValue,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap ) const;*/
+
+ /** this method is called for every item that has the MID_FLAG_NO_ITEM_IMPORT flag set */
+/* virtual sal_Bool handleNoItem(
+ sal_Int32 nIndex,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const ::rtl::OUString& rValue,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap ) const;*/
+
+ /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */
+ virtual void finished(
+ ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const;
+};
+
+class ScXMLRowImportPropertyMapper : public SvXMLImportPropertyMapper
+{
+protected:
+
+public:
+
+ ScXMLRowImportPropertyMapper(
+ const UniReference< XMLPropertySetMapper >& rMapper,
+ SvXMLImport& rImport);
+ virtual ~ScXMLRowImportPropertyMapper();
+
+ /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */
+ virtual void finished(
+ ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const;
+};
+struct ScXMLMapContent;
+
+class XMLTableStyleContext : public XMLPropStyleContext
+{
+ ::rtl::OUString sDataStyleName;
+ rtl::OUString sPageStyle;
+ const rtl::OUString sNumberFormat;
+ SvXMLStylesContext* pStyles;
+ std::vector<ScXMLMapContent> aMaps;
+ com::sun::star::uno::Any aConditionalFormat;
+ sal_Int32 nNumberFormat;
+ sal_Int32 nLastSheet;
+ sal_Bool bConditionalFormatCreated;
+ sal_Bool bParentSet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+ void SetOperator(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ ::com::sun::star::sheet::ConditionOperator eOp ) const;
+
+ void SetBaseCellAddress(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ const ::rtl::OUString& rBaseCell ) const;
+
+ void SetStyle(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ const ::rtl::OUString& rApplyStyle ) const;
+
+ void SetFormula(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps,
+ sal_Int32 nFormulaIdx, const ::rtl::OUString& rFormula,
+ const ::rtl::OUString& rFormulaNmsp, ::formula::FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const;
+
+ void GetConditionalFormat(
+ ::com::sun::star::uno::Any& aAny, const rtl::OUString& sCondition,
+ const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const;
+protected:
+
+ virtual void SetAttribute( sal_uInt16 nPrefixKey,
+ const ::rtl::OUString& rLocalName,
+ const ::rtl::OUString& rValue );
+
+public:
+
+ TYPEINFO();
+
+ XMLTableStyleContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle = false );
+ virtual ~XMLTableStyleContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual void FillPropertySet(const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+
+ virtual void SetDefaults();
+
+ void AddProperty(sal_Int16 nContextID, const com::sun::star::uno::Any& aValue);
+ XMLPropertyState* FindProperty(const sal_Int16 nContextID);
+
+ sal_Int32 GetNumberFormat();// { return nNumberFormat; }
+
+ sal_Int32 GetLastSheet() const { return nLastSheet; }
+ void SetLastSheet(sal_Int32 nNew) { nLastSheet = nNew; }
+
+private:
+ using XMLPropStyleContext::SetStyle;
+};
+
+class XMLTableStylesContext : public SvXMLStylesContext
+{
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xCellStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xColumnStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xRowStyles;
+ ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer > xTableStyles;
+ const ::rtl::OUString sCellStyleServiceName;
+ const ::rtl::OUString sColumnStyleServiceName;
+ const ::rtl::OUString sRowStyleServiceName;
+ const ::rtl::OUString sTableStyleServiceName;
+ sal_Int32 nNumberFormatIndex;
+ sal_Int32 nConditionalFormatIndex;
+ sal_Int32 nCellStyleIndex;
+ sal_Int32 nMasterPageNameIndex;
+ sal_Bool bAutoStyles;
+
+ UniReference < SvXMLImportPropertyMapper > xCellImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xColumnImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xRowImpPropMapper;
+ UniReference < SvXMLImportPropertyMapper > xTableImpPropMapper;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+protected:
+
+ // Create a style context.
+ virtual SvXMLStyleContext *CreateStyleStyleChildContext(
+ sal_uInt16 nFamily,
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLStyleContext *CreateDefaultStyleStyleChildContext(
+ sal_uInt16 nFamily, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+// virtual SvXMLImportPropertyMapper *GetImpPropMapper();
+
+public:
+
+ XMLTableStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx ,
+ const ::rtl::OUString& rLName ,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bAutoStyles );
+ virtual ~XMLTableStylesContext();
+
+ // Create child element.
+/* virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );*/
+
+ virtual void EndElement();
+
+ virtual UniReference < SvXMLImportPropertyMapper > GetImportPropertyMapper(
+ sal_uInt16 nFamily ) const;
+ virtual ::com::sun::star::uno::Reference <
+ ::com::sun::star::container::XNameContainer >
+ GetStylesContainer( sal_uInt16 nFamily ) const;
+ virtual ::rtl::OUString GetServiceName( sal_uInt16 nFamily ) const;
+
+ sal_Int32 GetIndex(const sal_Int16 nContextID);
+};
+
+class ScXMLMasterStylesContext : public SvXMLStylesContext
+{
+protected:
+ virtual SvXMLStyleContext *CreateStyleChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLStyleContext *CreateStyleStyleChildContext( sal_uInt16 nFamily,
+ sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual sal_Bool InsertStyleFamily( sal_uInt16 nFamily ) const;
+
+public:
+ TYPEINFO();
+
+ ScXMLMasterStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList);
+
+ virtual ~ScXMLMasterStylesContext();
+ virtual void EndElement();
+};
+
+namespace com { namespace sun { namespace star {
+ namespace style { class XStyle; }
+} } }
+
+class ScMasterPageContext : public XMLTextMasterPageContext
+{
+ com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet;
+ const rtl::OUString sEmpty;
+ sal_Bool bContainsRightHeader;
+ sal_Bool bContainsRightFooter;
+
+ void ClearContent(const rtl::OUString& rContent);
+public:
+
+ TYPEINFO();
+
+ ScMasterPageContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ sal_Bool bOverwrite );
+ virtual ~ScMasterPageContext();
+
+ virtual SvXMLImportContext *CreateChildContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+
+ virtual SvXMLImportContext *CreateHeaderFooterContext(
+ sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ const sal_Bool bFooter,
+ const sal_Bool bLeft );
+
+ virtual void Finish( sal_Bool bOverwrite );
+};
+
+class ScCellTextStyleContext : public XMLTextStyleContext
+{
+ sal_Int32 nLastSheet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
+ sal_Bool bDefaultStyle = false );
+ virtual ~ScCellTextStyleContext();
+
+ // overload FillPropertySet to store style information
+ virtual void FillPropertySet(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
new file mode 100644
index 000000000000..0e7f7b221152
--- /dev/null
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -0,0 +1,831 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include "xmlsubti.hxx"
+#include "global.hxx"
+#include "xmlstyli.hxx"
+#include "xmlimprt.hxx"
+#include "document.hxx"
+#include "markdata.hxx"
+#include "XMLConverter.hxx"
+#include "docuno.hxx"
+#include "cellsuno.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "tabprotection.hxx"
+#include <svx/svdpage.hxx>
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/CellInsertMode.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/XProtectable.hpp>
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+
+#include <memory>
+
+using ::std::auto_ptr;
+
+//------------------------------------------------------------------
+
+using namespace com::sun::star;
+
+ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow)
+ : nColsPerCol(nDefaultColCount, 1),
+ nRealCols(nDefaultColCount + 1, 0),
+ nRowsPerRow(nDefaultRowCount, 1),
+ nRealRows(nDefaultRowCount + 1, 0),
+ nChangedCols()
+{
+ aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet );
+ aTableCellPos.Column = nCol;
+ aTableCellPos.Row = nRow;
+
+ for (sal_Int32 i = 0; i < 3; ++i)
+ nRealCols[i] = i;
+ for (sal_Int32 j = 0; j < 3; ++j)
+ nRealRows[j] = j;
+
+ nSpannedCols = 1;
+ nColCount = 0;
+ nSubTableSpanned = 1;
+}
+
+ScMyTableData::~ScMyTableData()
+{
+}
+
+void ScMyTableData::AddRow()
+{
+ ++aTableCellPos.Row;
+ if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size())
+ {
+ nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1);
+ nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0);
+ }
+ nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row];
+}
+
+void ScMyTableData::AddColumn()
+{
+ ++aTableCellPos.Column;
+ if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size())
+ {
+ nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1);
+ nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0);
+ }
+ nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column];
+}
+
+sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const
+{
+ return (nIndex < 0) ? 0 : nRealCols[nIndex];
+}
+
+sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const
+{
+ ScMysalIntList::const_iterator i(nChangedCols.begin());
+ ScMysalIntList::const_iterator endi(nChangedCols.end());
+ while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex)))
+ ++i;
+ if (i == endi)
+ return -1;
+ else
+ if ((*i >= nFromIndex) && (*i < nToIndex))
+ return *i;
+ else
+ return -1;
+}
+
+void ScMyTableData::SetChangedCols(const sal_Int32 nValue)
+{
+ ScMysalIntList::iterator i(nChangedCols.begin());
+ ScMysalIntList::iterator endi(nChangedCols.end());
+ while ((i != endi) && (*i < nValue))
+ {
+ ++i;
+ }
+ if ((i == endi) || (*i != nValue))
+ nChangedCols.insert(i, nValue);
+}
+
+/*******************************************************************************************************************************/
+
+ScXMLTabProtectionData::ScXMLTabProtectionData() :
+ meHash1(PASSHASH_SHA1),
+ meHash2(PASSHASH_UNSPECIFIED),
+ mbProtected(false),
+ mbSelectProtectedCells(true),
+ mbSelectUnprotectedCells(true)
+{
+}
+
+ScMyTables::ScMyTables(ScXMLImport& rTempImport)
+ : rImport(rTempImport),
+ aFixupOLEs(rTempImport),
+ nCurrentColStylePos(0),
+ nCurrentDrawPage( -1 ),
+ nCurrentXShapes( -1 ),
+ nCurrentSheet( -1 )
+{
+}
+
+ScMyTables::~ScMyTables()
+{
+}
+
+void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
+ const ScXMLTabProtectionData& rProtectData)
+{
+ if (rImport.GetModel().is())
+ {
+ nCurrentColStylePos = 0;
+ sCurrentSheetName = sTableName;
+ maTables.clear();
+ ++nCurrentSheet;
+
+ maProtectionData = rProtectData;
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY );
+ if ( xSpreadDoc.is() )
+ {
+ uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets());
+ if (xSheets.is())
+ {
+ if (nCurrentSheet > 0)
+ {
+ try
+ {
+ xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
+ }
+ catch ( uno::RuntimeException& )
+ {
+ ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ ScXMLImport::MutexGuard aGuard(rImport);
+ String sTabName(String::CreateFromAscii("Table"));
+ pDoc->CreateValidTabName(sTabName);
+ rtl::OUString sOUTabName(sTabName);
+ xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
+ }
+ }
+ }
+ uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+ xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY);
+ if ( xCurrentSheet.is() )
+ {
+ xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY);
+ if (!(nCurrentSheet > 0))
+ {
+ uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
+ if ( xNamed.is() )
+ try
+ {
+ xNamed->setName(sTableName);
+ }
+ catch ( uno::RuntimeException& )
+ {
+ ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ ScXMLImport::MutexGuard aGuard(rImport);
+ String sTabName(String::CreateFromAscii("Table"));
+ pDoc->CreateValidTabName(sTabName);
+ rtl::OUString sOUTabName(sTabName);
+ xNamed->setName(sOUTabName);
+ }
+ }
+ }
+ rImport.SetTableStyle(sStyleName);
+
+ if ( sStyleName.getLength() )
+ {
+ // #i57869# All table style properties for all sheets are now applied here,
+ // before importing the contents.
+ // This is needed for the background color.
+ // Sheet visibility has special handling in ScDocFunc::SetTableVisible to
+ // allow hiding the first sheet.
+ // RTL layout is only remembered, not actually applied, so the shapes can
+ // be loaded before mirroring.
+
+ uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles();
+ if (pStyles)
+ {
+ XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
+ XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True);
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xProperties);
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) );
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ NewTable(1);
+}
+
+sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
+ table::CellRangeAddress& aCellAddress) const
+{
+ uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ {
+ uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY);
+ uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet());
+ uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange));
+ if (xMergeSheetCursor.is())
+ {
+ xMergeSheetCursor->collapseToMergedArea();
+ uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
+ if (xMergeCellAddress.is())
+ {
+ aCellAddress = xMergeCellAddress->getRangeAddress();
+ if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
+ aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
+ return false;
+ else
+ return sal_True;
+ }
+ }
+ }
+ return false;
+}
+
+void ScMyTables::UnMerge()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(false);
+ }
+ }
+}
+
+void ScMyTables::DoMerge(sal_Int32 nCount)
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(false);
+ }
+
+ //merge
+ uno::Reference <table::XCellRange> xMergeCellRange;
+ if (nCount == -1)
+ {
+ const ScMyTableData& r = maTables.back();
+ xMergeCellRange.set(
+ xCurrentCellRange->getCellRangeByPosition(
+ aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn + r.GetColsPerCol(r.GetColumn()) - 1,
+ aCellAddress.EndRow + r.GetRowsPerRow(r.GetRow()) - 1));
+ }
+ else
+ xMergeCellRange.set(
+ xCurrentCellRange->getCellRangeByPosition(
+ aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.StartColumn + nCount - 1,
+ aCellAddress.EndRow));
+
+ uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ }
+}
+
+void ScMyTables::InsertRow()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ sal_Int32 nRow(GetRealCellPos().Row);
+ const ScMyTableData& rTab = maTables.back();
+ for (sal_Int32 j = 0; j < GetRealCellPos().Column - rTab.GetColumn() - 1; ++j)
+ {
+ if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(false);
+ }
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ j += aCellAddress.EndColumn - aCellAddress.StartColumn;
+ }
+ rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument());
+ }
+}
+
+void ScMyTables::NewRow()
+{
+ size_t n = maTables.size();
+ if (n <= 1)
+ return;
+
+ if (maTables[n-1].GetRealRows(maTables[n-1].GetRow()) >
+ maTables[n-2].GetRowsPerRow(maTables[n-2].GetRow()) - 1)
+ {
+ if (GetRealCellPos().Column > 0)
+ InsertRow();
+
+ for (size_t i = n - 1; i > 0; --i)
+ {
+ sal_Int32 nRow = maTables[i-1].GetRow();
+ maTables[i-1].SetRowsPerRow(
+ nRow,
+ maTables[i-1].GetRowsPerRow(nRow) + 1);
+
+ maTables[i-1].SetRealRows(
+ nRow + 1,
+ maTables[i-1].GetRealRows(nRow) + maTables[i-1].GetRowsPerRow(nRow));
+ }
+ }
+}
+
+void ScMyTables::AddRow()
+{
+ ScMyTableData& rTab = maTables.back();
+ rTab.AddRow();
+ rTab.SetFirstColumn();
+ sal_Int32 nRow = rTab.GetRow();
+ if (nRow > 0)
+ NewRow();
+
+ rTab.SetRealRows(
+ nRow + 1, rTab.GetRealRows(nRow) + rTab.GetRowsPerRow(nRow));
+}
+
+void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName)
+{
+ rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName);
+}
+
+void ScMyTables::InsertColumn()
+{
+ if ( xCurrentCellRange.is() )
+ {
+ table::CellRangeAddress aCellAddress;
+ sal_Int32 nCol(GetRealCellPos().Column);
+ sal_Int32 n = GetRealCellPos().Row - maTables.back().GetRow() - 1;
+ for (sal_Int32 j = 0; j <= n; ++j)
+ {
+ table::CellRangeAddress aTempCellAddress;
+ if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress))
+ {
+ //unmerge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(false);
+ aTempCellAddress = aCellAddress;
+ aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1;
+ aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
+ }
+ else
+ {
+ aTempCellAddress = aCellAddress;
+ aTempCellAddress.StartColumn += 1;
+ aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
+ }
+
+ //insert Cell
+ sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT);
+ uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY);
+ xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode);
+
+ //merge
+ uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
+ aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY);
+ if (xMergeable.is())
+ xMergeable->merge(sal_True);
+ j += aCellAddress.EndRow - aCellAddress.StartRow;
+ }
+ rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument());
+ }
+}
+
+void ScMyTables::NewColumn(sal_Bool bIsCovered)
+{
+ if (bIsCovered)
+ return;
+
+ ScMyTableData& rLastTab = maTables.back();
+ sal_Int32 nColCount = rLastTab.GetColCount();
+ sal_Int32 nSpannedCols = rLastTab.GetSpannedCols();
+ if ( (nSpannedCols > nColCount) &&
+ (rLastTab.GetRow() == 0) &&
+ (rLastTab.GetColumn() == 0) )
+ {
+ if (nColCount > 0)
+ {
+ sal_Int32 FirstColsSpanned(nSpannedCols / nColCount);
+ sal_Int32 LastColSpanned(FirstColsSpanned
+ + (nSpannedCols % nColCount));
+ for (sal_Int32 i = 0; i < nColCount - 1; ++i)
+ {
+ rLastTab.SetColsPerCol(i, FirstColsSpanned);
+ rLastTab.SetRealCols(i + 1, rLastTab.GetRealCols(i) + FirstColsSpanned);
+ }
+ rLastTab.SetColsPerCol(nColCount - 1, LastColSpanned);
+ rLastTab.SetRealCols(
+ nColCount, rLastTab.GetRealCols(nColCount - 1) + LastColSpanned);
+ }
+ }
+ if (rLastTab.GetRealCols(rLastTab.GetColumn()) > nSpannedCols - 1)
+ {
+ if (rLastTab.GetRow() == 0)
+ {
+ InsertColumn();
+ size_t n = maTables.size();
+ for (size_t i = n - 1; i > 0; --i)
+ {
+ sal_Int32 nColPos =
+ maTables[i-1].GetColumn() + maTables[i].GetSpannedCols() - 1;
+
+ maTables[i-1].SetColsPerCol(nColPos,
+ maTables[i-1].GetColsPerCol(nColPos) +
+ rLastTab.GetColsPerCol(rLastTab.GetColumn()));
+
+ maTables[i-1].SetRealCols(
+ nColPos + 1,
+ maTables[i-1].GetRealCols(nColPos) + maTables[i-1].GetColsPerCol(nColPos));
+
+ maTables[i-1].SetChangedCols(nColPos);
+ }
+ }
+ }
+}
+
+void ScMyTables::AddColumn(sal_Bool bIsCovered)
+{
+ ScMyTableData& rLastTab = maTables.back();
+ rLastTab.AddColumn();
+ if (rLastTab.GetSubTableSpanned() > 1)
+ rLastTab.SetSubTableSpanned(rLastTab.GetSubTableSpanned() - 1);
+ else
+ {
+ NewColumn(bIsCovered);
+ sal_Int32 nCol = rLastTab.GetColumn();
+ sal_Int32 nRow = rLastTab.GetRow();
+ rLastTab.SetRealCols(
+ nCol + 1, rLastTab.GetRealCols(nCol) + rLastTab.GetColsPerCol(nCol));
+
+ if ((!bIsCovered) || (bIsCovered && (rLastTab.GetColsPerCol(nCol) > 1)))
+ {
+ if ((rLastTab.GetRowsPerRow(nRow) > 1) || (rLastTab.GetColsPerCol(nCol) > 1))
+ DoMerge();
+ }
+ }
+}
+
+void ScMyTables::NewTable(sal_Int32 nTempSpannedCols)
+{
+ maTables.push_back(new ScMyTableData(nCurrentSheet));
+
+ if (maTables.size() > 1)
+ {
+ ScMyTableData& rFirstTab = maTables.front();
+
+ const sal_Int32 nCol = rFirstTab.GetColumn();
+ const sal_Int32 nColCount = rFirstTab.GetColCount();
+ const sal_Int32 nColsPerCol = rFirstTab.GetColsPerCol(nCol);
+
+ sal_Int32 nSpannedCols = rFirstTab.GetSpannedCols();
+ sal_Int32 nTemp = nSpannedCols - nColCount;
+ sal_Int32 nTemp2 = nCol - nColCount + 1;
+ if ((nTemp > 0) && (nTemp2 == 0))
+ nTempSpannedCols *= nTemp + 1;
+ else
+ if (nColsPerCol > 1)
+ nTempSpannedCols *= nColsPerCol;
+
+ sal_Int32 nToMerge;
+ if (nSpannedCols > nColCount)
+ nToMerge = rFirstTab.GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount);
+ else
+ nToMerge = rFirstTab.GetChangedCols(nCol, nCol + nColsPerCol);
+ if (nToMerge > nCol)
+ nTempSpannedCols += nToMerge;
+ }
+
+ ScMyTableData& rNewTab = maTables.back();
+ rNewTab.SetSpannedCols(nTempSpannedCols);
+
+ size_t n = maTables.size();
+ if (n > 1)
+ {
+ maTables[n-2].SetSubTableSpanned(rNewTab.GetSpannedCols());
+ UnMerge();
+ }
+}
+
+void ScMyTables::UpdateRowHeights()
+{
+ if (rImport.GetModel().is())
+ {
+ ScXMLImport::MutexGuard aGuard(rImport);
+
+ // update automatic row heights
+
+ // For sheets with any kind of shapes (including notes),
+ // update row heights immediately (before setting the positions).
+ // For sheets without shapes, set "pending" flag
+ // and update row heights when a sheet is shown.
+ // The current sheet (from view settings) is always updated immediately.
+
+ ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
+ if (pDoc)
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
+ SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() );
+
+ ScMarkData aUpdateSheets;
+ for (SCTAB nTab=0; nTab<nCount; ++nTab)
+ {
+ const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
+ if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
+ aUpdateSheets.SelectTable( nTab, sal_True );
+ else
+ pDoc->SetPendingRowHeights( nTab, sal_True );
+ }
+
+ if (aUpdateSheets.GetSelectCount())
+ {
+ pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
+ ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+ pDoc->LockStreamValid( false );
+ }
+ }
+ }
+}
+
+void ScMyTables::DeleteTable()
+{
+ ScXMLImport::MutexGuard aGuard(rImport);
+
+ nCurrentColStylePos = 0;
+ if (!maTables.empty())
+ maTables.pop_back();
+
+ if (maTables.empty()) // only set the styles if all subtables are importet and the table is finished
+ {
+ rImport.GetStylesImportHelper()->SetStylesToRanges();
+ rImport.SetStylesToRangesFinished();
+ }
+
+ //#i48793#; has to be set before protection
+ if (!aMatrixRangeList.empty())
+ {
+ ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin();
+ ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
+ while(aItr != aEndItr)
+ {
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
+ ++aItr;
+ }
+ aMatrixRangeList.clear();
+ }
+
+ if (rImport.GetDocument() && maProtectionData.mbProtected)
+ {
+ uno::Sequence<sal_Int8> aHash;
+ SvXMLUnitConverter::decodeBase64(aHash, maProtectionData.maPassword);
+
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(maProtectionData.mbProtected);
+ pProtect->setPasswordHash(aHash, maProtectionData.meHash1, maProtectionData.meHash2);
+ pProtect->setOption(ScTableProtection::SELECT_LOCKED_CELLS, maProtectionData.mbSelectProtectedCells);
+ pProtect->setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, maProtectionData.mbSelectUnprotectedCells);
+ rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get());
+ }
+
+ //#95582#; find out whether it was possible to set the sheet name
+ // test it here, because if it is a linked table the name is changed by importing
+ // the linking informations
+ uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
+ if ( xNamed.is() )
+ {
+ rtl::OUString sCurrentName(xNamed->getName());
+ if (sCurrentName != sCurrentSheetName && rImport.GetDocument())
+ {
+ rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet),
+ sCurrentSheetName, false, sal_True);
+ }
+ }
+}
+
+table::CellAddress ScMyTables::GetRealCellPos()
+{
+ sal_Int32 nRow = 0;
+ sal_Int32 nCol = 0;
+ size_t n = maTables.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ const ScMyTableData& rTab = maTables[i];
+ nCol += rTab.GetRealCols(rTab.GetColumn());
+ nRow += rTab.GetRealRows(rTab.GetRow());
+ }
+
+ aRealCellPos.Row = nRow;
+ aRealCellPos.Column = nCol;
+ aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ return aRealCellPos;
+}
+
+void ScMyTables::AddColCount(sal_Int32 nTempColCount)
+{
+ ScMyTableData& rLastTab = maTables.back();
+ rLastTab.SetColCount(rLastTab.GetColCount() + nTempColCount);
+}
+
+void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName)
+{
+ DBG_ASSERT(maTables.size() == 1, "not possible to use default styles on columns in subtables");
+ rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat);
+ nCurrentColStylePos += nRepeat;
+}
+
+uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage()
+{
+ if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() )
+ {
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY );
+ if( xDrawPageSupplier.is() )
+ xDrawPage.set(xDrawPageSupplier->getDrawPage());
+ nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ }
+ return xDrawPage;
+}
+
+uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes()
+{
+ if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() )
+ {
+ xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY);
+ rImport.GetShapeImport()->startPage(xShapes);
+ rImport.GetShapeImport()->pushGroupForSorting ( xShapes );
+ nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ return xShapes;
+ }
+ else
+ return xShapes;
+}
+
+sal_Bool ScMyTables::HasDrawPage()
+{
+ return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is());
+}
+
+sal_Bool ScMyTables::HasXShapes()
+{
+ return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is());
+}
+
+void ScMyTables::AddOLE(uno::Reference <drawing::XShape>& rShape,
+ const rtl::OUString &rRangeList)
+{
+ aFixupOLEs.AddOLE(rShape, rRangeList);
+}
+
+void ScMyTables::AddMatrixRange(
+ sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow,
+ const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
+{
+ DBG_ASSERT(nEndRow >= nStartRow, "wrong row order");
+ DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order");
+ table::CellRangeAddress aRange;
+ aRange.StartColumn = nStartColumn;
+ aRange.StartRow = nStartRow;
+ aRange.EndColumn = nEndColumn;
+ aRange.EndRow = nEndRow;
+ aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
+ ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
+ aMatrixRangeList.push_back(aMRange);
+}
+
+sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
+{
+ sal_Bool bResult(false);
+ if (!aMatrixRangeList.empty())
+ {
+ ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin());
+ ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end());
+ sal_Bool bReady(false);
+ while(!bReady && aItr != aEndItr)
+ {
+ if (nCurrentSheet > aItr->aRange.Sheet)
+ {
+ OSL_FAIL("should never hapen, because the list should be cleared in DeleteTable");
+ aItr = aMatrixRangeList.erase(aItr);
+ }
+ else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
+ {
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
+ aItr = aMatrixRangeList.erase(aItr);
+ }
+ else if (nColumn < aItr->aRange.StartColumn)
+ bReady = sal_True;
+ else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow)
+ {
+ bReady = sal_True;
+ bResult = sal_True;
+ }
+ else
+ ++aItr;
+ }
+ }
+ return bResult;
+}
+
+void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
+{
+ uno::Reference <table::XCellRange> xMatrixCellRange(
+ GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow,
+ rRange.EndColumn, rRange.EndRow));
+ if (xMatrixCellRange.is())
+ {
+ uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY);
+ if (xArrayFormulaRange.is())
+ {
+ ScCellRangeObj* pCellRangeObj =
+ static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
+ xMatrixCellRange));
+ if (pCellRangeObj)
+ pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
new file mode 100644
index 000000000000..32b02080a900
--- /dev/null
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLSUBTI_HXX
+#define SC_XMLSUBTI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include "XMLTableShapeResizer.hxx"
+#include "formula/grammar.hxx"
+#include "tabprotection.hxx"
+
+#include <vector>
+#include <list>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+class ScXMLImport;
+
+typedef std::vector<sal_Int32> ScMysalIntVec;
+typedef std::list<sal_Int32> ScMysalIntList;
+
+const ScMysalIntVec::size_type nDefaultRowCount = 20;
+const ScMysalIntVec::size_type nDefaultColCount = 20;
+const ScMysalIntVec::size_type nDefaultTabCount = 10;
+
+class ScMyTableData
+{
+private:
+ com::sun::star::table::CellAddress aTableCellPos;
+ ScMysalIntVec nColsPerCol;
+ ScMysalIntVec nRealCols;
+ ScMysalIntVec nRowsPerRow;
+ ScMysalIntVec nRealRows;
+ sal_Int32 nSpannedCols;
+ sal_Int32 nColCount;
+ sal_Int32 nSubTableSpanned;
+ ScMysalIntList nChangedCols;
+public:
+ ScMyTableData(sal_Int32 nSheet = -1, sal_Int32 nCol = -1, sal_Int32 nRow = -1);
+ ~ScMyTableData();
+ com::sun::star::table::CellAddress GetCellPos() const { return aTableCellPos; }
+ sal_Int32 GetRow() const { return aTableCellPos.Row; }
+ sal_Int32 GetColumn() const { return aTableCellPos.Column; }
+ void AddRow();
+ void AddColumn();
+ void SetFirstColumn() { aTableCellPos.Column = -1; }
+ sal_Int32 GetColsPerCol(const sal_Int32 nIndex) const { return nColsPerCol[nIndex]; }
+ void SetColsPerCol(const sal_Int32 nIndex, sal_Int32 nValue = 1) { nColsPerCol[nIndex] = nValue; }
+ sal_Int32 GetRealCols(const sal_Int32 nIndex, const sal_Bool bIsNormal = sal_True) const;
+ void SetRealCols(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealCols[nIndex] = nValue; }
+ sal_Int32 GetRowsPerRow(const sal_Int32 nIndex) const { return nRowsPerRow[nIndex]; }
+ void SetRowsPerRow(const sal_Int32 nIndex, const sal_Int32 nValue = 1) { nRowsPerRow[nIndex] = nValue; }
+ sal_Int32 GetRealRows(const sal_Int32 nIndex) const { return nIndex < 0 ? 0 : nRealRows[nIndex]; }
+ void SetRealRows(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealRows[nIndex] = nValue; }
+ sal_Int32 GetSpannedCols() const { return nSpannedCols; }
+ void SetSpannedCols(const sal_Int32 nTempSpannedCols) { nSpannedCols = nTempSpannedCols; }
+ sal_Int32 GetColCount() const { return nColCount; }
+ void SetColCount(const sal_Int32 nTempColCount) { nColCount = nTempColCount; }
+ sal_Int32 GetSubTableSpanned() const { return nSubTableSpanned; }
+ void SetSubTableSpanned(const sal_Int32 nValue) { nSubTableSpanned = nValue; }
+ sal_Int32 GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const;
+ void SetChangedCols(const sal_Int32 nValue);
+};
+
+
+struct ScMatrixRange
+{
+ rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
+ formula::FormulaGrammar::Grammar eGrammar;
+ com::sun::star::table::CellRangeAddress aRange;
+ ScMatrixRange(const com::sun::star::table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammarP) :
+ sFormula(rFormula),
+ sFormulaNmsp(rFormulaNmsp),
+ eGrammar(eGrammarP),
+ aRange(rRange)
+ {
+ }
+};
+
+struct ScXMLTabProtectionData
+{
+ ::rtl::OUString maPassword;
+ ScPasswordHash meHash1;
+ ScPasswordHash meHash2;
+ bool mbProtected;
+ bool mbSelectProtectedCells;
+ bool mbSelectUnprotectedCells;
+
+ ScXMLTabProtectionData();
+};
+
+class ScMyTables
+{
+private:
+ typedef std::list<ScMatrixRange> ScMyMatrixRangeList;
+
+ ScXMLImport& rImport;
+
+ ScMyOLEFixer aFixupOLEs;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > xCurrentSheet;
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > xCurrentCellRange;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xDrawPage;
+ ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShapes > xShapes;
+ rtl::OUString sCurrentSheetName;
+ ::boost::ptr_vector<ScMyTableData> maTables;
+ ScXMLTabProtectionData maProtectionData;
+ ScMyMatrixRangeList aMatrixRangeList;
+ com::sun::star::table::CellAddress aRealCellPos;
+ sal_Int32 nCurrentColStylePos;
+ sal_Int16 nCurrentDrawPage;
+ sal_Int16 nCurrentXShapes;
+ sal_Int32 nCurrentSheet;
+
+ sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange,
+ const sal_Int32 nCol, const sal_Int32 nRow,
+ com::sun::star::table::CellRangeAddress& aCellAddress) const;
+ void UnMerge();
+ void DoMerge(sal_Int32 nCount = -1);
+ void InsertRow();
+ void NewRow();
+ void InsertColumn();
+ void NewColumn(sal_Bool bIsCovered);
+public:
+ ScMyTables(ScXMLImport& rImport);
+ ~ScMyTables();
+ void NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
+ const ScXMLTabProtectionData& rProtectData);
+ void AddRow();
+ void SetRowStyle(const rtl::OUString& rCellStyleName);
+ void AddColumn(sal_Bool bIsCovered);
+ void NewTable(sal_Int32 nTempSpannedCols);
+ void UpdateRowHeights();
+ void FixupOLEs() { aFixupOLEs.FixupOLEs(); }
+ sal_Bool IsOLE(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape) const
+ { return ScMyOLEFixer::IsOLE(rShape); }
+ void DeleteTable();
+ com::sun::star::table::CellAddress GetRealCellPos();
+ void AddColCount(sal_Int32 nTempColCount);
+ void AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName);
+ ScXMLTabProtectionData& GetCurrentProtectionData() { return maProtectionData; }
+ rtl::OUString GetCurrentSheetName() const { return sCurrentSheetName; }
+ sal_Int32 GetCurrentSheet() const { return nCurrentSheet; }
+ sal_Int32 GetCurrentColumn() const { return maTables.back().GetColCount(); }
+ sal_Int32 GetCurrentRow() const { return maTables.back().GetRow(); }
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >
+ GetCurrentXSheet() const { return xCurrentSheet; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ GetCurrentXCellRange() const { return xCurrentCellRange; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >
+ GetCurrentXDrawPage();
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ GetCurrentXShapes();
+ sal_Bool HasDrawPage();
+ sal_Bool HasXShapes();
+ void AddOLE(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape,
+ const rtl::OUString &rRangeList);
+
+ void AddMatrixRange( sal_Int32 nStartColumn,
+ sal_Int32 nStartRow,
+ sal_Int32 nEndColumn,
+ sal_Int32 nEndRow,
+ const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp,
+ const formula::FormulaGrammar::Grammar );
+
+ sal_Bool IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow);
+ void SetMatrix( const com::sun::star::table::CellRangeAddress& rRange,
+ const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp,
+ const formula::FormulaGrammar::Grammar );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
new file mode 100644
index 000000000000..8f2382eef7ab
--- /dev/null
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -0,0 +1,506 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "xmltabi.hxx"
+#include "xmlimprt.hxx"
+#include "xmlrowi.hxx"
+#include "xmlcoli.hxx"
+#include "xmlsceni.hxx"
+#include "xmlexternaltabi.hxx"
+#include "xmlnexpi.hxx"
+#include "document.hxx"
+#include "docuno.hxx"
+#include "olinetab.hxx"
+#include "XMLConverter.hxx"
+#include "XMLTableShapesContext.hxx"
+#include "XMLTableSourceContext.hxx"
+#include "XMLStylesImportHelper.hxx"
+#include "rangeutl.hxx"
+#include "externalrefmgr.hxx"
+#include "sheetdata.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/formsimp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/XMLEventsImportContext.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::xml::sax::XAttributeList;
+using ::rtl::OUString;
+
+/**
+ * Determine whether this table is an external reference cache from its
+ * name. There is currently no way of determining whether a table is a
+ * regular table or an external reference cache other than examining the
+ * name itself. We should probably introduce a new boolean value for
+ * table:table element and use it instead of doing this, to make it more
+ * reliable and future-proof.
+ *
+ * @param rName
+ *
+ * @return
+ */
+static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rUrl, rtl::OUString& rExtTabName)
+{
+ // 'file:///path/to/file.ods'#MySheet
+ // 'file:///path/to/file.ods'#MySheet with space
+ // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
+ // That's allowed.)
+
+ static const sal_Unicode aPrefix[] = {
+ '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
+ };
+
+ rtl::OUStringBuffer aUrlBuf, aTabNameBuf;
+ aUrlBuf.appendAscii("file://");
+ sal_Int32 n = rName.getLength();
+ const sal_Unicode* p = rName.getStr();
+
+ bool bInUrl = true;
+ sal_Unicode cPrev = 0;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (i <= 7)
+ {
+ // Checking the prefix 'file://'.
+ if (c != aPrefix[i])
+ return false;
+ }
+ else if (bInUrl)
+ {
+ // parsing file URL
+ if (c == '#')
+ {
+ if (cPrev != '\'')
+ return false;
+
+ rUrl = aUrlBuf.makeStringAndClear();
+ rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
+ bInUrl = false;
+ }
+ else
+ aUrlBuf.append(c);
+ }
+ else
+ // parsing sheet name.
+ aTabNameBuf.append(c);
+
+ cPrev = c;
+ }
+
+ if (bInUrl)
+ return false;
+
+ if (aTabNameBuf.getLength() == 0)
+ return false;
+
+ rExtTabName = aTabNameBuf.makeStringAndClear();
+
+ return true;
+}
+
+ScXMLExternalTabData::ScXMLExternalTabData() :
+ mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
+{
+}
+
+//------------------------------------------------------------------
+
+ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
+ sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsSubTable,
+ const sal_Int32 nSpannedCols) :
+ SvXMLImportContext( rImport, nPrfx, rLName ),
+ pExternalRefInfo(NULL),
+ nStartOffset(-1),
+ bStartFormPage(false),
+ bPrintEntireSheet(sal_True)
+{
+ // get start offset in file (if available)
+ nStartOffset = GetScImport().GetByteOffset();
+
+ if (!bTempIsSubTable)
+ {
+ ScXMLTabProtectionData aProtectData;
+ rtl::OUString sName;
+ rtl::OUString sStyleName;
+ sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap();
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ sAttrName, &aLocalName ));
+ const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
+
+ switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_NAME:
+ sName = sValue;
+ break;
+ case XML_TOK_TABLE_STYLE_NAME:
+ sStyleName = sValue;
+ break;
+ case XML_TOK_TABLE_PROTECTED:
+ aProtectData.mbProtected = IsXMLToken(sValue, XML_TRUE);
+ break;
+ case XML_TOK_TABLE_PRINT_RANGES:
+ sPrintRanges = sValue;
+ break;
+ case XML_TOK_TABLE_PASSWORD:
+ aProtectData.maPassword = sValue;
+ break;
+ case XML_TOK_TABLE_PASSHASH:
+ aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
+ break;
+ case XML_TOK_TABLE_PASSHASH_2:
+ aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
+ break;
+ case XML_TOK_TABLE_PRINT:
+ {
+ if (IsXMLToken(sValue, XML_FALSE))
+ bPrintEntireSheet = false;
+ }
+ break;
+ }
+ }
+
+ rtl::OUString aExtUrl, aExtTabName;
+ if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
+ {
+ // This is an external ref cache table.
+ pExternalRefInfo.reset(new ScXMLExternalTabData);
+ pExternalRefInfo->maFileUrl = aExtUrl;
+ ScDocument* pDoc = GetScImport().GetDocument();
+ if (pDoc)
+ {
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
+ pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
+ pExternalRefInfo->mpCacheTable->setWholeTableCached();
+ }
+ }
+ else
+ {
+ // This is a regular table.
+ GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
+ }
+ }
+ else
+ {
+ GetScImport().GetTables().NewTable(nSpannedCols);
+ }
+}
+
+ScXMLTableContext::~ScXMLTableContext()
+{
+}
+
+SvXMLImportContext *ScXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
+{
+ const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap());
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName);
+ if (pExternalRefInfo.get())
+ {
+ // We only care about the table-row and table-source elements for
+ // external cache data.
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_ROW_GROUP:
+ case XML_TOK_TABLE_HEADER_ROWS:
+ case XML_TOK_TABLE_ROWS:
+ // #i101319# don't discard rows in groups or header (repeat range)
+ return new ScXMLExternalRefRowsContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ case XML_TOK_TABLE_ROW:
+ return new ScXMLExternalRefRowContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ case XML_TOK_TABLE_SOURCE:
+ return new ScXMLExternalRefTabSourceContext(
+ GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
+ default:
+ ;
+ }
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLName);
+ }
+
+ SvXMLImportContext *pContext(0);
+
+ switch (nToken)
+ {
+ case XML_TOK_TABLE_NAMED_EXPRESSIONS:
+ {
+ SCTAB nTab = GetScImport().GetTables().GetCurrentSheet();
+ pContext = new ScXMLNamedExpressionsContext(
+ GetScImport(), nPrefix, rLName, xAttrList,
+ new ScXMLNamedExpressionsContext::SheetLocalInserter(GetScImport(), nTab));
+ }
+ break;
+ case XML_TOK_TABLE_COL_GROUP:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, sal_True );
+ break;
+ case XML_TOK_TABLE_HEADER_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, false );
+ break;
+ case XML_TOK_TABLE_COLS:
+ pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, false );
+ break;
+ case XML_TOK_TABLE_COL:
+ pContext = new ScXMLTableColContext( GetScImport(), nPrefix,
+ rLName, xAttrList );
+ break;
+ case XML_TOK_TABLE_PROTECTION:
+ pContext = new ScXMLTableProtectionContext( GetScImport(), nPrefix, rLName, xAttrList );
+ break;
+ case XML_TOK_TABLE_ROW_GROUP:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, sal_True );
+ break;
+ case XML_TOK_TABLE_HEADER_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ sal_True, false );
+ break;
+ case XML_TOK_TABLE_ROWS:
+ pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
+ rLName, xAttrList,
+ false, false );
+ break;
+ case XML_TOK_TABLE_ROW:
+ pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
+ rLName, xAttrList//,
+ //this
+ );
+ break;
+ case XML_TOK_TABLE_SOURCE:
+ pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_SCENARIO:
+ pContext = new ScXMLTableScenarioContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_SHAPES:
+ pContext = new ScXMLTableShapesContext( GetScImport(), nPrefix, rLName, xAttrList);
+ break;
+ case XML_TOK_TABLE_FORMS:
+ {
+ GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
+ bStartFormPage = sal_True;
+ pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName );
+ }
+ break;
+ case XML_TOK_TABLE_EVENT_LISTENERS:
+ case XML_TOK_TABLE_EVENT_LISTENERS_EXT:
+ {
+ // use XEventsSupplier interface of the sheet
+ uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
+ pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier );
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+
+ return pContext;
+}
+
+void ScXMLTableContext::EndElement()
+{
+ ScXMLImport::MutexGuard aMutexGuard(GetScImport());
+ GetScImport().GetStylesImportHelper()->EndTable();
+ ScDocument* pDoc(GetScImport().GetDocument());
+ if (!pDoc)
+ return;
+
+ SCTAB nCurTab = static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet());
+ if (sPrintRanges.getLength())
+ {
+ Reference< sheet::XPrintAreas > xPrintAreas(
+ GetScImport().GetTables().GetCurrentXSheet(), UNO_QUERY);
+
+ if( xPrintAreas.is() )
+ {
+ Sequence< table::CellRangeAddress > aRangeList;
+ ScRangeStringConverter::GetRangeListFromString( aRangeList, sPrintRanges, pDoc, ::formula::FormulaGrammar::CONV_OOO );
+ xPrintAreas->setPrintAreas( aRangeList );
+ }
+ }
+ else if (!bPrintEntireSheet)
+ // Sheet has "print entire sheet" option by default. Remove it.
+ pDoc->ClearPrintRanges(nCurTab);
+
+ ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab, false));
+ if (pOutlineTable)
+ {
+ ScOutlineArray* pColArray(pOutlineTable->GetColArray());
+ sal_Int32 nDepth(pColArray->GetDepth());
+ sal_Int32 i;
+ for (i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nCount(pColArray->GetCount(static_cast<sal_uInt16>(i)));
+ for (sal_Int32 j = 0; j < nCount; ++j)
+ {
+ ScOutlineEntry* pEntry(pColArray->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j)));
+ if (pEntry->IsHidden())
+ pColArray->SetVisibleBelow(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j), false);
+ }
+ }
+ ScOutlineArray* pRowArray(pOutlineTable->GetRowArray());
+ nDepth = pRowArray->GetDepth();
+ for (i = 0; i < nDepth; ++i)
+ {
+ sal_Int32 nCount(pRowArray->GetCount(static_cast<sal_uInt16>(i)));
+ for (sal_Int32 j = 0; j < nCount; ++j)
+ {
+ ScOutlineEntry* pEntry(pRowArray->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j)));
+ if (pEntry->IsHidden())
+ pRowArray->SetVisibleBelow(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j), false);
+ }
+ }
+ }
+ if (GetScImport().GetTables().HasDrawPage())
+ {
+ if (GetScImport().GetTables().HasXShapes())
+ {
+ GetScImport().GetShapeImport()->popGroupAndSort();
+ uno::Reference < drawing::XShapes > xTempShapes(GetScImport().GetTables().GetCurrentXShapes());
+ GetScImport().GetShapeImport()->endPage(xTempShapes);
+ }
+ if (bStartFormPage)
+ GetScImport().GetFormImport()->endPage();
+ }
+
+ GetScImport().GetTables().DeleteTable();
+ GetScImport().ProgressBarIncrement(false);
+
+ // store stream positions
+ if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */)
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet();
+ // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
+ pSheetData->StartStreamPos( nTab, nStartOffset );
+ }
+}
+
+// ============================================================================
+
+ScXMLImport& ScXMLTableProtectionContext::GetScImport()
+{
+ return static_cast<ScXMLImport&>(GetImport());
+}
+
+ScXMLTableProtectionContext::ScXMLTableProtectionContext(
+ ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
+ const Reference<XAttributeList>& xAttrList ) :
+ SvXMLImportContext( rImport, nPrefix, rLName )
+{
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableProtectionAttrTokenMap();
+ bool bSelectProtectedCells = false;
+ bool bSelectUnprotectedCells = false;
+
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const OUString& aAttrName = xAttrList->getNameByIndex(i);
+ const OUString aValue = xAttrList->getValueByIndex(i);
+
+ OUString aLocalName;
+ sal_uInt16 nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
+ aAttrName, &aLocalName);
+
+ switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
+ {
+ case XML_TOK_TABLE_SELECT_PROTECTED_CELLS:
+ bSelectProtectedCells = IsXMLToken(aValue, XML_TRUE);
+ break;
+ case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS:
+ bSelectUnprotectedCells = IsXMLToken(aValue, XML_TRUE);
+ break;
+ default:
+ ;
+ }
+ }
+
+ ScXMLTabProtectionData& rProtectData = GetScImport().GetTables().GetCurrentProtectionData();
+ rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
+ rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
+}
+
+ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
+{
+}
+
+SvXMLImportContext* ScXMLTableProtectionContext::CreateChildContext(
+ sal_uInt16 /*nPrefix*/, const OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return NULL;
+}
+
+void ScXMLTableProtectionContext::EndElement()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmltabi.hxx b/sc/source/filter/xml/xmltabi.hxx
new file mode 100644
index 000000000000..d3d7303d3203
--- /dev/null
+++ b/sc/source/filter/xml/xmltabi.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SC_XMLTABI_HXX
+#define SC_XMLTABI_HXX
+
+#include "externalrefmgr.hxx"
+
+#include <xmloff/xmlictxt.hxx>
+#include <memory>
+
+class ScXMLImport;
+
+struct ScXMLExternalTabData
+{
+ String maFileUrl;
+ ScExternalRefCache::TableTypeRef mpCacheTable;
+ sal_Int32 mnRow;
+ sal_Int32 mnCol;
+ sal_uInt16 mnFileId;
+
+ ScXMLExternalTabData();
+};
+
+class ScXMLTableContext : public SvXMLImportContext
+{
+ rtl::OUString sPrintRanges;
+ ::std::auto_ptr<ScXMLExternalTabData> pExternalRefInfo;
+ sal_Int32 nStartOffset;
+ sal_Bool bStartFormPage;
+ sal_Bool bPrintEntireSheet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+
+ ScXMLTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ const sal_Bool bTempIsSubTable = false,
+ const sal_Int32 nSpannedCols = 0);
+
+ virtual ~ScXMLTableContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+// ============================================================================
+
+class ScXMLTableProtectionContext : public SvXMLImportContext
+{
+ ScXMLImport& GetScImport();
+
+public:
+ ScXMLTableProtectionContext( ScXMLImport& rImport, sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual ~ScXMLTableProtectionContext();
+
+ virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
new file mode 100644
index 000000000000..2a121a49f065
--- /dev/null
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -0,0 +1,968 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+#include <rsc/rscsfx.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/debug.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <svx/xmlgrhlp.hxx>
+#include <svtools/sfxecode.hxx>
+#include <sfx2/frame.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/xml/sax/XErrorHandler.hpp>
+#include <com/sun/star/xml/sax/XEntityResolver.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDTDHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <comphelper/extract.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <comphelper/genericpropertyset.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+
+#include <svx/xmleohlp.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/saveopt.hxx>
+
+#include "document.hxx"
+#include "xmlwrap.hxx"
+#include "xmlimprt.hxx"
+#include "xmlexprt.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "scerrors.hxx"
+#include "XMLExportSharedData.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
+#include "XMLCodeNameProvider.hxx"
+
+#define MAP_LEN(x) x, sizeof(x) - 1
+
+using namespace com::sun::star;
+using ::rtl::OUString;
+
+using rtl::OUString;
+
+// -----------------------------------------------------------------------
+
+ScXMLImportWrapper::ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) :
+ rDoc(rD),
+ pMedium(pM),
+ xStorage(xStor)
+{
+ DBG_ASSERT( pMedium || xStorage.is(), "ScXMLImportWrapper: Medium or Storage must be set" );
+}
+
+uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator()
+{
+ uno::Reference<task::XStatusIndicator> xStatusIndicator;
+ if (pMedium)
+ {
+ SfxItemSet* pSet = pMedium->GetItemSet();
+ if (pSet)
+ {
+ const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL));
+ if (pItem)
+ xStatusIndicator.set(pItem->GetValue(), uno::UNO_QUERY);
+ }
+ }
+ return xStatusIndicator;
+}
+
+sal_uInt32 ScXMLImportWrapper::ImportFromComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory,
+ uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xXMLParser,
+ xml::sax::InputSource& aParserInput,
+ const rtl::OUString& sComponentName, const rtl::OUString& sDocName,
+ const rtl::OUString& sOldDocName, uno::Sequence<uno::Any>& aArgs,
+ sal_Bool bMustBeSuccessfull)
+{
+ uno::Reference < io::XStream > xDocStream;
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetStorage();
+
+ sal_Bool bEncrypted = false;
+ rtl::OUString sStream(sDocName);
+ if( xStorage.is() )
+ {
+ try
+ {
+ uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
+ if ( xAccess->hasByName(sDocName) && xStorage->isStreamElement( sDocName) )
+ xDocStream = xStorage->openStreamElement( sDocName, embed::ElementModes::READ );
+ else if (sOldDocName.getLength() && xAccess->hasByName(sOldDocName) && xStorage->isStreamElement( sOldDocName) )
+ {
+ xDocStream = xStorage->openStreamElement( sOldDocName, embed::ElementModes::READ );
+ sStream = sOldDocName;
+ }
+ else
+ return false;
+
+ aParserInput.aInputStream = xDocStream->getInputStream();
+ uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
+
+ uno::Any aAny = xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
+ aAny >>= bEncrypted;
+ }
+ catch( packages::WrongPasswordException& )
+ {
+ return ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( packages::zip::ZipIOException& )
+ {
+ return ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch( uno::Exception& )
+ {
+ return SCERR_IMPORT_UNKNOWN;
+ }
+ }
+ else
+ return SCERR_IMPORT_UNKNOWN;
+
+ // set Base URL
+ uno::Reference< beans::XPropertySet > xInfoSet;
+ if( aArgs.getLength() > 0 )
+ aArgs.getConstArray()[0] >>= xInfoSet;
+ DBG_ASSERT( xInfoSet.is(), "missing property set" );
+ if( xInfoSet.is() )
+ {
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( sStream ) );
+ }
+
+ sal_uInt32 nReturn(0);
+ rDoc.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded
+
+ uno::Reference<xml::sax::XDocumentHandler> xDocHandler(
+ xServiceFactory->createInstanceWithArguments(
+ sComponentName, aArgs ),
+ uno::UNO_QUERY );
+ DBG_ASSERT( xDocHandler.is(), "can't get Calc importer" );
+ uno::Reference<document::XImporter> xImporter( xDocHandler, uno::UNO_QUERY );
+ uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
+ if (xImporter.is())
+ xImporter->setTargetDocument( xComponent );
+
+ // connect parser and filter
+ uno::Reference<xml::sax::XParser> xParser( xXMLParser, uno::UNO_QUERY );
+ xParser->setDocumentHandler( xDocHandler );
+
+ try
+ {
+ xParser->parseStream( aParserInput );
+ }
+ catch( xml::sax::SAXParseException& r )
+ {
+ // sax parser sends wrapped exceptions,
+ // try to find the original one
+ xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
+ sal_Bool bTryChild = sal_True;
+
+ while( bTryChild )
+ {
+ xml::sax::SAXException aTmp;
+ if ( aSaxEx.WrappedException >>= aTmp )
+ aSaxEx = aTmp;
+ else
+ bTryChild = false;
+ }
+
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( aSaxEx.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+ else if( bEncrypted )
+ nReturn = ERRCODE_SFX_WRONGPASSWORD;
+ else
+ {
+
+#ifdef DBG_UTIL
+ ByteString aError( "SAX parse exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aError.GetBuffer() );
+#endif
+
+ String sErr( String::CreateFromInt32( r.LineNumber ));
+ sErr += ',';
+ sErr += String::CreateFromInt32( r.ColumnNumber );
+
+ if( sDocName.getLength() )
+ {
+ nReturn = *new TwoStringErrorInfo(
+ (bMustBeSuccessfull ? SCERR_IMPORT_FILE_ROWCOL
+ : SCWARN_IMPORT_FILE_ROWCOL),
+ sDocName, sErr,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
+ }
+ else
+ {
+ DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" );
+ nReturn = *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL, sErr,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
+ }
+ }
+ }
+ catch( xml::sax::SAXException& r )
+ {
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( r.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+ else if( bEncrypted )
+ nReturn = ERRCODE_SFX_WRONGPASSWORD;
+ else
+ {
+
+#ifdef DBG_UTIL
+ ByteString aError( "SAX exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_FORMAT;
+ }
+ }
+ catch( packages::zip::ZipIOException& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "Zip exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch( io::IOException& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "IO exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_OPEN;
+ }
+ catch( uno::Exception& r )
+ {
+#ifdef DBG_UTIL
+ ByteString aError( "uno exception catched while importing:\n" );
+ aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aError.GetBuffer() );
+#endif
+ (void)r; // avoid warning in product version
+
+ nReturn = SCERR_IMPORT_UNKNOWN;
+ }
+
+ // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler,
+ // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer.
+ // So the overflow warning ErrorCode is now stored in the document.
+ // Export works differently, there getImplementation still works.
+
+ if (rDoc.HasRangeOverflow() && !nReturn)
+ nReturn = rDoc.GetRangeOverflowType();
+
+ // free the component
+ xParser->setDocumentHandler( NULL );
+
+ // success!
+ return nReturn;
+}
+
+sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Import" );
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( !xServiceFactory.is() )
+ return false;
+
+ xml::sax::InputSource aParserInput;
+ if (pMedium)
+ aParserInput.sSystemId = OUString(pMedium->GetName());
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetStorage();
+
+ // get parser
+ uno::Reference<uno::XInterface> xXMLParser(
+ xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) ));
+ DBG_ASSERT( xXMLParser.is(), "com.sun.star.xml.sax.Parser service missing" );
+ if( !xXMLParser.is() )
+ return false;
+
+ // get filter
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ if ( pObjSh )
+ {
+ rtl::OUString sEmpty;
+ uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
+
+ /** property map for export info set */
+ comphelper::PropertyMapEntry aImportInfoMap[] =
+ {
+ { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference<uno::XInterface> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "VBACompatibilityMode" ), 0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) );
+
+ // ---- get BuildId from parent container if available
+
+ uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY );
+ if( xChild.is() )
+ {
+ uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
+ if( xParentSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
+ {
+ xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
+ }
+ }
+ }
+
+ // -------------------------------------
+
+ uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
+ if (xStatusIndicator.is())
+ {
+ sal_Int32 nProgressRange(1000000);
+ xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC)), nProgressRange);
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange));
+ }
+
+ // Set base URI
+ OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
+ ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : ::rtl::OUString();
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
+
+ // TODO/LATER: do not do it for embedded links
+ if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() )
+ {
+ OUString aName;
+ if ( pMedium && pMedium->GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+ else
+ aName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "dummyObjectName" ));
+
+ if( aName.getLength() )
+ {
+ sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
+ }
+ }
+
+ sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+
+ sal_uInt32 nMetaRetval(0);
+ if(!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aMetaArgs(1);
+ uno::Any* pMetaArgs = aMetaArgs.getArray();
+ pMetaArgs[0] <<= xInfoSet;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" );
+
+ nMetaRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs,
+ false);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" );
+ }
+
+ SvXMLGraphicHelper* pGraphicHelper = NULL;
+ uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
+
+ uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
+ SvXMLEmbeddedObjectHelper *pObjectHelper = NULL;
+
+ if( xStorage.is() )
+ {
+ pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
+ xGrfContainer = pGraphicHelper;
+
+ if( pObjSh )
+ {
+ pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_READ, false );
+ xObjectResolver = pObjectHelper;
+ }
+ }
+ uno::Sequence<uno::Any> aStylesArgs(4);
+ uno::Any* pStylesArgs = aStylesArgs.getArray();
+ pStylesArgs[0] <<= xInfoSet;
+ pStylesArgs[1] <<= xGrfContainer;
+ pStylesArgs[2] <<= xStatusIndicator;
+ pStylesArgs[3] <<= xObjectResolver;
+
+ sal_uInt32 nSettingsRetval(0);
+ if (!bStylesOnly)
+ {
+ // Settings must be loaded first because of the printer setting,
+ // which is needed in the page styles (paper tray).
+
+ uno::Sequence<uno::Any> aSettingsArgs(1);
+ uno::Any* pSettingsArgs = aSettingsArgs.getArray();
+ pSettingsArgs[0] <<= xInfoSet;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import start" );
+
+ nSettingsRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
+ sEmpty, aSettingsArgs, false);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import end" );
+ }
+
+ sal_uInt32 nStylesRetval(0);
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import start" );
+
+ nStylesRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
+ sEmpty, aStylesArgs, sal_True);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import end" );
+ }
+
+ sal_uInt32 nDocRetval(0);
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aDocArgs(4);
+ uno::Any* pDocArgs = aDocArgs.getArray();
+ pDocArgs[0] <<= xInfoSet;
+ pDocArgs[1] <<= xGrfContainer;
+ pDocArgs[2] <<= xStatusIndicator;
+ pDocArgs[3] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import start" );
+
+ nDocRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput,
+ bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter"))
+ : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs,
+ sal_True);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" );
+ }
+ if( pGraphicHelper )
+ SvXMLGraphicHelper::Destroy( pGraphicHelper );
+
+ if( pObjectHelper )
+ SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+
+ sal_Bool bRet(false);
+ if (bStylesOnly)
+ {
+ if (nStylesRetval)
+ nError = nStylesRetval;
+ else
+ bRet = sal_True;
+ }
+ else
+ {
+ if (nDocRetval)
+ {
+ nError = nDocRetval;
+ if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW ||
+ nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW)
+ bRet = sal_True;
+ }
+ else if (nStylesRetval)
+ nError = nStylesRetval;
+ else if (nMetaRetval)
+ nError = nMetaRetval;
+ else if (nSettingsRetval)
+ nError = nSettingsRetval;
+ else
+ bRet = sal_True;
+ }
+
+ // set BuildId on XModel for later OLE object loading
+ if( xInfoSet.is() )
+ {
+ uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
+ if( xModelSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
+ OUString sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) );
+ if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) )
+ {
+ xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) );
+ }
+ }
+
+ // Set Code Names
+ uno::Any aAny = xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration") ));
+ uno::Reference <container::XNameAccess> xCodeNameAccess;
+ if( aAny >>= xCodeNameAccess )
+ XMLCodeNameProvider::set( xCodeNameAccess, &rDoc );
+
+ // VBA compatibility
+ bool bVBACompat = false;
+ if ( (xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"))) >>= bVBACompat) && bVBACompat )
+ {
+ /* Set library container to VBA compatibility mode, this
+ forces loading the Basic project, which in turn creates the
+ VBA Globals object and does all related initialization. */
+ if ( xModelSet.is() ) try
+ {
+ uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY_THROW );
+ xVBACompat->setVBACompatibilityMode( sal_True );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
+ return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval;
+ }
+ return false;
+}
+
+bool lcl_HasValidStream(ScDocument& rDoc)
+{
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ if ( pObjSh->IsDocShared() )
+ return false; // never copy stream from shared file
+
+ // don't read remote file again
+ // (could instead re-use medium directly in that case)
+ SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium();
+ if ( !pSrcMed || pSrcMed->IsRemote() )
+ return false;
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (rDoc.IsStreamValid(nTab))
+ return true;
+ return false;
+}
+
+sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory,
+ uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xWriter,
+ uno::Sequence<beans::PropertyValue>& aDescriptor, const rtl::OUString& sName,
+ const rtl::OUString& sMediaType, const rtl::OUString& sComponentName,
+ const sal_Bool bPlainText, uno::Sequence<uno::Any>& aArgs, ScMySharedData*& pSharedData)
+{
+ sal_Bool bRet(false);
+ uno::Reference<io::XOutputStream> xOut;
+ uno::Reference<io::XStream> xStream;
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetOutputStorage();
+
+ if( xStorage.is() )
+ {
+ // #96807#; trunc stream before use, because it could be an existing stream
+ // and the new content could be shorter than the old content. In this case
+ // would not all be over written by the new content and the xml file
+ // would not be valid.
+ xStream = xStorage->openStreamElement( sName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
+ if (xSet.is())
+ {
+ xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType));
+ OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
+ if (bPlainText)
+ xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(false));
+
+ // even plain stream should be encrypted in encrypted documents
+ xSet->setPropertyValue( aUseCommonPassPropName, uno::makeAny(sal_True) );
+ }
+
+ xOut = xStream->getOutputStream();
+ }
+
+ // set Base URL
+ uno::Reference< beans::XPropertySet > xInfoSet;
+ if( aArgs.getLength() > 0 )
+ aArgs.getConstArray()[0] >>= xInfoSet;
+ DBG_ASSERT( xInfoSet.is(), "missing property set" );
+ if( xInfoSet.is() )
+ {
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( sName ) );
+ }
+
+ uno::Reference<io::XActiveDataSource> xSrc( xWriter, uno::UNO_QUERY );
+ xSrc->setOutputStream( xOut );
+
+ uno::Reference<document::XFilter> xFilter(
+ xServiceFactory->createInstanceWithArguments( sComponentName , aArgs ),
+ uno::UNO_QUERY );
+ DBG_ASSERT( xFilter.is(), "can't get exporter" );
+ uno::Reference<document::XExporter> xExporter( xFilter, uno::UNO_QUERY );
+ uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY );
+ if (xExporter.is())
+ xExporter->setSourceDocument( xComponent );
+
+ if ( xFilter.is() )
+ {
+ ScXMLExport* pExport = static_cast<ScXMLExport*>(SvXMLExport::getImplementation(xFilter));
+ pExport->SetSharedData(pSharedData);
+
+ // if there are sheets to copy, get the source stream
+ if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("content.xml")) && lcl_HasValidStream(rDoc) &&
+ ( pExport->getExportFlags() & EXPORT_OASIS ) )
+ {
+ // old stream is still in this file's storage - open read-only
+
+ // #i106854# use the document's storage directly, without a temporary SfxMedium
+ uno::Reference<embed::XStorage> xTmpStorage = rDoc.GetDocumentShell()->GetStorage();
+ uno::Reference<io::XStream> xSrcStream;
+ uno::Reference<io::XInputStream> xSrcInput;
+
+ // #i108978# If an embedded object is saved and no events are notified, don't use the stream
+ // because without the ...DONE events, stream positions aren't updated.
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xModel)->GetSheetSaveData();
+ if (pSheetData && pSheetData->IsInSupportedSave())
+ {
+ try
+ {
+ if (xTmpStorage.is())
+ xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ );
+ if (xSrcStream.is())
+ xSrcInput = xSrcStream->getInputStream();
+ }
+ catch (uno::Exception&)
+ {
+ // stream not available (for example, password protected) - save normally (xSrcInput is null)
+ }
+ }
+
+ pExport->SetSourceStream( xSrcInput );
+ bRet = xFilter->filter( aDescriptor );
+ pExport->SetSourceStream( uno::Reference<io::XInputStream>() );
+
+ // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
+ // #i110692# For embedded objects, the stream may be unavailable for one save operation (m_pAntiImpl)
+ // and become available again later. But after saving normally once, the stream positions aren't
+ // valid anymore, so the flags also have to be reset if the stream wasn't available.
+ if ( !bRet || !xSrcInput.is() )
+ {
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (rDoc.IsStreamValid(nTab))
+ rDoc.SetStreamValid(nTab, false);
+ }
+ }
+ else
+ bRet = xFilter->filter( aDescriptor );
+
+ pSharedData = pExport->GetSharedData();
+ }
+
+ return bRet;
+}
+
+sal_Bool ScXMLImportWrapper::Export(sal_Bool bStylesOnly)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Export" );
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory(comphelper::getProcessServiceFactory());
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( !xServiceFactory.is() )
+ return false;
+
+ uno::Reference<uno::XInterface> xWriter(xServiceFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) ));
+ DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" );
+ if(!xWriter.is())
+ return false;
+
+ if ( !xStorage.is() && pMedium )
+ xStorage = pMedium->GetOutputStorage();
+
+ uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY );
+
+ OUString sFileName;
+ OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml"));
+ if (pMedium)
+ sFileName = pMedium->GetName();
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ uno::Sequence<beans::PropertyValue> aDescriptor(1);
+ beans::PropertyValue* pProps = aDescriptor.getArray();
+ pProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
+ pProps[0].Value <<= sFileName;
+
+ /** property map for export info set */
+ comphelper::PropertyMapEntry aExportInfoMap[] =
+ {
+ { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence<sal_Int32>*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+ { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence<rtl::OUString>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence<sal_Int32>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) );
+
+ if ( pObjSh && xStorage.is() )
+ {
+ pObjSh->UpdateDocInfoForSave(); // update information
+
+ uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
+ uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
+ sal_Int32 nProgressRange(1000000);
+ if(xStatusIndicator.is())
+ xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC)), nProgressRange);
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange));
+
+ SvtSaveOptions aSaveOpt;
+ sal_Bool bUsePrettyPrinting(aSaveOpt.IsPrettyPrinting());
+ xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting));
+
+ const OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
+ xInfoSet->setPropertyValue( sTargetStorage, uno::Any( xStorage ) );
+
+ OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
+ ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL( true ) : ::rtl::OUString();
+ rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
+
+ // TODO/LATER: do not do it for embedded links
+ if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() )
+ {
+ OUString aName(RTL_CONSTASCII_USTRINGPARAM("dummyObjectName"));
+ if ( pMedium && pMedium->GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+
+ if( aName.getLength() )
+ {
+ sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
+ }
+ }
+
+ sal_Bool bMetaRet(pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
+ sal_Bool bStylesRet (false);
+ sal_Bool bDocRet(false);
+ sal_Bool bSettingsRet(false);
+ ScMySharedData* pSharedData = NULL;
+
+ sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+
+ // meta export
+ if (!bStylesOnly && !bMetaRet)
+ {
+ uno::Sequence<uno::Any> aMetaArgs(3);
+ uno::Any* pMetaArgs = aMetaArgs.getArray();
+ pMetaArgs[0] <<= xInfoSet;
+ pMetaArgs[1] <<= xHandler;
+ pMetaArgs[2] <<= xStatusIndicator;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export start" );
+
+ bMetaRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")),
+ sal_True, aMetaArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export end" );
+ }
+
+ uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
+ SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
+
+ uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
+ SvXMLGraphicHelper* pGraphicHelper = 0;
+
+ if( xStorage.is() )
+ {
+ pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, false );
+ xGrfContainer = pGraphicHelper;
+ }
+
+ if( pObjSh )
+ {
+ pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, false );
+ xObjectResolver = pObjectHelper;
+ }
+
+ // styles export
+
+ {
+ uno::Sequence<uno::Any> aStylesArgs(5);
+ uno::Any* pStylesArgs = aStylesArgs.getArray();
+ pStylesArgs[0] <<= xInfoSet;
+ pStylesArgs[1] <<= xGrfContainer;
+ pStylesArgs[2] <<= xStatusIndicator;
+ pStylesArgs[3] <<= xHandler;
+ pStylesArgs[4] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export start" );
+
+ bStylesRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")),
+ false, aStylesArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export end" );
+ }
+
+ // content export
+
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aDocArgs(5);
+ uno::Any* pDocArgs = aDocArgs.getArray();
+ pDocArgs[0] <<= xInfoSet;
+ pDocArgs[1] <<= xGrfContainer;
+ pDocArgs[2] <<= xStatusIndicator;
+ pDocArgs[3] <<= xHandler;
+ pDocArgs[4] <<= xObjectResolver;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export start" );
+
+ bDocRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")),
+ false, aDocArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export end" );
+ }
+
+ if( pGraphicHelper )
+ SvXMLGraphicHelper::Destroy( pGraphicHelper );
+
+ if( pObjectHelper )
+ SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
+
+ // settings export
+
+ if (!bStylesOnly)
+ {
+ uno::Sequence<uno::Any> aSettingsArgs(3);
+ uno::Any* pSettingsArgs = aSettingsArgs.getArray();
+ pSettingsArgs[0] <<= xInfoSet;
+ pSettingsArgs[1] <<= xHandler;
+ pSettingsArgs[2] <<= xStatusIndicator;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export start" );
+
+ bSettingsRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor,
+ rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")),
+ sTextMediaType,
+ bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter"))
+ : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")),
+ false, aSettingsArgs, pSharedData);
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export end" );
+ }
+
+ if (pSharedData)
+ delete pSharedData;
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+ return bStylesRet && ((!bStylesOnly && bDocRet && bMetaRet && bSettingsRet) || bStylesOnly);
+ }
+
+ // later: give string descriptor as parameter for doc type
+
+ return false;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */