summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2009-12-01 17:41:04 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2009-12-01 17:41:04 +0000
commitc2b4af25ca2f1266be37f074ef22b903b31fbc5f (patch)
tree382e5b5b79e3003cde0288e24c179af85207fb32
parent23d63d58c951ea4c172c5c759e764c8a783951d9 (diff)
parentbebc983ea6df34dbc310d1dfbb3ca74ea62db830 (diff)
chartshapes: merge with DEV300 m55
-rw-r--r--chart2/prj/build.lst2
-rw-r--r--chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx11
-rw-r--r--chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx4
-rw-r--r--chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx12
-rw-r--r--chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx13
-rw-r--r--chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx6
-rw-r--r--chart2/source/controller/chartapiwrapper/WrappedNumberFormatProperty.cxx11
-rw-r--r--chart2/source/controller/dialogs/Bitmaps.hrc28
-rw-r--r--chart2/source/controller/dialogs/Bitmaps.src14
-rw-r--r--chart2/source/controller/dialogs/Bitmaps_HC.hrc26
-rw-r--r--chart2/source/controller/dialogs/Bitmaps_HC.src14
-rw-r--r--chart2/source/controller/dialogs/ChartTypeDialogController.cxx36
-rw-r--r--chart2/source/controller/dialogs/ChartTypeDialogController.hxx13
-rw-r--r--chart2/source/controller/dialogs/DataBrowser.cxx8
-rw-r--r--chart2/source/controller/dialogs/DataBrowserModel.cxx38
-rw-r--r--chart2/source/controller/dialogs/DialogModel.cxx2
-rw-r--r--chart2/source/controller/dialogs/ObjectNameProvider.cxx9
-rw-r--r--chart2/source/controller/dialogs/Strings.src5
-rw-r--r--chart2/source/controller/dialogs/Strings_ChartTypes.src9
-rw-r--r--chart2/source/controller/dialogs/res_DataLabel.cxx13
-rw-r--r--chart2/source/controller/dialogs/tp_ChartType.cxx1
-rw-r--r--chart2/source/controller/inc/DataPointItemConverter.hxx1
-rw-r--r--chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx11
-rw-r--r--chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx5
-rw-r--r--chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx4
-rw-r--r--chart2/source/controller/main/ChartController.cxx5
-rw-r--r--chart2/source/controller/main/ChartController_Properties.cxx5
-rw-r--r--chart2/source/controller/main/ChartWindow.cxx28
-rw-r--r--chart2/source/controller/main/ChartWindow.hxx6
-rw-r--r--chart2/source/inc/ChartTypeHelper.hxx11
-rw-r--r--chart2/source/inc/CommonFunctors.hxx5
-rw-r--r--chart2/source/inc/Strings.hrc6
-rw-r--r--chart2/source/inc/chartview/ChartSfxItemIds.hxx3
-rw-r--r--chart2/source/inc/chartview/ExplicitValueProvider.hxx7
-rw-r--r--chart2/source/inc/servicenames_charttypes.hxx1
-rw-r--r--chart2/source/model/template/BubbleChartType.cxx245
-rw-r--r--chart2/source/model/template/BubbleChartType.hxx89
-rw-r--r--chart2/source/model/template/BubbleChartTypeTemplate.cxx322
-rw-r--r--chart2/source/model/template/BubbleChartTypeTemplate.hxx106
-rw-r--r--chart2/source/model/template/BubbleDataInterpreter.cxx317
-rw-r--r--chart2/source/model/template/BubbleDataInterpreter.hxx64
-rw-r--r--chart2/source/model/template/ChartTypeManager.cxx8
-rw-r--r--chart2/source/model/template/ChartTypeTemplate.cxx24
-rw-r--r--chart2/source/model/template/_serviceregistration_charttypes.cxx9
-rw-r--r--chart2/source/model/template/makefile.mk3
-rw-r--r--chart2/source/tools/ChartTypeHelper.cxx57
-rw-r--r--chart2/source/tools/DiagramHelper.cxx18
-rw-r--r--chart2/source/tools/TitleHelper.cxx36
-rw-r--r--chart2/source/view/charttypes/AreaChart.cxx52
-rw-r--r--chart2/source/view/charttypes/AreaChart.hxx10
-rw-r--r--chart2/source/view/charttypes/BarChart.cxx12
-rw-r--r--chart2/source/view/charttypes/BubbleChart.cxx420
-rw-r--r--chart2/source/view/charttypes/BubbleChart.hxx97
-rw-r--r--chart2/source/view/charttypes/CandleStickChart.cxx2
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx4
-rw-r--r--chart2/source/view/charttypes/Splines.cxx350
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx11
-rw-r--r--chart2/source/view/charttypes/makefile.mk3
-rw-r--r--chart2/source/view/diagram/VDiagram.cxx10
-rw-r--r--chart2/source/view/inc/ShapeFactory.hxx7
-rw-r--r--chart2/source/view/inc/Stripe.hxx2
-rw-r--r--chart2/source/view/inc/VDataSeries.hxx16
-rw-r--r--chart2/source/view/main/ChartItemPool.cxx1
-rw-r--r--chart2/source/view/main/ChartView.cxx28
-rw-r--r--chart2/source/view/main/PlottingPositionHelper.cxx34
-rw-r--r--chart2/source/view/main/ShapeFactory.cxx52
-rw-r--r--chart2/source/view/main/Stripe.cxx47
-rw-r--r--chart2/source/view/main/VDataSeries.cxx136
-rw-r--r--sc/inc/address.hxx6
-rw-r--r--sc/inc/cell.hxx14
-rw-r--r--sc/inc/cellsuno.hxx12
-rw-r--r--sc/inc/compiler.hxx15
-rw-r--r--sc/inc/conditio.hxx19
-rw-r--r--sc/inc/datauno.hxx11
-rw-r--r--sc/inc/document.hxx52
-rw-r--r--sc/inc/docuno.hxx2
-rw-r--r--sc/inc/dpobject.hxx3
-rw-r--r--sc/inc/drwlayer.hxx6
-rw-r--r--sc/inc/externalrefmgr.hxx37
-rw-r--r--sc/inc/fmtuno.hxx33
-rw-r--r--sc/inc/formulaparserpool.hxx70
-rw-r--r--sc/inc/global.hxx9
-rw-r--r--sc/inc/globstr.hrc1
-rw-r--r--sc/inc/pch/precompiled_sc.hxx3
-rw-r--r--sc/inc/postit.hxx177
-rw-r--r--sc/inc/progress.hxx11
-rw-r--r--sc/inc/rangenam.hxx10
-rw-r--r--sc/inc/refdata.hxx21
-rw-r--r--sc/inc/reftokenhelper.hxx3
-rw-r--r--sc/inc/sc.hrc7
-rw-r--r--sc/inc/scabstdlg.hxx1
-rw-r--r--sc/inc/scextopt.hxx2
-rw-r--r--sc/inc/table.hxx63
-rw-r--r--sc/inc/tabprotection.hxx180
-rw-r--r--sc/inc/tokenuno.hxx20
-rw-r--r--sc/inc/unonames.hxx6
-rw-r--r--sc/inc/validat.hxx4
-rw-r--r--sc/prj/build.lst2
-rw-r--r--sc/source/core/data/attarray.cxx5
-rw-r--r--sc/source/core/data/bcaslot.cxx2
-rw-r--r--sc/source/core/data/cell.cxx12
-rw-r--r--sc/source/core/data/cell2.cxx291
-rw-r--r--sc/source/core/data/column.cxx20
-rw-r--r--sc/source/core/data/column3.cxx51
-rw-r--r--sc/source/core/data/conditio.cxx48
-rw-r--r--sc/source/core/data/documen2.cxx19
-rw-r--r--sc/source/core/data/documen3.cxx52
-rw-r--r--sc/source/core/data/documen4.cxx11
-rw-r--r--sc/source/core/data/documen5.cxx8
-rw-r--r--sc/source/core/data/documen8.cxx13
-rw-r--r--sc/source/core/data/document.cxx316
-rw-r--r--sc/source/core/data/dpobject.cxx9
-rw-r--r--sc/source/core/data/drwlayer.cxx22
-rw-r--r--sc/source/core/data/makefile.mk3
-rw-r--r--sc/source/core/data/postit.cxx645
-rw-r--r--sc/source/core/data/stlsheet.cxx8
-rw-r--r--sc/source/core/data/table1.cxx20
-rw-r--r--sc/source/core/data/table2.cxx54
-rw-r--r--sc/source/core/data/table3.cxx105
-rw-r--r--sc/source/core/data/table5.cxx21
-rw-r--r--sc/source/core/data/table6.cxx2
-rw-r--r--sc/source/core/data/tabprotection.cxx465
-rw-r--r--sc/source/core/data/validat.cxx49
-rw-r--r--sc/source/core/inc/interpre.hxx26
-rw-r--r--sc/source/core/inc/refupdat.hxx2
-rw-r--r--sc/source/core/tool/address.cxx53
-rw-r--r--sc/source/core/tool/compiler.cxx251
-rw-r--r--sc/source/core/tool/detfunc.cxx2
-rw-r--r--sc/source/core/tool/editutil.cxx4
-rw-r--r--sc/source/core/tool/formulaparserpool.cxx171
-rw-r--r--sc/source/core/tool/interpr1.cxx435
-rw-r--r--sc/source/core/tool/interpr4.cxx9
-rw-r--r--sc/source/core/tool/makefile.mk4
-rw-r--r--sc/source/core/tool/progress.cxx2
-rw-r--r--sc/source/core/tool/rangenam.cxx42
-rw-r--r--sc/source/core/tool/reftokenhelper.cxx59
-rw-r--r--sc/source/core/tool/refupdat.cxx10
-rw-r--r--sc/source/core/tool/token.cxx3
-rw-r--r--sc/source/filter/excel/biffdump.cxx9864
-rw-r--r--sc/source/filter/excel/colrowst.cxx6
-rw-r--r--sc/source/filter/excel/excdoc.cxx67
-rw-r--r--sc/source/filter/excel/excel.cxx7
-rw-r--r--sc/source/filter/excel/excimp8.cxx57
-rw-r--r--sc/source/filter/excel/excrecds.cxx63
-rw-r--r--sc/source/filter/excel/expop2.cxx4
-rw-r--r--sc/source/filter/excel/impop.cxx48
-rw-r--r--sc/source/filter/excel/namebuff.cxx3
-rw-r--r--sc/source/filter/excel/read.cxx11
-rw-r--r--sc/source/filter/excel/xechart.cxx19
-rw-r--r--sc/source/filter/excel/xeescher.cxx5
-rw-r--r--sc/source/filter/excel/xeformula.cxx2
-rw-r--r--sc/source/filter/excel/xeroot.cxx44
-rw-r--r--sc/source/filter/excel/xestream.cxx317
-rw-r--r--sc/source/filter/excel/xichart.cxx104
-rw-r--r--sc/source/filter/excel/xicontent.cxx192
-rw-r--r--sc/source/filter/excel/xiescher.cxx32
-rw-r--r--sc/source/filter/excel/xilink.cxx1
-rw-r--r--sc/source/filter/excel/xiroot.cxx26
-rw-r--r--sc/source/filter/excel/xistream.cxx17
-rw-r--r--sc/source/filter/excel/xlchart.cxx3
-rw-r--r--sc/source/filter/excel/xlpage.cxx206
-rw-r--r--sc/source/filter/excel/xlroot.cxx14
-rw-r--r--sc/source/filter/excel/xlstyle.cxx2
-rw-r--r--sc/source/filter/html/htmlimp.cxx4
-rw-r--r--sc/source/filter/html/htmlpars.cxx369
-rw-r--r--sc/source/filter/inc/excimp8.hxx2
-rw-r--r--sc/source/filter/inc/excrecds.hxx17
-rw-r--r--sc/source/filter/inc/htmlpars.hxx357
-rw-r--r--sc/source/filter/inc/imp_op.hxx6
-rw-r--r--sc/source/filter/inc/xcl97rec.hxx180
-rw-r--r--sc/source/filter/inc/xeroot.hxx5
-rw-r--r--sc/source/filter/inc/xestream.hxx116
-rw-r--r--sc/source/filter/inc/xetable.hxx2
-rw-r--r--sc/source/filter/inc/xichart.hxx8
-rw-r--r--sc/source/filter/inc/xicontent.hxx61
-rw-r--r--sc/source/filter/inc/xiroot.hxx16
-rw-r--r--sc/source/filter/inc/xistream.hxx5
-rw-r--r--sc/source/filter/inc/xlchart.hxx1
-rw-r--r--sc/source/filter/inc/xlroot.hxx4
-rw-r--r--sc/source/filter/lotus/op.cxx2
-rw-r--r--sc/source/filter/starcalc/scflt.cxx18
-rw-r--r--sc/source/filter/xcl97/XclExpChangeTrack.cxx1
-rw-r--r--sc/source/filter/xcl97/makefile.mk1
-rw-r--r--sc/source/filter/xcl97/xcl97rec.cxx322
-rw-r--r--sc/source/filter/xml/XMLConverter.cxx302
-rw-r--r--sc/source/filter/xml/XMLConverter.hxx58
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.cxx50
-rw-r--r--sc/source/filter/xml/XMLExportDatabaseRanges.hxx12
-rw-r--r--sc/source/filter/xml/XMLTrackedChangesContext.cxx24
-rw-r--r--sc/source/filter/xml/xmlannoi.cxx92
-rw-r--r--sc/source/filter/xml/xmlannoi.hxx51
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx13
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx202
-rw-r--r--sc/source/filter/xml/xmlcelli.hxx25
-rw-r--r--sc/source/filter/xml/xmlcvali.cxx289
-rw-r--r--sc/source/filter/xml/xmldrani.cxx5
-rw-r--r--sc/source/filter/xml/xmldrani.hxx6
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx14
-rw-r--r--sc/source/filter/xml/xmlfilti.cxx44
-rw-r--r--sc/source/filter/xml/xmlfilti.hxx9
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx118
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx81
-rw-r--r--sc/source/filter/xml/xmlnexpi.cxx15
-rw-r--r--sc/source/filter/xml/xmlstyli.cxx250
-rw-r--r--sc/source/filter/xml/xmlstyli.hxx30
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx63
-rw-r--r--sc/source/filter/xml/xmlsubti.hxx6
-rw-r--r--sc/source/ui/Accessibility/AccessibleDocument.cxx25
-rw-r--r--sc/source/ui/app/inputhdl.cxx50
-rw-r--r--sc/source/ui/app/inputwin.cxx2
-rw-r--r--sc/source/ui/app/transobj.cxx2
-rw-r--r--sc/source/ui/attrdlg/scdlgfact.cxx18
-rw-r--r--sc/source/ui/attrdlg/scdlgfact.hxx4
-rw-r--r--sc/source/ui/dbgui/sortdlg.cxx41
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx21
-rw-r--r--sc/source/ui/docshell/docfunc.cxx390
-rw-r--r--sc/source/ui/docshell/docsh.cxx112
-rw-r--r--sc/source/ui/docshell/docsh3.cxx4
-rw-r--r--sc/source/ui/docshell/docsh4.cxx14
-rw-r--r--sc/source/ui/docshell/docsh5.cxx44
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx101
-rw-r--r--sc/source/ui/drawfunc/drawsh.cxx2
-rw-r--r--sc/source/ui/drawfunc/fudraw.cxx6
-rw-r--r--sc/source/ui/drawfunc/fuins2.cxx4
-rw-r--r--sc/source/ui/drawfunc/fupoor.cxx5
-rw-r--r--sc/source/ui/drawfunc/fusel.cxx6
-rw-r--r--sc/source/ui/drawfunc/fusel2.cxx3
-rw-r--r--sc/source/ui/drawfunc/futext.cxx4
-rw-r--r--sc/source/ui/drawfunc/futext3.cxx2
-rw-r--r--sc/source/ui/formdlg/formula.cxx7
-rw-r--r--sc/source/ui/inc/docfunc.hxx9
-rw-r--r--sc/source/ui/inc/docsh.hxx3
-rw-r--r--sc/source/ui/inc/formula.hxx1
-rw-r--r--sc/source/ui/inc/gridwin.hxx9
-rw-r--r--sc/source/ui/inc/printfun.hxx2
-rw-r--r--sc/source/ui/inc/protectiondlg.hrc47
-rw-r--r--sc/source/ui/inc/protectiondlg.hxx85
-rw-r--r--sc/source/ui/inc/retypepassdlg.hrc74
-rw-r--r--sc/source/ui/inc/retypepassdlg.hxx177
-rw-r--r--sc/source/ui/inc/scui_def.hxx2
-rw-r--r--sc/source/ui/inc/sortdlg.hrc8
-rw-r--r--sc/source/ui/inc/sortdlg.hxx18
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx3
-rw-r--r--sc/source/ui/inc/undoblk.hxx30
-rw-r--r--sc/source/ui/inc/undotab.hxx46
-rw-r--r--sc/source/ui/inc/viewfunc.hxx4
-rw-r--r--sc/source/ui/miscdlgs/makefile.mk16
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.cxx164
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.src130
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.cxx547
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.src316
-rw-r--r--sc/source/ui/src/filter.src64
-rw-r--r--sc/source/ui/src/globstr.src4
-rw-r--r--sc/source/ui/src/sortdlg.src44
-rw-r--r--sc/source/ui/undo/undoblk3.cxx105
-rw-r--r--sc/source/ui/undo/undocell.cxx11
-rw-r--r--sc/source/ui/undo/undotab.cxx303
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx47
-rw-r--r--sc/source/ui/unoobj/chart2uno.cxx16
-rw-r--r--sc/source/ui/unoobj/datauno.cxx158
-rw-r--r--sc/source/ui/unoobj/docuno.cxx35
-rw-r--r--sc/source/ui/unoobj/editsrc.cxx3
-rw-r--r--sc/source/ui/unoobj/fmtuno.cxx145
-rw-r--r--sc/source/ui/unoobj/notesuno.cxx6
-rw-r--r--sc/source/ui/unoobj/scdetect.cxx2
-rw-r--r--sc/source/ui/unoobj/tokenuno.cxx53
-rw-r--r--sc/source/ui/unoobj/viewuno.cxx5
-rw-r--r--sc/source/ui/unoobj/warnpassword.cxx1
-rw-r--r--sc/source/ui/vba/vbacontrol.cxx9
-rw-r--r--sc/source/ui/vba/vbarange.cxx52
-rw-r--r--sc/source/ui/view/cellsh1.cxx28
-rw-r--r--sc/source/ui/view/cellsh2.cxx358
-rw-r--r--sc/source/ui/view/cellsh3.cxx10
-rw-r--r--sc/source/ui/view/dbfunc3.cxx6
-rw-r--r--sc/source/ui/view/gridwin.cxx206
-rw-r--r--sc/source/ui/view/gridwin5.cxx4
-rw-r--r--sc/source/ui/view/output2.cxx6
-rw-r--r--sc/source/ui/view/preview.cxx4
-rw-r--r--sc/source/ui/view/printfun.cxx5
-rw-r--r--sc/source/ui/view/scextopt.cxx4
-rw-r--r--sc/source/ui/view/select.cxx23
-rw-r--r--sc/source/ui/view/tabview3.cxx46
-rw-r--r--sc/source/ui/view/tabvwsh3.cxx218
-rw-r--r--sc/source/ui/view/tabvwsh4.cxx4
-rw-r--r--sc/source/ui/view/tabvwsh5.cxx5
-rw-r--r--sc/source/ui/view/tabvwshh.cxx21
-rw-r--r--sc/source/ui/view/viewfun2.cxx4
-rw-r--r--sc/source/ui/view/viewfun4.cxx128
-rw-r--r--sc/source/ui/view/viewfun6.cxx6
-rw-r--r--sc/source/ui/view/viewfunc.cxx183
-rw-r--r--sc/util/makefile.mk2
-rw-r--r--scaddins/prj/build.lst2
-rw-r--r--sccomp/prj/build.lst2
293 files changed, 22743 insertions, 3612 deletions
diff --git a/chart2/prj/build.lst b/chart2/prj/build.lst
index d824fc575bca..0d4978606d11 100644
--- a/chart2/prj/build.lst
+++ b/chart2/prj/build.lst
@@ -1,4 +1,4 @@
-ch chart2 : comphelper cppu cppuhelper sal svtools svx tools vcl toolkit unotools sfx2 goodies NULL
+ch chart2 : l10n comphelper cppu cppuhelper sal svtools svx tools vcl toolkit unotools sfx2 goodies NULL
ch chart2 usr1 - all ch_mkout NULL
ch chart2\inc nmake - all ch_inc NULL
ch chart2\source\inc get - all ch_source_inc NULL
diff --git a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx
index 4b44b2e0593d..3d930f72f0af 100644
--- a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx
+++ b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx
@@ -177,6 +177,17 @@ sal_Int32 Chart2ModelContact::getExplicitNumberFormatKeyForAxis(
, Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) );
}
+sal_Int32 Chart2ModelContact::getExplicitNumberFormatKeyForSeries(
+ const Reference< chart2::XDataSeries >& xSeries )
+{
+ return ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
+ uno::Reference< beans::XPropertySet >( xSeries, uno::UNO_QUERY ),
+ xSeries,
+ -1 /*-1 for whole series*/,
+ ChartModelHelper::findDiagram( m_xChartModel )
+ );
+}
+
//-----------------------------------------------------------------------------
awt::Size Chart2ModelContact::GetPageSize() const
diff --git a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx
index b8ce668dff28..0cc8a16bafff 100644
--- a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx
+++ b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx
@@ -34,6 +34,7 @@
#include <com/sun/star/chart2/ExplicitIncrementData.hpp>
#include <com/sun/star/chart2/XAxis.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XTitle.hpp>
#include <cppuhelper/weakref.hxx>
@@ -87,6 +88,9 @@ public:
sal_Int32 getExplicitNumberFormatKeyForAxis(
const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis );
+ sal_Int32 getExplicitNumberFormatKeyForSeries(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries );
+
/** Returns the size of the page in logic coordinates. This value is used
for setting an appropriate "ReferencePageSize" for FontHeights.
*/
diff --git a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx
index 3e3b7254f578..fcc17fefeebc 100644
--- a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx
@@ -98,6 +98,7 @@ enum eServiceType
SERVICE_NAME_PIE_DIAGRAM,
SERVICE_NAME_STOCK_DIAGRAM,
SERVICE_NAME_XY_DIAGRAM,
+ SERVICE_NAME_BUBBLE_DIAGRAM,
SERVICE_NAME_DASH_TABLE,
SERVICE_NAME_GARDIENT_TABLE,
@@ -126,6 +127,7 @@ tServiceNameMap & lcl_getStaticServiceNameMap()
( C2U( "com.sun.star.chart.PieDiagram" ), SERVICE_NAME_PIE_DIAGRAM )
( C2U( "com.sun.star.chart.StockDiagram" ), SERVICE_NAME_STOCK_DIAGRAM )
( C2U( "com.sun.star.chart.XYDiagram" ), SERVICE_NAME_XY_DIAGRAM )
+ ( C2U( "com.sun.star.chart.BubbleDiagram" ), SERVICE_NAME_BUBBLE_DIAGRAM )
( C2U( "com.sun.star.drawing.DashTable" ), SERVICE_NAME_DASH_TABLE )
( C2U( "com.sun.star.drawing.GradientTable" ), SERVICE_NAME_GARDIENT_TABLE )
@@ -1367,6 +1369,16 @@ uno::Reference< uno::XInterface > SAL_CALL ChartDocumentWrapper::createInstance(
}
break;
+ case SERVICE_NAME_BUBBLE_DIAGRAM:
+ if( xManagerFact.is())
+ {
+ xTemplate.set(
+ xManagerFact->createInstance(
+ C2U( "com.sun.star.chart2.template.Bubble" )), uno::UNO_QUERY );
+ bCreateDiagram = true;
+ }
+ break;
+
case SERVICE_NAME_DASH_TABLE:
case SERVICE_NAME_GARDIENT_TABLE:
case SERVICE_NAME_HATCH_TABLE:
diff --git a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
index a6c18f9475dc..ce417155dc4f 100644
--- a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
@@ -50,6 +50,7 @@
#include "WrappedDataCaptionProperties.hxx"
#include "WrappedSeriesAreaOrLineProperty.hxx"
#include "WrappedScaleTextProperties.hxx"
+#include "WrappedNumberFormatProperty.hxx"
#include "WrappedTextRotationProperty.hxx"
#include <rtl/ustrbuf.hxx>
#include <rtl/math.hxx>
@@ -88,6 +89,7 @@ enum
PROP_SERIES_DATAPOINT_PERCENT_DIAGONAL,
PROP_SERIES_DATAPOINT_LABEL_SEPARATOR,
PROP_SERIES_NUMBERFORMAT,
+ PROP_SERIES_LINK_NUMBERFORMAT_TO_SOURCE,
PROP_SERIES_PERCENTAGE_NUMBERFORMAT,
PROP_SERIES_DATAPOINT_LABEL_PLACEMENT,
//other series properties
@@ -165,6 +167,13 @@ void lcl_AddPropertiesToVector_SeriesOnly(
::getCppuType( reinterpret_cast< sal_Int32 * >(0)),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LinkNumberFormatToSource" ),
+ PROP_SERIES_LINK_NUMBERFORMAT_TO_SOURCE,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
}
const uno::Sequence< Property > & lcl_GetPropertySequence( DataSeriesPointWrapper::eType _eType )
@@ -713,6 +722,10 @@ const std::vector< WrappedProperty* > DataSeriesPointWrapper::createWrappedPrope
{
WrappedStatisticProperties::addWrappedPropertiesForSeries( aWrappedProperties, m_spChart2ModelContact );
aWrappedProperties.push_back( new WrappedAttachedAxisProperty( m_spChart2ModelContact ) );
+
+ WrappedNumberFormatProperty* pWrappedNumberFormatProperty = new WrappedNumberFormatProperty( m_spChart2ModelContact );
+ aWrappedProperties.push_back( pWrappedNumberFormatProperty );
+ aWrappedProperties.push_back( new WrappedLinkNumberFormatProperty(pWrappedNumberFormatProperty) );
}
WrappedSymbolProperties::addWrappedPropertiesForSeries( aWrappedProperties, m_spChart2ModelContact );
diff --git a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
index 5bd12775fbcd..fe1359aab7f3 100644
--- a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx
@@ -549,6 +549,9 @@ OUString lcl_getDiagramType( const OUString & rTemplateServiceName )
if( aName.indexOf( C2U("Stock") ) != -1 )
return C2U( "com.sun.star.chart.StockDiagram" );
+ if( aName.indexOf( C2U("Bubble") ) != -1 )
+ return C2U( "com.sun.star.chart.BubbleDiagram" );
+
// Note: this must be checked after Bar, Net and Scatter
// "Symbol" "StackedSymbol" "PercentStackedSymbol" "Line" "StackedLine"
@@ -594,6 +597,9 @@ const tMakeStringStringMap& lcl_getChartTypeNameMap()
( ::rtl::OUString::createFromAscii( "com.sun.star.chart2.CandleStickChartType" )
, ::rtl::OUString::createFromAscii( "com.sun.star.chart.StockDiagram" ) )
+ ( ::rtl::OUString::createFromAscii( "com.sun.star.chart2.BubbleChartType" )
+ , ::rtl::OUString::createFromAscii( "com.sun.star.chart.BubbleDiagram" ) )
+
;
return g_aChartTypeNameMap;
}
diff --git a/chart2/source/controller/chartapiwrapper/WrappedNumberFormatProperty.cxx b/chart2/source/controller/chartapiwrapper/WrappedNumberFormatProperty.cxx
index 4110a6ef3b54..00101ef10f34 100644
--- a/chart2/source/controller/chartapiwrapper/WrappedNumberFormatProperty.cxx
+++ b/chart2/source/controller/chartapiwrapper/WrappedNumberFormatProperty.cxx
@@ -98,8 +98,15 @@ Any WrappedNumberFormatProperty::getPropertyValue( const Reference< beans::XProp
Any aRet( xInnerPropertySet->getPropertyValue( m_aInnerName ));
if( !aRet.hasValue() )
{
- Reference< chart2::XAxis > xAxis( xInnerPropertySet, uno::UNO_QUERY );
- sal_Int32 nKey = m_spChart2ModelContact->getExplicitNumberFormatKeyForAxis( xAxis );
+ sal_Int32 nKey = 0;
+ Reference< chart2::XDataSeries > xSeries( xInnerPropertySet, uno::UNO_QUERY );
+ if( xSeries.is() )
+ nKey = m_spChart2ModelContact->getExplicitNumberFormatKeyForSeries( xSeries );
+ else
+ {
+ Reference< chart2::XAxis > xAxis( xInnerPropertySet, uno::UNO_QUERY );
+ nKey = m_spChart2ModelContact->getExplicitNumberFormatKeyForAxis( xAxis );
+ }
aRet <<= nKey;
}
return aRet;
diff --git a/chart2/source/controller/dialogs/Bitmaps.hrc b/chart2/source/controller/dialogs/Bitmaps.hrc
index 58b1d540cc1a..07ed2eeec0d5 100644
--- a/chart2/source/controller/dialogs/Bitmaps.hrc
+++ b/chart2/source/controller/dialogs/Bitmaps.hrc
@@ -34,23 +34,28 @@
#include <svtools/solar.hrc>
#endif
-// next free: 100
-
#ifndef STD_MASKCOLOR
#define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
#endif
//-----------------------------------------------------------------------------
// chart types
+// Images:
#define IMG_TYPE_COLUMN (RID_APP_START + 1)
#define IMG_TYPE_BAR (RID_APP_START + 2)
#define IMG_TYPE_PIE (RID_APP_START + 3)
-#define IMG_TYPE_LINE (RID_APP_START + 4)
-#define IMG_TYPE_AREA (RID_APP_START + 5)
-#define IMG_TYPE_NET (RID_APP_START + 6)
-#define IMG_TYPE_STOCK (RID_APP_START + 7)
-#define IMG_TYPE_COLUMN_LINE (RID_APP_START + 8)
+#define IMG_TYPE_AREA (RID_APP_START + 4)
+#define IMG_TYPE_LINE (RID_APP_START + 5)
+#define IMG_TYPE_XY (RID_APP_START + 6)
+#define IMG_TYPE_BUBBLE (RID_APP_START + 7)
+#define IMG_TYPE_NET (RID_APP_START + 8)
+#define IMG_TYPE_STOCK (RID_APP_START + 9)
+#define IMG_TYPE_COLUMN_LINE (RID_APP_START + 10)
+
+//-----------------------------------------------------------------------------
+//Chart Subtypes
+// Bitmaps:
//----------------------
// Column Chart Subtypes
@@ -185,7 +190,13 @@
#define BMP_COLUMN_LINE (RID_APP_START + 86)
#define BMP_COLUMN_LINE_STACKED (RID_APP_START + 87)
+//----------------------
+// Bubble Chart Subtypes
+#define BMP_BUBBLE_1 (RID_APP_START + 88)
+
//-----------------------------------------------------------------------------
+//further Images:
+
//SchStatisticTabPage and SchDataStatisticsDlg part 1
#define BMP_INDICATE_BOTH_VERTI (RID_APP_START + 89)
#define BMP_INDICATE_UP (RID_APP_START + 90)
@@ -201,9 +212,8 @@
#define BMP_REGRESSION_EXP (RID_APP_START + 95)
#define BMP_REGRESSION_POWER (RID_APP_START + 96)
-//-----------------------------------------------------------------------------
// hide-button for range-choosing
-#define IMG_SELECTRANGE (RID_APP_START + 9)
+#define IMG_SELECTRANGE (RID_APP_START + 100)
// CHART_BITMAPS_HRC
#endif
diff --git a/chart2/source/controller/dialogs/Bitmaps.src b/chart2/source/controller/dialogs/Bitmaps.src
index 2af607b6963c..35a897848fb1 100644
--- a/chart2/source/controller/dialogs/Bitmaps.src
+++ b/chart2/source/controller/dialogs/Bitmaps.src
@@ -49,6 +49,11 @@ Image IMG_TYPE_LINE
ImageBitmap = Bitmap { File = "typepointline_16.png" ; };
MaskColor = STD_MASKCOLOR;
};
+Image IMG_TYPE_XY
+{
+ ImageBitmap = Bitmap { File = "typexy_16.png" ; };
+ MaskColor = STD_MASKCOLOR;
+};
Image IMG_TYPE_AREA
{
ImageBitmap = Bitmap { File = "typearea_16.png" ; };
@@ -69,6 +74,15 @@ Image IMG_TYPE_COLUMN_LINE
ImageBitmap = Bitmap { File = "typecolumnline_16.png" ; };
MaskColor = STD_MASKCOLOR;
};
+Image IMG_TYPE_BUBBLE
+{
+ ImageBitmap = Bitmap { File = "typebubble_16.png" ; };
+ MaskColor = STD_MASKCOLOR;
+};
+Bitmap BMP_BUBBLE_1
+{
+ File = "bubble_52x60.png" ;
+};
Bitmap BMP_AREAS_2D
{
File = "areas_52x60.png" ;
diff --git a/chart2/source/controller/dialogs/Bitmaps_HC.hrc b/chart2/source/controller/dialogs/Bitmaps_HC.hrc
index 0b65579973c5..84a23ba426bc 100644
--- a/chart2/source/controller/dialogs/Bitmaps_HC.hrc
+++ b/chart2/source/controller/dialogs/Bitmaps_HC.hrc
@@ -41,15 +41,22 @@
//-----------------------------------------------------------------------------
// chart types
+// Images:
#define IMG_TYPE_COLUMN_HC (RID_SCH_START + 1)
#define IMG_TYPE_BAR_HC (RID_SCH_START + 2)
#define IMG_TYPE_PIE_HC (RID_SCH_START + 3)
-#define IMG_TYPE_LINE_HC (RID_SCH_START + 4)
-#define IMG_TYPE_AREA_HC (RID_SCH_START + 5)
-#define IMG_TYPE_NET_HC (RID_SCH_START + 6)
-#define IMG_TYPE_STOCK_HC (RID_SCH_START + 7)
-#define IMG_TYPE_COLUMN_LINE_HC (RID_SCH_START + 8)
+#define IMG_TYPE_AREA_HC (RID_SCH_START + 4)
+#define IMG_TYPE_LINE_HC (RID_SCH_START + 5)
+#define IMG_TYPE_XY_HC (RID_SCH_START + 6)
+#define IMG_TYPE_BUBBLE_HC (RID_SCH_START + 7)
+#define IMG_TYPE_NET_HC (RID_SCH_START + 8)
+#define IMG_TYPE_STOCK_HC (RID_SCH_START + 9)
+#define IMG_TYPE_COLUMN_LINE_HC (RID_SCH_START + 10)
+
+//-----------------------------------------------------------------------------
+//Chart Subtypes
+// Bitmaps:
//----------------------
// Column Chart Subtypes
@@ -183,7 +190,13 @@
#define BMP_COLUMN_LINE_HC (RID_SCH_START + 86)
#define BMP_COLUMN_LINE_STACKED_HC (RID_SCH_START + 87)
+//----------------------
+// Bubble Chart Subtypes
+#define BMP_BUBBLE_1_HC (RID_SCH_START + 88)
+
//-----------------------------------------------------------------------------
+//further Images:
+
//SchStatisticTabPage and SchDataStatisticsDlg part 1
#define BMP_INDICATE_BOTH_VERTI_HC (RID_SCH_START + 89)
#define BMP_INDICATE_UP_HC (RID_SCH_START + 90)
@@ -199,6 +212,5 @@
#define BMP_REGRESSION_EXP_HC (RID_SCH_START + 95)
#define BMP_REGRESSION_POWER_HC (RID_SCH_START + 96)
-//-----------------------------------------------------------------------------
// hide-button for range-choosing
-#define IMG_SELECTRANGE_HC (RID_SCH_START + 9)
+#define IMG_SELECTRANGE_HC (RID_SCH_START + 100)
diff --git a/chart2/source/controller/dialogs/Bitmaps_HC.src b/chart2/source/controller/dialogs/Bitmaps_HC.src
index 1e2fe5f4ba14..0fb7ef5e5a1a 100644
--- a/chart2/source/controller/dialogs/Bitmaps_HC.src
+++ b/chart2/source/controller/dialogs/Bitmaps_HC.src
@@ -49,6 +49,11 @@ Image IMG_TYPE_LINE_HC
ImageBitmap = Bitmap { File = "typepointline_16.png" ; };
MaskColor = SC_HC_MASKCOLOR;
};
+Image IMG_TYPE_XY_HC
+{
+ ImageBitmap = Bitmap { File = "typexy_16.png" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+};
Image IMG_TYPE_AREA_HC
{
ImageBitmap = Bitmap { File = "typearea_16.png" ; };
@@ -69,6 +74,15 @@ Image IMG_TYPE_COLUMN_LINE_HC
ImageBitmap = Bitmap { File = "typecolumnline_16.png" ; };
MaskColor = SC_HC_MASKCOLOR;
};
+Image IMG_TYPE_BUBBLE_HC
+{
+ ImageBitmap = Bitmap { File = "typebubble_16.png" ; };
+ MaskColor = SC_HC_MASKCOLOR;
+};
+Bitmap BMP_BUBBLE_1_HC
+{
+ File = "bubble_52x60_h.png" ;
+};
Bitmap BMP_AREAS_2D_HC
{
File = "areas_52x60_h.png" ;
diff --git a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx
index 79efe0b04919..de57e82e58da 100644
--- a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx
+++ b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx
@@ -808,7 +808,7 @@ String XYChartDialogController::getName()
}
Image XYChartDialogController::getImage( bool bIsHighContrast )
{
- return SELECT_IMAGE( IMG_TYPE_LINE );
+ return SELECT_IMAGE( IMG_TYPE_XY );
}
const tTemplateServiceChartTypeParameterMap& XYChartDialogController::getTemplateMap() const
{
@@ -1238,6 +1238,40 @@ void CombiColumnLineChartDialogController::adjustParameterToSubType( ChartTypePa
break;
}
}
+//--------------------------------------------------------------------------
+BubbleChartDialogController::BubbleChartDialogController()
+{
+}
+BubbleChartDialogController::~BubbleChartDialogController()
+{
+}
+String BubbleChartDialogController::getName()
+{
+ return String( SchResId( STR_TYPE_BUBBLE ));
+}
+Image BubbleChartDialogController::getImage( bool bIsHighContrast )
+{
+ return SELECT_IMAGE( IMG_TYPE_BUBBLE );
+}
+const tTemplateServiceChartTypeParameterMap& BubbleChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap m_aTemplateMap =
+ tTemplateServiceChartTypeParameterMap
+ ( C2U( "com.sun.star.chart2.template.Bubble" ), ChartTypeParameter(1,true) ) ;
+ return m_aTemplateMap;
+}
+void BubbleChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, bool bIsHighContrast, const ChartTypeParameter& /*rParameter*/ )
+{
+ rSubTypeList.Clear();
+ rSubTypeList.InsertItem( 1, SELECT_BITMAP( BMP_BUBBLE_1 ) );
+
+ rSubTypeList.SetItemText( 1, String( SchResId( STR_BUBBLE_1 )) );
+}
+void BubbleChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+ rParameter.eStackMode = GlobalStackMode_NONE;
+}
//.............................................................................
} //namespace chart
//.............................................................................
diff --git a/chart2/source/controller/dialogs/ChartTypeDialogController.hxx b/chart2/source/controller/dialogs/ChartTypeDialogController.hxx
index 0f6c7a8ae2c0..cdbda807813f 100644
--- a/chart2/source/controller/dialogs/ChartTypeDialogController.hxx
+++ b/chart2/source/controller/dialogs/ChartTypeDialogController.hxx
@@ -301,6 +301,19 @@ private:
MetricField* m_pMF_NumberOfLines;
};
+class BubbleChartDialogController : public ChartTypeDialogController
+{
+public:
+ BubbleChartDialogController();
+ virtual ~BubbleChartDialogController();
+
+ virtual String getName();
+ virtual Image getImage( bool bIsHighContrast );
+ virtual const tTemplateServiceChartTypeParameterMap& getTemplateMap() const;
+ virtual void fillSubTypeList( ValueSet& rSubTypeList, bool bIsHighContrast, const ChartTypeParameter& rParameter );
+ virtual void adjustParameterToSubType( ChartTypeParameter& rParameter );
+};
+
//.............................................................................
} //namespace chart
//.............................................................................
diff --git a/chart2/source/controller/dialogs/DataBrowser.cxx b/chart2/source/controller/dialogs/DataBrowser.cxx
index cf61b88a63ac..0a9b58758de6 100644
--- a/chart2/source/controller/dialogs/DataBrowser.cxx
+++ b/chart2/source/controller/dialogs/DataBrowser.cxx
@@ -407,8 +407,7 @@ Image SeriesHeader::GetChartTypeImage(
}
else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ))
{
- // @todo: correct image for scatter chart type
- aResult = SELECT_IMAGE( IMG_TYPE_LINE, bHC );
+ aResult = SELECT_IMAGE( IMG_TYPE_XY, bHC );
}
else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_PIE ))
{
@@ -423,6 +422,10 @@ Image SeriesHeader::GetChartTypeImage(
// @todo: correct image for candle-stick type
aResult = SELECT_IMAGE( IMG_TYPE_STOCK, bHC );
}
+ else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ))
+ {
+ aResult = SELECT_IMAGE( IMG_TYPE_BUBBLE, bHC );
+ }
return aResult;
}
@@ -1068,6 +1071,7 @@ sal_Bool DataBrowser::IsTabAllowed( sal_Bool bForward ) const
if( CellContainsNumbers( nRow, nCol ))
{
+ m_aNumberEditField.UseInputStringForFormatting();
m_aNumberEditField.SetFormatKey( GetNumberFormatKey( nRow, nCol ));
return m_rNumberEditController;
}
diff --git a/chart2/source/controller/dialogs/DataBrowserModel.cxx b/chart2/source/controller/dialogs/DataBrowserModel.cxx
index e612edc0901b..1db67c6721af 100644
--- a/chart2/source/controller/dialogs/DataBrowserModel.cxx
+++ b/chart2/source/controller/dialogs/DataBrowserModel.cxx
@@ -41,6 +41,8 @@
#include "macros.hxx"
#include "StatisticsHelper.hxx"
#include "ContainerHelper.hxx"
+#include "ChartTypeHelper.hxx"
+#include "chartview/ExplicitValueProvider.hxx"
#include <com/sun/star/container/XIndexReplace.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
@@ -329,6 +331,8 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex )
Reference< chart2::XDataSeries > xSeries;
if( static_cast< tDataColumnVector::size_type >( nAfterColumnIndex ) <= m_aColumns.size())
xSeries.set( m_aColumns[nAfterColumnIndex].m_xDataSeries );
+
+ sal_Int32 nSeriesNumberFormat = 0;
if( xSeries.is())
{
xChartType.set( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ));
@@ -337,6 +341,10 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex )
lcl_DataSeriesOfHeaderMatches( xSeries )));
if( aIt != m_aHeaders.end())
nStartCol = aIt->m_nEndColumn;
+
+ Reference< beans::XPropertySet > xSeriesProps( xSeries, uno::UNO_QUERY );
+ if( xSeriesProps.is() )
+ xSeriesProps->getPropertyValue( C2U( "NumberFormat" )) >>= nSeriesNumberFormat;
}
else
{
@@ -404,6 +412,14 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex )
}
}
}
+ if( nSeriesNumberFormat != 0 )
+ {
+ //give the new series the same number format as the former series especially for bubble charts thus the bubble size values can be edited with same format immidiately
+ Reference< beans::XPropertySet > xNewSeriesProps( xNewSeries, uno::UNO_QUERY );
+ if( xNewSeriesProps.is() )
+ xNewSeriesProps->setPropertyValue( C2U( "NumberFormat" ), uno::makeAny( nSeriesNumberFormat ) );
+ }
+
updateFromModel();
}
}
@@ -724,11 +740,15 @@ void DataBrowserModel::updateFromModel()
{
Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
+ sal_Int32 nXAxisNumberFormat = DataSeriesHelper::getNumberFormatKeyFromAxis( 0, aCooSysSeq[nCooSysIdx], 0, 0 );
+
for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
{
Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
if( xSeriesCnt.is())
{
+ rtl::OUString aRoleForDataLabelNumberFormat = ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( aChartTypes[nCTIdx] );
+
Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
lcl_tSharedSeqVec aSharedSequences( lcl_getSharedSequences( aSeries ));
for( lcl_tSharedSeqVec::const_iterator aIt( aSharedSequences.begin());
@@ -741,16 +761,15 @@ void DataBrowserModel::updateFromModel()
// as the sequences are shared it should be ok to take the first series
// @todo: dimension index 0 for x-values used here. This is just a guess.
// Also, the axis index is 0, as there is usually only one x-axis
- aSharedSequence.m_nNumberFormatKey =
- DataSeriesHelper::getNumberFormatKeyFromAxis(
- aSeries[0], aCooSysSeq[nCooSysIdx], 0, 0 );
+ aSharedSequence.m_nNumberFormatKey = nXAxisNumberFormat;
m_aColumns.push_back( aSharedSequence );
++nHeaderStart;
}
for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
{
tDataColumnVector::size_type nStartColIndex = m_aColumns.size();
- Reference< chart2::data::XDataSource > xSource( aSeries[nSeriesIdx], uno::UNO_QUERY );
+ Reference< chart2::XDataSeries > xSeries( aSeries[nSeriesIdx] );
+ Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
if( xSource.is())
{
Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeqs( xSource->getDataSequences());
@@ -768,9 +787,14 @@ void DataBrowserModel::updateFromModel()
{
sal_Int32 nSequenceNumberFormatKey = nYAxisNumberFormatKey;
OUString aRole = lcl_getRole( aLSeqs[nSeqIdx] );
- if( aRole.equals( C2U( "values-x" ) ) )
- nSequenceNumberFormatKey = DataSeriesHelper::getNumberFormatKeyFromAxis(
- aSeries[nSeriesIdx], aCooSysSeq[nCooSysIdx], 0, 0 );
+
+ if( aRole.equals( aRoleForDataLabelNumberFormat ) )
+ {
+ nSequenceNumberFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
+ Reference< beans::XPropertySet >( xSeries, uno::UNO_QUERY ), xSeries, -1, xDiagram );
+ }
+ else if( aRole.equals( C2U( "values-x" ) ) )
+ nSequenceNumberFormatKey = nXAxisNumberFormat;
if( ::std::find_if( aSharedSequences.begin(), aSharedSequences.end(),
lcl_RepresentationsOfLSeqMatch( aLSeqs[nSeqIdx] )) == aSharedSequences.end())
diff --git a/chart2/source/controller/dialogs/DialogModel.cxx b/chart2/source/controller/dialogs/DialogModel.cxx
index 1a7e8675f5bc..69e693911c22 100644
--- a/chart2/source/controller/dialogs/DialogModel.cxx
+++ b/chart2/source/controller/dialogs/DialogModel.cxx
@@ -108,6 +108,7 @@ OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI )
aTranslationMap[ C2U( "values-min" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN )));
aTranslationMap[ C2U( "values-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X )));
aTranslationMap[ C2U( "values-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y )));
+ aTranslationMap[ C2U( "values-size" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE )));
}
if( bFromInternalToUI )
@@ -155,6 +156,7 @@ void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
rOutMap[ C2U( "values-min" ) ] = ++nIndex;
rOutMap[ C2U( "values-max" ) ] = ++nIndex;
rOutMap[ C2U( "values-last" ) ] = ++nIndex;
+ rOutMap[ C2U( "values-size" ) ] = ++nIndex;
}
struct lcl_DataSeriesContainerAppend : public
diff --git a/chart2/source/controller/dialogs/ObjectNameProvider.cxx b/chart2/source/controller/dialogs/ObjectNameProvider.cxx
index 7ee4ae67761d..1ed974814ea7 100644
--- a/chart2/source/controller/dialogs/ObjectNameProvider.cxx
+++ b/chart2/source/controller/dialogs/ObjectNameProvider.cxx
@@ -109,7 +109,7 @@ OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal
Sequence< Reference< data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
- rtl::OUString aX, aY, aY_Min, aY_Max, aY_First, aY_Last;
+ rtl::OUString aX, aY, aY_Min, aY_Max, aY_First, aY_Last, a_Size;
double fValue = 0;
uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
@@ -170,6 +170,12 @@ OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal
sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
aY_Last = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
}
+ else if( aRole.equals(C2U("values-size")) )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ a_Size = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
}
catch( uno::Exception& e )
{
@@ -201,6 +207,7 @@ OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal
lcl_addText( aRet, aSeparator, aY_Min );
lcl_addText( aRet, aSeparator, aY_Max );
lcl_addText( aRet, aSeparator, aY_Last );
+ lcl_addText( aRet, aSeparator, a_Size );
return aRet;
}
diff --git a/chart2/source/controller/dialogs/Strings.src b/chart2/source/controller/dialogs/Strings.src
index b08fe754513f..3b384915f2d0 100644
--- a/chart2/source/controller/dialogs/Strings.src
+++ b/chart2/source/controller/dialogs/Strings.src
@@ -471,6 +471,11 @@ String STR_DATA_ROLE_Y
Text [ en-US ] = "Y-Values" ;
};
+String STR_DATA_ROLE_SIZE
+{
+ Text [ en-US ] = "Bubble Sizes" ;
+};
+
String STR_DATA_ROLE_X_ERROR
{
Text [ en-US ] = "X-Error-Bars" ;
diff --git a/chart2/source/controller/dialogs/Strings_ChartTypes.src b/chart2/source/controller/dialogs/Strings_ChartTypes.src
index 1e18f0e8724f..2234f04a3fcd 100644
--- a/chart2/source/controller/dialogs/Strings_ChartTypes.src
+++ b/chart2/source/controller/dialogs/Strings_ChartTypes.src
@@ -140,4 +140,13 @@ String STR_DEEP
Text [ en-US ] = "Deep" ;
};
//-----------------------------------------------------------------------------
+String STR_TYPE_BUBBLE
+{
+ Text [ en-US ] = "Bubble" ;
+};
+String STR_BUBBLE_1
+{
+ Text [ en-US ] = "Bubble Chart" ;
+};
+//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
diff --git a/chart2/source/controller/dialogs/res_DataLabel.cxx b/chart2/source/controller/dialogs/res_DataLabel.cxx
index a93711151ac1..c6129629a51a 100644
--- a/chart2/source/controller/dialogs/res_DataLabel.cxx
+++ b/chart2/source/controller/dialogs/res_DataLabel.cxx
@@ -215,6 +215,13 @@ DataLabelResources::DataLabelResources( Window* pWindow, const SfxItemSet& rInAt
m_bNumberFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, m_nNumberFormatForValue, m_bSourceFormatForValue, m_bSourceFormatMixedState );
m_bPercentFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_nNumberFormatForPercent, m_bSourceFormatForPercent , m_bPercentSourceMixedState);
+ if( rInAttrs.GetItemState(SCHATTR_DATADESCR_NO_PERCENTVALUE, TRUE, &pPoolItem) == SFX_ITEM_SET )
+ {
+ bool bForbidPercentValue = (static_cast< const SfxBoolItem & >( rInAttrs.Get( SCHATTR_DATADESCR_NO_PERCENTVALUE )).GetValue() );
+ if( bForbidPercentValue )
+ m_aCBPercent.Enable(false);
+ }
+
m_aDC_Dial.SetLinkedField( &m_aNF_Degrees );
}
@@ -286,14 +293,14 @@ IMPL_LINK( DataLabelResources, CheckHdl, CheckBox*, pBox )
void DataLabelResources::EnableControls()
{
- m_aCBSymbol.Enable( m_aCBNumber.IsChecked() || m_aCBPercent.IsChecked() || m_aCBCategory.IsChecked() );
+ m_aCBSymbol.Enable( m_aCBNumber.IsChecked() || (m_aCBPercent.IsChecked() && m_aCBPercent.IsEnabled()) || m_aCBCategory.IsChecked() );
//enable separator
{
long nNumberOfCheckedLabelParts = 0;
if( m_aCBNumber.IsChecked() )
++nNumberOfCheckedLabelParts;
- if( m_aCBPercent.IsChecked() )
+ if( m_aCBPercent.IsChecked() && m_aCBPercent.IsEnabled() )
++nNumberOfCheckedLabelParts;
if( m_aCBCategory.IsChecked() )
++nNumberOfCheckedLabelParts;
@@ -307,7 +314,7 @@ void DataLabelResources::EnableControls()
}
m_aPB_NumberFormatForValue.Enable( m_pNumberFormatter && m_aCBNumber.IsChecked() );
- m_aPB_NumberFormatForPercent.Enable( m_pNumberFormatter && m_aCBPercent.IsChecked() );
+ m_aPB_NumberFormatForPercent.Enable( m_pNumberFormatter && m_aCBPercent.IsChecked() && m_aCBPercent.IsEnabled() );
bool bEnableRotation = ( m_aCBNumber.IsChecked() || m_aCBPercent.IsChecked() || m_aCBCategory.IsChecked() );
m_aFL_Rotate.Enable( bEnableRotation );
diff --git a/chart2/source/controller/dialogs/tp_ChartType.cxx b/chart2/source/controller/dialogs/tp_ChartType.cxx
index f60637af4c44..b2d64400ef98 100644
--- a/chart2/source/controller/dialogs/tp_ChartType.cxx
+++ b/chart2/source/controller/dialogs/tp_ChartType.cxx
@@ -862,6 +862,7 @@ ChartTypeTabPage::ChartTypeTabPage( Window* pParent
m_aChartTypeDialogControllerList.push_back(new AreaChartDialogController() );
m_aChartTypeDialogControllerList.push_back(new LineChartDialogController() );
m_aChartTypeDialogControllerList.push_back(new XYChartDialogController() );
+ m_aChartTypeDialogControllerList.push_back(new BubbleChartDialogController() );
m_aChartTypeDialogControllerList.push_back(new NetChartDialogController() );
m_aChartTypeDialogControllerList.push_back(new StockChartDialogController() );
m_aChartTypeDialogControllerList.push_back(new CombiColumnLineChartDialogController() );
diff --git a/chart2/source/controller/inc/DataPointItemConverter.hxx b/chart2/source/controller/inc/DataPointItemConverter.hxx
index a59170f4d699..4eec81bd20b5 100644
--- a/chart2/source/controller/inc/DataPointItemConverter.hxx
+++ b/chart2/source/controller/inc/DataPointItemConverter.hxx
@@ -103,6 +103,7 @@ private:
sal_Int32 m_nNumberFormat;
sal_Int32 m_nPercentNumberFormat;
::com::sun::star::uno::Sequence< sal_Int32 > m_aAvailableLabelPlacements;
+ bool m_bForbidPercentValue;
};
} // namespace wrapper
diff --git a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
index 0c0ea2d0dbdd..af062cf3b93c 100644
--- a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
@@ -239,7 +239,8 @@ DataPointItemConverter::DataPointItemConverter(
m_nSpecialFillColor(nSpecialFillColor),
m_nNumberFormat(nNumberFormat),
m_nPercentNumberFormat(nPercentNumberFormat),
- m_aAvailableLabelPlacements()
+ m_aAvailableLabelPlacements(),
+ m_bForbidPercentValue(true)
{
m_aConverters.push_back( new GraphicPropertyItemConverter(
rPropertySet, rItemPool, rDrawModel, xNamedPropertyContainerFactory, eMapTo ));
@@ -257,6 +258,8 @@ DataPointItemConverter::DataPointItemConverter(
bool bAmbiguous = false;
sal_Bool bSwapXAndY = DiagramHelper::getVertical( xDiagram, bFound, bAmbiguous );
m_aAvailableLabelPlacements = ChartTypeHelper::getSupportedLabelPlacements( xChartType, DiagramHelper::getDimension( xDiagram ), bSwapXAndY, xSeries );
+
+ m_bForbidPercentValue = AxisType::CATEGORY != ChartTypeHelper::getAxisType( xChartType, 0 );
}
DataPointItemConverter::~DataPointItemConverter()
@@ -648,6 +651,12 @@ void DataPointItemConverter::FillSpecialItem(
}
break;
+ case SCHATTR_DATADESCR_NO_PERCENTVALUE:
+ {
+ rOutItemSet.Put( SfxBoolItem( nWhichId, m_bForbidPercentValue ));
+ }
+ break;
+
case SCHATTR_STYLE_SYMBOL:
{
chart2::Symbol aSymbol;
diff --git a/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx b/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx
index 9f300e8febc1..4b626e1be839 100644
--- a/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx
+++ b/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx
@@ -141,9 +141,8 @@ AllDataLabelItemConverter::AllDataLabelItemConverter(
uno::Reference< beans::XPropertySet > xObjectProperties( *aIt, uno::UNO_QUERY);
uno::Reference< uno::XComponentContext> xContext(0);//do not need Context for label properties
- sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForLabel( xObjectProperties, *aIt, -1/*nPointIndex*/,
- uno::Reference< beans::XPropertySet >( DiagramHelper::getAttachedAxis( *aIt, ChartModelHelper::findDiagram( xChartModel ) ), uno::UNO_QUERY ) );
- sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForLabel(
+ sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( xObjectProperties, *aIt, -1/*nPointIndex*/, ChartModelHelper::findDiagram( xChartModel ) );
+ sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
xObjectProperties,uno::Reference< util::XNumberFormatsSupplier >(xChartModel, uno::UNO_QUERY));
m_aConverters.push_back( new ::chart::wrapper::DataPointItemConverter(
diff --git a/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx
index 0321df6035f2..dbefb0e7f025 100644
--- a/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx
+++ b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx
@@ -128,8 +128,6 @@ const USHORT nDataLabelWhichPairs[] =
SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, /* 11432 svx/svxids.hrc */ \
SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, /* 40 sch/schattr.hxx*/ \
SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, /* 41 sch/schattr.hxx*/ \
- SCHATTR_DATADESCR_PLACEMENT, SCHATTR_DATADESCR_PLACEMENT,
- SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS, SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS,
SCHATTR_TEXT_DEGREES,SCHATTR_TEXT_DEGREES,
EE_PARA_WRITINGDIR,EE_PARA_WRITINGDIR,
0
@@ -145,8 +143,6 @@ const USHORT nDataLabelWhichPairs[] =
SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, /* 11432 svx/svxids.hrc */ \
SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, /* 40 sch/schattr.hxx*/ \
SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, /* 41 sch/schattr.hxx*/ \
- SCHATTR_DATADESCR_PLACEMENT, SCHATTR_DATADESCR_PLACEMENT, \
- SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS, SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS, \
SCHATTR_TEXT_DEGREES, SCHATTR_TEXT_DEGREES, \
SCHATTR_STYLE_START,SCHATTR_STYLE_END, /* 59 - 68 sch/schattr.hxx*/ \
SCHATTR_SYMBOL_BRUSH,SCHATTR_SYMBOL_BRUSH, /* 94 sch/schattr.hxx*/ \
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
index c56a0317b4dc..b104e232b3b6 100644
--- a/chart2/source/controller/main/ChartController.cxx
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -480,7 +480,7 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent
{
//the view has become dirty, we should repaint it if we have a window
if( m_pChartWindow )
- m_pChartWindow->Invalidate();
+ m_pChartWindow->ForceInvalidate();
}
else if( rEvent.NewMode.equals(C2U("invalid")) )
{
@@ -490,8 +490,11 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent
if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() )
this->EndTextEdit();
if( m_pDrawViewWrapper )
+ {
m_pDrawViewWrapper->UnmarkAll();
//m_pDrawViewWrapper->hideMarkHandles(); todo??
+ m_pDrawViewWrapper->HideSdrPage();
+ }
}
else
{
diff --git a/chart2/source/controller/main/ChartController_Properties.cxx b/chart2/source/controller/main/ChartController_Properties.cxx
index 3b5b3d6fa7ba..530cd6f0aeb8 100644
--- a/chart2/source/controller/main/ChartController_Properties.cxx
+++ b/chart2/source/controller/main/ChartController_Properties.cxx
@@ -240,9 +240,8 @@ namespace
}
}
}
- sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForLabel( xObjectProperties, xSeries, nPointIndex,
- uno::Reference< beans::XPropertySet >( DiagramHelper::getAttachedAxis( xSeries, xDiagram ), uno::UNO_QUERY ) );
- sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForLabel(
+ sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( xObjectProperties, xSeries, nPointIndex, xDiagram );
+ sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
xObjectProperties,uno::Reference< util::XNumberFormatsSupplier >(xChartModel, uno::UNO_QUERY));
pItemConverter = new wrapper::DataPointItemConverter( xChartModel, xContext,
diff --git a/chart2/source/controller/main/ChartWindow.cxx b/chart2/source/controller/main/ChartWindow.cxx
index 5c9e201aebd8..10b999df8f43 100644
--- a/chart2/source/controller/main/ChartWindow.cxx
+++ b/chart2/source/controller/main/ChartWindow.cxx
@@ -60,6 +60,7 @@ namespace chart
ChartWindow::ChartWindow( WindowController* pWindowController, Window* pParent, WinBits nStyle )
: Window(pParent, nStyle)
, m_pWindowController( pWindowController )
+ , m_bInPaint(false)
{
this->SetSmartHelpId( SmartId( HID_SCH_WIN_DOCUMENT ) );
this->SetMapMode( MapMode(MAP_100TH_MM) );
@@ -67,7 +68,7 @@ ChartWindow::ChartWindow( WindowController* pWindowController, Window* pParent,
// chart does not depend on exact pixel painting => enable antialiased drawing
SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | GetAntialiasing() );
EnableRTL( FALSE );
- if( pParent )
+ if( pParent )
pParent->EnableRTL( FALSE );// #i96215# necessary for a correct position of the context menu in rtl mode
}
@@ -92,10 +93,12 @@ void ChartWindow::PrePaint()
void ChartWindow::Paint( const Rectangle& rRect )
{
+ m_bInPaint = true;
if( m_pWindowController )
m_pWindowController->execute_Paint( rRect );
else
Window::Paint( rRect );
+ m_bInPaint = false;
}
void ChartWindow::MouseButtonDown(const MouseEvent& rMEvt)
@@ -243,6 +246,29 @@ void ChartWindow::adjustHighContrastMode()
SetDrawMode( bUseContrast ? nContrastMode : DRAWMODE_DEFAULT );
}
+void ChartWindow::ForceInvalidate()
+{
+ ::Window::Invalidate();
+}
+void ChartWindow::Invalidate( USHORT nFlags )
+{
+ if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+ return;
+ ::Window::Invalidate( nFlags );
+}
+void ChartWindow::Invalidate( const Rectangle& rRect, USHORT nFlags )
+{
+ if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+ return;
+ ::Window::Invalidate( rRect, nFlags );
+}
+void ChartWindow::Invalidate( const Region& rRegion, USHORT nFlags )
+{
+ if( m_bInPaint ) // #i101928# superfluous paint calls while entering and editing charts"
+ return;
+ ::Window::Invalidate( rRegion, nFlags );
+}
+
//.............................................................................
} //namespace chart
//.............................................................................
diff --git a/chart2/source/controller/main/ChartWindow.hxx b/chart2/source/controller/main/ChartWindow.hxx
index 41cc7b514a07..543c0b13ffdc 100644
--- a/chart2/source/controller/main/ChartWindow.hxx
+++ b/chart2/source/controller/main/ChartWindow.hxx
@@ -70,10 +70,16 @@ public:
virtual void DataChanged( const DataChangedEvent& rDCEvt );
virtual void RequestHelp( const HelpEvent& rHEvt );
+ void ForceInvalidate();
+ virtual void Invalidate( USHORT nFlags = 0 );
+ virtual void Invalidate( const Rectangle& rRect, USHORT nFlags = 0 );
+ virtual void Invalidate( const Region& rRegion, USHORT nFlags = 0 );
+
virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
private:
WindowController* m_pWindowController;
+ bool m_bInPaint;
void adjustHighContrastMode();
};
diff --git a/chart2/source/inc/ChartTypeHelper.hxx b/chart2/source/inc/ChartTypeHelper.hxx
index efa4758c4ccd..df43e24a9482 100644
--- a/chart2/source/inc/ChartTypeHelper.hxx
+++ b/chart2/source/inc/ChartTypeHelper.hxx
@@ -86,6 +86,17 @@ public:
static sal_Int32 //one of ::com::sun::star::chart2::AxisType
getAxisType( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType
, sal_Int32 nDimensionIndex );
+
+ static rtl::OUString getRoleOfSequenceForYAxisNumberFormatDetection( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XChartType >& xChartType );
+
+ static rtl::OUString getRoleOfSequenceForDataLabelNumberFormatDetection( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XChartType >& xChartType );
+
+ static bool shouldLabelNumberFormatKeyBeDetectedFromYAxis( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XChartType >& xChartType );
+
+ static bool isSupportingOnlyDeepStackingFor3D( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
};
//.............................................................................
diff --git a/chart2/source/inc/CommonFunctors.hxx b/chart2/source/inc/CommonFunctors.hxx
index 1c4a76efd229..2ec4efa41b8c 100644
--- a/chart2/source/inc/CommonFunctors.hxx
+++ b/chart2/source/inc/CommonFunctors.hxx
@@ -100,8 +100,11 @@ struct OOO_DLLPUBLIC_CHARTTOOLS AnyToString : public ::std::unary_function< ::co
::com::sun::star::uno::TypeClass eClass( rAny.getValueType().getTypeClass() );
if( eClass == ::com::sun::star::uno::TypeClass_DOUBLE )
{
+ const double* pDouble = reinterpret_cast< const double * >( rAny.getValue() );
+ if( ::rtl::math::isNan(*pDouble) )
+ return ::rtl::OUString();
return ::rtl::math::doubleToUString(
- * reinterpret_cast< const double * >( rAny.getValue() ),
+ * pDouble,
rtl_math_StringFormat_Automatic,
-1, // use maximum decimal places available
sal_Char( '.' ), // decimal separator
diff --git a/chart2/source/inc/Strings.hrc b/chart2/source/inc/Strings.hrc
index 0af8f7e1ae04..133f5bcc255b 100644
--- a/chart2/source/inc/Strings.hrc
+++ b/chart2/source/inc/Strings.hrc
@@ -33,8 +33,8 @@
// this includes no link dependency
#include <svtools/solar.hrc>
+//next free is 285
//single free is: 134
-//next free is 282
//#define RID_APP_START 30000
////#define STR_NULL (RID_APP_START + 1)
@@ -129,6 +129,9 @@
#define STR_STOCK_3 (RID_APP_START + 145)
#define STR_STOCK_4 (RID_APP_START + 146)
+#define STR_TYPE_BUBBLE (RID_APP_START + 282)
+#define STR_BUBBLE_1 (RID_APP_START + 283)
+
//-----------------------------------------------------------------------------
//additional controls for wizard:
@@ -181,6 +184,7 @@
#define STR_DATA_ROLE_MIN (RID_APP_START + 248)
#define STR_DATA_ROLE_MAX (RID_APP_START + 249)
#define STR_DATA_ROLE_CATEGORIES (RID_APP_START + 260)
+#define STR_DATA_ROLE_SIZE (RID_APP_START + 284)
#define STR_DATA_UNNAMED_SERIES (RID_APP_START + 250)
#define STR_DATA_UNNAMED_SERIES_WITH_INDEX (RID_APP_START + 251)
diff --git a/chart2/source/inc/chartview/ChartSfxItemIds.hxx b/chart2/source/inc/chartview/ChartSfxItemIds.hxx
index d1a738d84e94..e4afc0d9efbd 100644
--- a/chart2/source/inc/chartview/ChartSfxItemIds.hxx
+++ b/chart2/source/inc/chartview/ChartSfxItemIds.hxx
@@ -51,7 +51,8 @@
#define SCHATTR_DATADESCR_SEPARATOR (SCHATTR_DATADESCR_START + 4)
#define SCHATTR_DATADESCR_PLACEMENT (SCHATTR_DATADESCR_START + 5)
#define SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS (SCHATTR_DATADESCR_START + 6)
-#define SCHATTR_DATADESCR_END SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS
+#define SCHATTR_DATADESCR_NO_PERCENTVALUE (SCHATTR_DATADESCR_START + 7) //percentage values should not be offered
+#define SCHATTR_DATADESCR_END SCHATTR_DATADESCR_NO_PERCENTVALUE
#define SCHATTR_LEGEND_START (SCHATTR_DATADESCR_END + 1)
#define SCHATTR_LEGEND_POS SCHATTR_LEGEND_START
diff --git a/chart2/source/inc/chartview/ExplicitValueProvider.hxx b/chart2/source/inc/chartview/ExplicitValueProvider.hxx
index 2f96bed91fa5..ab94e7e1c337 100644
--- a/chart2/source/inc/chartview/ExplicitValueProvider.hxx
+++ b/chart2/source/inc/chartview/ExplicitValueProvider.hxx
@@ -36,6 +36,7 @@
#include <com/sun/star/chart2/XAxis.hpp>
#include <com/sun/star/chart2/XCoordinateSystem.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/drawing/XShape.hpp>
@@ -94,13 +95,13 @@ public:
SAL_DLLPRIVATE static sal_Int32 getPercentNumberFormat( const ::com::sun::star::uno::Reference<
::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier );
- static sal_Int32 getExplicitNumberFormatKeyForLabel(
+ static sal_Int32 getExplicitNumberFormatKeyForDataLabel(
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesOrPointProp
, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries
, sal_Int32 nPointIndex /*-1 for whole series*/
- , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xAttachedAxisProps );
+ , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& xDiagram );
- static sal_Int32 getExplicitPercentageNumberFormatKeyForLabel(
+ static sal_Int32 getExplicitPercentageNumberFormatKeyForDataLabel(
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesOrPointProp
, const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier );
};
diff --git a/chart2/source/inc/servicenames_charttypes.hxx b/chart2/source/inc/servicenames_charttypes.hxx
index 461483b46e0d..1c2782de3852 100644
--- a/chart2/source/inc/servicenames_charttypes.hxx
+++ b/chart2/source/inc/servicenames_charttypes.hxx
@@ -43,6 +43,7 @@ namespace chart
#define CHART2_SERVICE_NAME_CHARTTYPE_PIE ::rtl::OUString::createFromAscii("com.sun.star.chart2.PieChartType")
#define CHART2_SERVICE_NAME_CHARTTYPE_NET ::rtl::OUString::createFromAscii("com.sun.star.chart2.NetChartType")
#define CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ::rtl::OUString::createFromAscii("com.sun.star.chart2.CandleStickChartType")
+#define CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ::rtl::OUString::createFromAscii("com.sun.star.chart2.BubbleChartType")
//.............................................................................
} //namespace chart
diff --git a/chart2/source/model/template/BubbleChartType.cxx b/chart2/source/model/template/BubbleChartType.cxx
new file mode 100644
index 000000000000..09e629462d48
--- /dev/null
+++ b/chart2/source/model/template/BubbleChartType.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_chart2.hxx"
+#include "BubbleChartType.hxx"
+#include "PropertyHelper.hxx"
+#include "macros.hxx"
+#include "servicenames_charttypes.hxx"
+#include "ContainerHelper.hxx"
+#include "CartesianCoordinateSystem.hxx"
+#include "AxisHelper.hxx"
+#include "AxisIndexDefines.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::Property;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::osl::MutexGuard;
+
+namespace
+{
+
+void lcl_AddPropertiesToVector(
+ ::std::vector< Property > & /*rOutProperties*/ )
+{
+}
+
+void lcl_AddDefaultsToMap(
+ ::chart::tPropertyValueMap & /*rOutMap*/ )
+{
+}
+
+const Sequence< Property > & lcl_GetPropertySequence()
+{
+ static Sequence< Property > aPropSeq;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aPropSeq.getLength() )
+ {
+ // get properties
+ ::std::vector< ::com::sun::star::beans::Property > aProperties;
+ lcl_AddPropertiesToVector( aProperties );
+
+ // and sort them for access via bsearch
+ ::std::sort( aProperties.begin(), aProperties.end(),
+ ::chart::PropertyNameLess() );
+
+ // transfer result to static Sequence
+ aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
+ }
+
+ return aPropSeq;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+BubbleChartType::BubbleChartType(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : ChartType( xContext )
+{
+}
+
+BubbleChartType::BubbleChartType( const BubbleChartType & rOther ) :
+ ChartType( rOther )
+{
+}
+
+BubbleChartType::~BubbleChartType()
+{}
+
+// ____ XCloneable ____
+uno::Reference< util::XCloneable > SAL_CALL BubbleChartType::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new BubbleChartType( *this ));
+}
+
+// ____ XChartType ____
+Reference< chart2::XCoordinateSystem > SAL_CALL
+ BubbleChartType::createCoordinateSystem( ::sal_Int32 DimensionCount )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ Reference< chart2::XCoordinateSystem > xResult(
+ new CartesianCoordinateSystem(
+ GetComponentContext(), DimensionCount, /* bSwapXAndYAxis */ sal_False ));
+
+ for( sal_Int32 i=0; i<DimensionCount; ++i )
+ {
+ Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) );
+ if( !xAxis.is() )
+ {
+ OSL_ENSURE(false,"a created coordinate system should have an axis for each dimension");
+ continue;
+ }
+
+ chart2::ScaleData aScaleData = xAxis->getScaleData();
+ aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
+ aScaleData.Scaling = AxisHelper::createLinearScaling();
+
+ if( i == 2 )
+ aScaleData.AxisType = chart2::AxisType::SERIES;
+ else
+ aScaleData.AxisType = chart2::AxisType::REALNUMBER;
+
+ xAxis->setScaleData( aScaleData );
+ }
+
+ return xResult;
+}
+
+::rtl::OUString SAL_CALL BubbleChartType::getChartType()
+ throw (uno::RuntimeException)
+{
+ return CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL BubbleChartType::getSupportedMandatoryRoles()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< ::rtl::OUString > aMandRolesSeq;
+
+ if( aMandRolesSeq.getLength() == 0 )
+ {
+ aMandRolesSeq.realloc( 4 );
+ aMandRolesSeq[0] = C2U( "label" );
+ aMandRolesSeq[1] = C2U( "values-x" );
+ aMandRolesSeq[2] = C2U( "values-y" );
+ aMandRolesSeq[3] = C2U( "values-size" );
+ }
+
+ return aMandRolesSeq;
+}
+
+OUString SAL_CALL BubbleChartType::getRoleOfSequenceForSeriesLabel()
+ throw (uno::RuntimeException)
+{
+ return C2U( "values-size" );
+}
+
+// ____ OPropertySet ____
+uno::Any BubbleChartType::GetDefaultValue( sal_Int32 nHandle ) const
+ throw(beans::UnknownPropertyException)
+{
+ static tPropertyValueMap aStaticDefaults;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aStaticDefaults.size() )
+ {
+ // initialize defaults
+ lcl_AddDefaultsToMap( aStaticDefaults );
+ }
+
+ tPropertyValueMap::const_iterator aFound(
+ aStaticDefaults.find( nHandle ));
+
+ if( aFound == aStaticDefaults.end())
+ return uno::Any();
+
+ return (*aFound).second;
+ // \--
+}
+
+// ____ OPropertySet ____
+::cppu::IPropertyArrayHelper & SAL_CALL BubbleChartType::getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper aArrayHelper( lcl_GetPropertySequence(),
+ /* bSorted = */ sal_True );
+
+ return aArrayHelper;
+}
+
+
+// ____ XPropertySet ____
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ BubbleChartType::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is())
+ {
+ xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
+ getInfoHelper());
+ }
+
+ return xInfo;
+ // \--
+}
+
+uno::Sequence< ::rtl::OUString > BubbleChartType::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 3 );
+ aServices[ 0 ] = CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartType" );
+ aServices[ 2 ] = C2U( "com.sun.star.beans.PropertySet" );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( BubbleChartType,
+ C2U( "com.sun.star.comp.chart.BubbleChartType" ));
+
+} // namespace chart
diff --git a/chart2/source/model/template/BubbleChartType.hxx b/chart2/source/model/template/BubbleChartType.hxx
new file mode 100644
index 000000000000..3694ac1c955c
--- /dev/null
+++ b/chart2/source/model/template/BubbleChartType.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART_BUBBLECHARTTYPE_HXX
+#define CHART_BUBBLECHARTTYPE_HXX
+
+#include "ChartType.hxx"
+#include "ServiceMacros.hxx"
+#include <com/sun/star/chart2/CurveStyle.hpp>
+
+namespace chart
+{
+
+class BubbleChartType : public ChartType
+{
+public:
+ BubbleChartType(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & xContext );
+ virtual ~BubbleChartType();
+
+ APPHELPER_XSERVICEINFO_DECL()
+
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( BubbleChartType )
+
+protected:
+ explicit BubbleChartType( const BubbleChartType & rOther );
+
+ // ____ XChartType ____
+ virtual ::rtl::OUString SAL_CALL getChartType()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedMandatoryRoles()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > SAL_CALL
+ createCoordinateSystem( ::sal_Int32 DimensionCount )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRoleOfSequenceForSeriesLabel()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ OPropertySet ____
+ virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
+ throw(::com::sun::star::beans::UnknownPropertyException);
+
+ // ____ OPropertySet ____
+ virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // ____ XPropertySet ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+} // namespace chart
+
+// CHART_BUBBLECHARTTYPE_HXX
+#endif
diff --git a/chart2/source/model/template/BubbleChartTypeTemplate.cxx b/chart2/source/model/template/BubbleChartTypeTemplate.cxx
new file mode 100644
index 000000000000..0853cea6a5cb
--- /dev/null
+++ b/chart2/source/model/template/BubbleChartTypeTemplate.cxx
@@ -0,0 +1,322 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_chart2.hxx"
+#include "BubbleChartTypeTemplate.hxx"
+#include "macros.hxx"
+#include "BubbleDataInterpreter.hxx"
+#include "CartesianCoordinateSystem.hxx"
+#include "Scaling.hxx"
+#include "DiagramHelper.hxx"
+#include "servicenames_charttypes.hxx"
+#include "ContainerHelper.hxx"
+#include "DataSeriesHelper.hxx"
+#include <com/sun/star/chart2/SymbolStyle.hpp>
+#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include "PropertyHelper.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+using ::com::sun::star::beans::Property;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::osl::MutexGuard;
+
+namespace
+{
+
+static const OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.BubbleChartTypeTemplate" ));
+
+void lcl_AddPropertiesToVector(
+ ::std::vector< Property > & /*rOutProperties*/ )
+{
+}
+
+void lcl_AddDefaultsToMap(
+ ::chart::tPropertyValueMap & /*rOutMap*/ )
+{
+}
+
+const Sequence< Property > & lcl_GetPropertySequence()
+{
+ static Sequence< Property > aPropSeq;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aPropSeq.getLength() )
+ {
+ // get properties
+ ::std::vector< ::com::sun::star::beans::Property > aProperties;
+ lcl_AddPropertiesToVector( aProperties );
+
+ // and sort them for access via bsearch
+ ::std::sort( aProperties.begin(), aProperties.end(),
+ ::chart::PropertyNameLess() );
+
+ // transfer result to static Sequence
+ aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
+ }
+
+ return aPropSeq;
+}
+
+::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper aArrayHelper(
+ lcl_GetPropertySequence(),
+ /* bSorted = */ sal_True );
+
+ return aArrayHelper;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+BubbleChartTypeTemplate::BubbleChartTypeTemplate(
+ Reference<
+ uno::XComponentContext > const & xContext,
+ const OUString & rServiceName ) :
+ ChartTypeTemplate( xContext, rServiceName ),
+ ::property::OPropertySet( m_aMutex )
+{
+}
+
+BubbleChartTypeTemplate::~BubbleChartTypeTemplate()
+{}
+
+// ____ OPropertySet ____
+uno::Any BubbleChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const
+ throw(beans::UnknownPropertyException)
+{
+ static tPropertyValueMap aStaticDefaults;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aStaticDefaults.size() )
+ {
+ // initialize defaults
+ lcl_AddDefaultsToMap( aStaticDefaults );
+ }
+
+ tPropertyValueMap::const_iterator aFound(
+ aStaticDefaults.find( nHandle ));
+
+ if( aFound == aStaticDefaults.end())
+ return uno::Any();
+
+ return (*aFound).second;
+ // \--
+}
+
+::cppu::IPropertyArrayHelper & SAL_CALL BubbleChartTypeTemplate::getInfoHelper()
+{
+ return lcl_getInfoHelper();
+}
+
+
+// ____ XPropertySet ____
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ BubbleChartTypeTemplate::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is())
+ {
+ xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
+ getInfoHelper());
+ }
+
+ return xInfo;
+ // \--
+}
+
+sal_Int32 BubbleChartTypeTemplate::getDimension() const
+{
+ return 2;
+}
+
+StackMode BubbleChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const
+{
+ return StackMode_NONE;
+}
+
+bool BubbleChartTypeTemplate::supportsCategories() const
+{
+ return false;
+}
+
+
+void SAL_CALL BubbleChartTypeTemplate::applyStyle(
+ const Reference< chart2::XDataSeries >& xSeries,
+ ::sal_Int32 nChartTypeIndex,
+ ::sal_Int32 nSeriesIndex,
+ ::sal_Int32 nSeriesCount )
+ throw (uno::RuntimeException)
+{
+ ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount );
+
+ try
+ {
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// ____ XChartTypeTemplate ____
+Sequence< OUString > SAL_CALL BubbleChartTypeTemplate::getAvailableCreationParameterNames()
+ throw (uno::RuntimeException)
+{
+ return Sequence< OUString >();
+}
+
+sal_Bool SAL_CALL BubbleChartTypeTemplate::matchesTemplate(
+ const Reference< chart2::XDiagram >& xDiagram,
+ sal_Bool bAdaptProperties )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties );
+
+ if( bResult )
+ {
+ ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+
+ for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
+ aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
+ {
+ try
+ {
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+
+ // adapt curve style, spline order and resolution
+ if( bResult && bAdaptProperties )
+ {
+ try
+ {
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return bResult;
+}
+
+Reference< chart2::XChartType > BubbleChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ )
+{
+ Reference< chart2::XChartType > xResult;
+
+ try
+ {
+ Reference< lang::XMultiServiceFactory > xFact(
+ GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
+ xResult.set( xFact->createInstance(
+ CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ), uno::UNO_QUERY_THROW );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return xResult;
+}
+
+Reference< chart2::XChartType > SAL_CALL BubbleChartTypeTemplate::getChartTypeForNewSeries(
+ const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes )
+ throw (uno::RuntimeException)
+{
+ Reference< chart2::XChartType > xResult;
+
+ try
+ {
+ Reference< lang::XMultiServiceFactory > xFact(
+ GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
+ xResult.set( xFact->createInstance(
+ CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ), uno::UNO_QUERY_THROW );
+
+ ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem( aFormerlyUsedChartTypes, xResult );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return xResult;
+}
+
+Reference< chart2::XDataInterpreter > SAL_CALL BubbleChartTypeTemplate::getDataInterpreter()
+ throw (uno::RuntimeException)
+{
+ if( ! m_xDataInterpreter.is())
+ m_xDataInterpreter.set( new BubbleDataInterpreter( GetComponentContext()) );
+
+ return m_xDataInterpreter;
+}
+
+// ----------------------------------------
+
+Sequence< OUString > BubbleChartTypeTemplate::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( BubbleChartTypeTemplate, lcl_aServiceName );
+
+IMPLEMENT_FORWARD_XINTERFACE2( BubbleChartTypeTemplate, ChartTypeTemplate, OPropertySet )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( BubbleChartTypeTemplate, ChartTypeTemplate, OPropertySet )
+
+} // namespace chart
diff --git a/chart2/source/model/template/BubbleChartTypeTemplate.hxx b/chart2/source/model/template/BubbleChartTypeTemplate.hxx
new file mode 100644
index 000000000000..c094e38e28ac
--- /dev/null
+++ b/chart2/source/model/template/BubbleChartTypeTemplate.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART_BUBBLECHARTTYPETEMPLATE_HXX
+#define CHART_BUBBLECHARTTYPETEMPLATE_HXX
+
+#include "ChartTypeTemplate.hxx"
+#include "OPropertySet.hxx"
+#include "MutexContainer.hxx"
+#include <comphelper/uno3.hxx>
+
+namespace chart
+{
+
+class BubbleChartTypeTemplate :
+ public MutexContainer,
+ public ChartTypeTemplate,
+ public ::property::OPropertySet
+{
+public:
+ explicit BubbleChartTypeTemplate(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & xContext,
+ const ::rtl::OUString & rServiceName );
+ virtual ~BubbleChartTypeTemplate();
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+
+ /// merge XInterface implementations
+ DECLARE_XINTERFACE()
+ /// merge XTypeProvider implementations
+ DECLARE_XTYPEPROVIDER()
+
+protected:
+ // ____ OPropertySet ____
+ virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
+ throw(::com::sun::star::beans::UnknownPropertyException);
+ virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // ____ XPropertySet ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XChartTypeTemplate ____
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableCreationParameterNames()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL matchesTemplate(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XDiagram >& xDiagram,
+ sal_Bool bAdaptProperties )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > SAL_CALL
+ getChartTypeForNewSeries( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XChartType > >& aFormerlyUsedChartTypes )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataInterpreter > SAL_CALL getDataInterpreter()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL applyStyle(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries,
+ ::sal_Int32 nChartTypeGroupIndex,
+ ::sal_Int32 nSeriesIndex,
+ ::sal_Int32 nSeriesCount )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ ChartTypeTemplate ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >
+ getChartTypeForIndex( sal_Int32 nChartTypeIndex );
+ virtual sal_Int32 getDimension() const;
+ virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const;
+
+ virtual bool supportsCategories() const;
+};
+
+} // namespace chart
+
+// CHART_BUBBLECHARTTYPETEMPLATE_HXX
+#endif
diff --git a/chart2/source/model/template/BubbleDataInterpreter.cxx b/chart2/source/model/template/BubbleDataInterpreter.cxx
new file mode 100644
index 000000000000..a5ebb6b1ec2f
--- /dev/null
+++ b/chart2/source/model/template/BubbleDataInterpreter.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_chart2.hxx"
+
+#include "BubbleDataInterpreter.hxx"
+#include "DataSeries.hxx"
+#include "macros.hxx"
+#include "DataSeriesHelper.hxx"
+#include "CommonConverters.hxx"
+#include "ContainerHelper.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using namespace ::std;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+BubbleDataInterpreter::BubbleDataInterpreter(
+ const uno::Reference< uno::XComponentContext > & xContext ) :
+ DataInterpreter( xContext )
+{
+}
+
+BubbleDataInterpreter::~BubbleDataInterpreter()
+{
+}
+
+// ____ XDataInterpreter ____
+chart2::InterpretedData SAL_CALL BubbleDataInterpreter::interpretDataSource(
+ const Reference< chart2::data::XDataSource >& xSource,
+ const Sequence< beans::PropertyValue >& aArguments,
+ const Sequence< Reference< XDataSeries > >& aSeriesToReUse )
+ throw (uno::RuntimeException)
+{
+ if( ! xSource.is())
+ return InterpretedData();
+
+ Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() );
+
+ Reference< data::XLabeledDataSequence > xValuesX;
+ vector< Reference< data::XLabeledDataSequence > > aYValuesVector;
+ vector< Reference< data::XLabeledDataSequence > > aSizeValuesVector;
+
+ Reference< data::XLabeledDataSequence > xCategories;
+ bool bHasCategories = HasCategories( aArguments, aData );
+
+ Sequence< Reference< data::XLabeledDataSequence > > aUnusedData;
+
+ bool bHasXValues = false;
+ sal_Int32 nDataSeqCount = aData.getLength();
+
+ bHasXValues = bHasCategories ? ( (nDataSeqCount-1) > 2 && (nDataSeqCount-1) % 2 != 0 )
+ :( nDataSeqCount > 2 && nDataSeqCount % 2 != 0 );
+
+ bool bCategoriesUsed = false;
+ bool bNextIsYValues = bHasCategories ? nDataSeqCount>2 : nDataSeqCount>1;
+ for( sal_Int32 nDataIdx = 0; nDataIdx < aData.getLength(); ++nDataIdx )
+ {
+ try
+ {
+ if( bHasCategories && !bCategoriesUsed )
+ {
+ xCategories.set( aData[nDataIdx] );
+ if( xCategories.is())
+ SetRole( xCategories->getValues(), C2U("categories"));
+ bCategoriesUsed = true;
+ }
+ else if( !xValuesX.is() && bHasXValues )
+ {
+ xValuesX.set( aData[nDataIdx] );
+ if( xValuesX.is())
+ SetRole( xValuesX->getValues(), C2U("values-x"));
+ }
+ else if( bNextIsYValues )
+ {
+ aYValuesVector.push_back( aData[nDataIdx] );
+ if( aData[nDataIdx].is())
+ SetRole( aData[nDataIdx]->getValues(), C2U("values-y"));
+ bNextIsYValues = false;
+ }
+ else if( !bNextIsYValues )
+ {
+ aSizeValuesVector.push_back( aData[nDataIdx] );
+ if( aData[nDataIdx].is())
+ SetRole( aData[nDataIdx]->getValues(), C2U("values-size"));
+ bNextIsYValues = true;
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ // create DataSeries
+ sal_Int32 nSeriesIndex = 0;
+ vector< Reference< XDataSeries > > aSeriesVec;
+ aSeriesVec.reserve( aSizeValuesVector.size());
+
+ Reference< data::XLabeledDataSequence > xClonedXValues = xValuesX;
+ Reference< util::XCloneable > xCloneableX( xValuesX, uno::UNO_QUERY );
+
+ for( size_t nCount = 0; nCount < aSizeValuesVector.size(); ++nCount, ++nSeriesIndex )
+ {
+ sal_Int32 nDataSequenceCount = 2;
+ if( xValuesX.is() )
+ nDataSequenceCount = 3;
+ else if( aYValuesVector.empty() )
+ nDataSequenceCount = 1;
+
+ Sequence< Reference< data::XLabeledDataSequence > > aNewData( nDataSequenceCount );
+ sal_Int32 nDataIndex = 0;
+ if( xValuesX.is() )
+ {
+ if( nCount > 0 && xCloneableX.is() )
+ xClonedXValues.set( xCloneableX->createClone(), uno::UNO_QUERY );
+ aNewData[nDataIndex++] = xClonedXValues;
+ }
+ if( aYValuesVector.size() > nCount )
+ aNewData[nDataIndex++] = aYValuesVector[nCount];
+ if( aSizeValuesVector.size() > nCount )
+ aNewData[nDataIndex++] = aSizeValuesVector[nCount];
+
+ Reference< XDataSeries > xSeries;
+ if( nSeriesIndex < aSeriesToReUse.getLength())
+ xSeries.set( aSeriesToReUse[nSeriesIndex] );
+ else
+ xSeries.set( new DataSeries( GetComponentContext() ) );
+ OSL_ASSERT( xSeries.is() );
+ Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY );
+ OSL_ASSERT( xSink.is() );
+ xSink->setData( aNewData );
+
+ aSeriesVec.push_back( xSeries );
+ }
+
+ Sequence< Sequence< Reference< XDataSeries > > > aSeries(1);
+ aSeries[0] = ContainerHelper::ContainerToSequence( aSeriesVec );
+ return InterpretedData( aSeries, xCategories, aUnusedData );
+}
+
+chart2::InterpretedData SAL_CALL BubbleDataInterpreter::reinterpretDataSeries(
+ const chart2::InterpretedData& aInterpretedData )
+ throw (uno::RuntimeException)
+{
+ InterpretedData aResult( aInterpretedData );
+ vector< Reference< data::XLabeledDataSequence > > aUnused(
+ ContainerHelper::SequenceToVector( aInterpretedData.UnusedData ));
+
+ sal_Int32 i=0;
+ Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series ));
+ const sal_Int32 nCount = aSeries.getLength();
+ for( ; i<nCount; ++i )
+ {
+ try
+ {
+ Reference< data::XDataSource > xSeriesSource( aSeries[i], uno::UNO_QUERY_THROW );
+ Sequence< Reference< data::XLabeledDataSequence > > aNewSequences;
+
+ Reference< data::XLabeledDataSequence > xValuesSize(
+ DataSeriesHelper::getDataSequenceByRole( xSeriesSource, C2U("values-size"), false ));
+ Reference< data::XLabeledDataSequence > xValuesY(
+ DataSeriesHelper::getDataSequenceByRole( xSeriesSource, C2U("values-y"), false ));
+ Reference< data::XLabeledDataSequence > xValuesX(
+ DataSeriesHelper::getDataSequenceByRole( xSeriesSource, C2U("values-x"), false ));
+
+ if( ! xValuesX.is() ||
+ ! xValuesY.is() ||
+ ! xValuesSize.is() )
+ {
+ vector< Reference< data::XLabeledDataSequence > > aValueSeqVec(
+ DataSeriesHelper::getAllDataSequencesByRole(
+ xSeriesSource->getDataSequences(), C2U("values"), true ));
+ if( xValuesX.is())
+ aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesX ));
+ if( xValuesY.is())
+ aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesY ));
+ if( xValuesSize.is())
+ aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesSize ));
+
+ size_t nIndex = 0;
+
+ if( ! xValuesSize.is() &&
+ aValueSeqVec.size() > nIndex )
+ {
+ xValuesSize.set( aValueSeqVec[nIndex++] );
+ if( xValuesSize.is())
+ SetRole( xValuesSize->getValues(), C2U("values-size"));
+ }
+
+ if( ! xValuesY.is() &&
+ aValueSeqVec.size() > nIndex )
+ {
+ xValuesY.set( aValueSeqVec[nIndex++] );
+ if( xValuesY.is())
+ SetRole( xValuesY->getValues(), C2U("values-y"));
+ }
+
+ if( ! xValuesX.is() &&
+ aValueSeqVec.size() > nIndex )
+ {
+ xValuesX.set( aValueSeqVec[nIndex++] );
+ if( xValuesX.is())
+ SetRole( xValuesY->getValues(), C2U("values-x"));
+ }
+ }
+ if( xValuesSize.is())
+ {
+ if( xValuesY.is() )
+ {
+ if( xValuesX.is() )
+ {
+ aNewSequences.realloc(3);
+ aNewSequences[0] = xValuesX;
+ aNewSequences[1] = xValuesY;
+ aNewSequences[2] = xValuesSize;
+ }
+ else
+ {
+ aNewSequences.realloc(2);
+ aNewSequences[0] = xValuesY;
+ aNewSequences[1] = xValuesSize;
+ }
+ }
+ else
+ {
+ aNewSequences.realloc(1);
+ aNewSequences[0] = xValuesSize;
+ }
+ }
+
+ Sequence< Reference< data::XLabeledDataSequence > > aSeqs( xSeriesSource->getDataSequences());
+ if( aSeqs.getLength() != aNewSequences.getLength() )
+ {
+ sal_Int32 j=0;
+ for( ; j<aSeqs.getLength(); ++j )
+ {
+ if( aSeqs[j] != xValuesY &&
+ aSeqs[j] != xValuesX &&
+ aSeqs[j] != xValuesSize )
+ aUnused.push_back( aSeqs[j] );
+ }
+ Reference< data::XDataSink > xSink( xSeriesSource, uno::UNO_QUERY_THROW );
+ xSink->setData( aNewSequences );
+ aResult.UnusedData = ContainerHelper::ContainerToSequence( aUnused );
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return aResult;
+}
+
+sal_Bool SAL_CALL BubbleDataInterpreter::isDataCompatible(
+ const chart2::InterpretedData& aInterpretedData )
+ throw (uno::RuntimeException)
+{
+ Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series ));
+ for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
+ {
+ try
+ {
+ Reference< data::XDataSource > xSrc( aSeries[i], uno::UNO_QUERY_THROW );
+ Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences());
+ if( aSeq.getLength() != 3 )
+ return sal_False;
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return sal_True;
+}
+
+} // namespace chart
diff --git a/chart2/source/model/template/BubbleDataInterpreter.hxx b/chart2/source/model/template/BubbleDataInterpreter.hxx
new file mode 100644
index 000000000000..a173f801812c
--- /dev/null
+++ b/chart2/source/model/template/BubbleDataInterpreter.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART_BUBBLEDATAINTERPRETER_HXX
+#define CHART_BUBBLEDATAINTERPRETER_HXX
+
+#include "DataInterpreter.hxx"
+
+namespace chart
+{
+
+class BubbleDataInterpreter : public DataInterpreter
+{
+public:
+ explicit BubbleDataInterpreter(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ virtual ~BubbleDataInterpreter();
+
+protected:
+ // ____ XDataInterpreter ____
+ virtual ::com::sun::star::chart2::InterpretedData SAL_CALL interpretDataSource(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSource >& xSource,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArguments,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > >& aSeriesToReUse )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::chart2::InterpretedData SAL_CALL reinterpretDataSeries(
+ const ::com::sun::star::chart2::InterpretedData& aInterpretedData )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isDataCompatible(
+ const ::com::sun::star::chart2::InterpretedData& aInterpretedData )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+} // namespace chart
+
+// CHART_BUBBLEDATAINTERPRETER_HXX
+#endif
diff --git a/chart2/source/model/template/ChartTypeManager.cxx b/chart2/source/model/template/ChartTypeManager.cxx
index 6365c08f4403..0e4a3a119a02 100644
--- a/chart2/source/model/template/ChartTypeManager.cxx
+++ b/chart2/source/model/template/ChartTypeManager.cxx
@@ -45,6 +45,7 @@
#include "ScatterChartTypeTemplate.hxx"
#include "StockChartTypeTemplate.hxx"
#include "NetChartTypeTemplate.hxx"
+#include "BubbleChartTypeTemplate.hxx"
#include <cppuhelper/component_context.hxx>
#include <comphelper/InlineContainer.hxx>
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
@@ -131,6 +132,7 @@ enum TemplateId
TEMPLATE_STOCKOPENLOWHIGHCLOSE,
TEMPLATE_STOCKVOLUMELOWHIGHCLOSE,
TEMPLATE_STOCKVOLUMEOPENLOWHIGHCLOSE,
+ TEMPLATE_BUBBLE,
// TEMPLATE_SURFACE,
// TEMPLATE_ADDIN,
TEMPLATE_NOT_FOUND = 0xffff
@@ -202,6 +204,7 @@ const tTemplateMapType & lcl_DefaultChartTypeMap()
( C2U( "com.sun.star.chart2.template.StockOpenLowHighClose" ), TEMPLATE_STOCKOPENLOWHIGHCLOSE )
( C2U( "com.sun.star.chart2.template.StockVolumeLowHighClose" ), TEMPLATE_STOCKVOLUMELOWHIGHCLOSE )
( C2U( "com.sun.star.chart2.template.StockVolumeOpenLowHighClose" ), TEMPLATE_STOCKVOLUMEOPENLOWHIGHCLOSE )
+ ( C2U( "com.sun.star.chart2.template.Bubble" ), TEMPLATE_BUBBLE )
// ( C2U( "com.sun.star.chart2.template.Surface" ), TEMPLATE_SURFACE )
// ( C2U( "com.sun.star.chart2.template.Addin" ), TEMPLATE_ADDIN )
);
@@ -518,6 +521,11 @@ uno::Reference< uno::XInterface > SAL_CALL ChartTypeManager::createInstance(
StockChartTypeTemplate::VOL_OPEN_LOW_HI_CLOSE, true ));
break;
+ //BubbleChart
+ case TEMPLATE_BUBBLE:
+ xTemplate.set( new BubbleChartTypeTemplate( m_xContext, aServiceSpecifier ));
+ break;
+
// case TEMPLATE_SURFACE:
// case TEMPLATE_ADDIN:
// break;
diff --git a/chart2/source/model/template/ChartTypeTemplate.cxx b/chart2/source/model/template/ChartTypeTemplate.cxx
index b5791baf6c0f..1996cc12830e 100644
--- a/chart2/source/model/template/ChartTypeTemplate.cxx
+++ b/chart2/source/model/template/ChartTypeTemplate.cxx
@@ -68,27 +68,6 @@ using ::com::sun::star::uno::Any;
namespace
{
-sal_Int32 lcl_getSeriesLength( const Reference< XDataSeries > & xSeries )
-{
- sal_Int32 nResult = 0;
- try
- {
- Reference< data::XDataSource > xDataSource( xSeries, uno::UNO_QUERY_THROW );
- Sequence< Reference< data::XLabeledDataSequence > > aLabSeq( xDataSource->getDataSequences());
- if( aLabSeq.getLength())
- {
- Reference< data::XDataSequence > xSeq( aLabSeq[0]->getValues());
- if( xSeq.is())
- nResult = xSeq->getData().getLength();
- }
- }
- catch( const uno::Exception & ex )
- {
- ASSERT_EXCEPTION( ex );
- }
- return nResult;
-}
-
void lcl_applyDefaultStyle(
const Reference< XDataSeries > & xSeries,
sal_Int32 nIndex,
@@ -347,12 +326,9 @@ void SAL_CALL ChartTypeTemplate::changeDiagramData(
Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq( aData.Series );
sal_Int32 i, j, nIndex = 0;
- sal_Int32 nFirstSeriesLength = 0;
for( i=0; i<aSeriesSeq.getLength(); ++i )
for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex )
{
- if( i==0 && j==0 )
- nFirstSeriesLength = lcl_getSeriesLength( aSeriesSeq[0][0] );
if( nIndex >= nFormerSeriesCount )
{
lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram );
diff --git a/chart2/source/model/template/_serviceregistration_charttypes.cxx b/chart2/source/model/template/_serviceregistration_charttypes.cxx
index b059eb24957a..6e5960410445 100644
--- a/chart2/source/model/template/_serviceregistration_charttypes.cxx
+++ b/chart2/source/model/template/_serviceregistration_charttypes.cxx
@@ -41,6 +41,7 @@
#include "NetChartType.hxx"
#include "PieChartType.hxx"
#include "ScatterChartType.hxx"
+#include "BubbleChartType.hxx"
namespace
{
@@ -110,6 +111,14 @@ static struct ::cppu::ImplementationEntry g_entries_chart2_charttypes[] =
, 0
, 0
}
+ ,{
+ ::chart::BubbleChartType::create
+ , ::chart::BubbleChartType::getImplementationName_Static
+ , ::chart::BubbleChartType::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
,{ 0, 0, 0, 0, 0, 0 }
};
diff --git a/chart2/source/model/template/makefile.mk b/chart2/source/model/template/makefile.mk
index 0913c42a89e2..ad8fcd552c8d 100644
--- a/chart2/source/model/template/makefile.mk
+++ b/chart2/source/model/template/makefile.mk
@@ -71,6 +71,9 @@ SLOFILES= \
$(SLO)$/PieChartTypeTemplate.obj \
$(SLO)$/ScatterChartType.obj \
$(SLO)$/ScatterChartTypeTemplate.obj \
+ $(SLO)$/BubbleChartType.obj \
+ $(SLO)$/BubbleChartTypeTemplate.obj \
+ $(SLO)$/BubbleDataInterpreter.obj \
$(SLO)$/StockChartTypeTemplate.obj \
$(SLO)$/StockDataInterpreter.obj \
$(SLO)$/XYDataInterpreter.obj \
diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx
index d7bb3a15bdf6..357cf5c43d92 100644
--- a/chart2/source/tools/ChartTypeHelper.cxx
+++ b/chart2/source/tools/ChartTypeHelper.cxx
@@ -108,6 +108,8 @@ sal_Bool ChartTypeHelper::isSupportingStatisticProperties( const uno::Reference<
return sal_False;
if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) ) //todo: BubbleChart support error bars and trend lines
+ return sal_False;
}
return sal_True;
}
@@ -281,6 +283,7 @@ uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedLabelPlacements( const
}
else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
|| aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE)
)
{
aRet.realloc(5);
@@ -509,7 +512,8 @@ sal_Int32 ChartTypeHelper::getAxisType( const uno::Reference<
return AxisType::REALNUMBER;
if(0==nDimensionIndex)//x-axis
{
- if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
return AxisType::REALNUMBER;
return AxisType::CATEGORY;
}
@@ -558,7 +562,8 @@ uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedMissingValueTreatments(
rtl::OUString aChartTypeName = xChartType->getChartType();
if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) ||
- aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
{
aRet.realloc( 2 );
sal_Int32* pSeq = aRet.getArray();
@@ -604,6 +609,54 @@ uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedMissingValueTreatments(
return aRet;
}
+rtl::OUString ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
+{
+ rtl::OUString aRet( C2U( "values-y" ) );
+ if( !xChartType.is() )
+ return aRet;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ aRet = xChartType->getRoleOfSequenceForSeriesLabel();
+ return aRet;
+}
+
+rtl::OUString ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
+{
+ rtl::OUString aRet( C2U( "values-y" ) );
+ if( !xChartType.is() )
+ return aRet;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ aRet = xChartType->getRoleOfSequenceForSeriesLabel();
+ return aRet;
+}
+
+bool ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( const uno::Reference< XChartType >& xChartType )
+{
+ bool bRet = true;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ bRet = false;
+ return bRet;
+}
+
+bool ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( const uno::Reference< XChartType >& xChartType )
+{
+ bool bRet = false;
+ if( !xChartType.is() )
+ return bRet;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
//.............................................................................
} //namespace chart
//.............................................................................
diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx
index 8af5b412c5c1..ac2a32f93298 100644
--- a/chart2/source/tools/DiagramHelper.cxx
+++ b/chart2/source/tools/DiagramHelper.cxx
@@ -503,8 +503,12 @@ void DiagramHelper::setDimension(
try
{
- //change all coordinate systems:
+ bool rbFound = false;
+ bool rbAmbiguous = true;
+ StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous );
+ bool bIsSupportingOnlyDeepStackingFor3D=false;
+ //change all coordinate systems:
Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
@@ -520,6 +524,7 @@ void DiagramHelper::setDimension(
for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
{
Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY );
+ bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType );
if(!xNewCooSys.is())
{
xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount );
@@ -533,6 +538,12 @@ void DiagramHelper::setDimension(
// replace the old coordinate system at all places where it was used
DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys );
}
+
+ //correct stack mode if necessary
+ if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D )
+ DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED );
+ else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED )
+ DiagramHelper::setStackMode( xDiagram, StackMode_NONE );
}
catch( uno::Exception & ex )
{
@@ -556,6 +567,8 @@ void DiagramHelper::replaceCoordinateSystem(
{
try
{
+ Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
+
// move chart types of xCooSysToReplace to xReplacement
Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW );
Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW );
@@ -563,6 +576,9 @@ void DiagramHelper::replaceCoordinateSystem(
xCont->removeCoordinateSystem( xCooSysToReplace );
xCont->addCoordinateSystem( xReplacement );
+
+ if( xCategories.is() )
+ DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram );
}
catch( uno::Exception & ex )
{
diff --git a/chart2/source/tools/TitleHelper.cxx b/chart2/source/tools/TitleHelper.cxx
index 43006920951a..fe10c92e78cc 100644
--- a/chart2/source/tools/TitleHelper.cxx
+++ b/chart2/source/tools/TitleHelper.cxx
@@ -36,6 +36,7 @@
#include "AxisHelper.hxx"
#include "DiagramHelper.hxx"
#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <rtl/ustrbuf.hxx>
//.............................................................................
namespace chart
@@ -269,13 +270,44 @@ void TitleHelper::setCompleteString( const rtl::OUString& rNewText
if(!xTitle.is())
return;
+ rtl::OUString aNewText = rNewText;
+
+ bool bStacked = false;
+ uno::Reference< beans::XPropertySet > xTitleProperties( xTitle, uno::UNO_QUERY );
+ if( xTitleProperties.is() )
+ xTitleProperties->getPropertyValue( C2U( "StackCharacters" ) ) >>= bStacked;
+
+ if( bStacked )
+ {
+ //#i99841# remove linebreaks that were added for vertical stacking
+ rtl::OUStringBuffer aUnstackedStr;
+ rtl::OUStringBuffer aSource(rNewText);
+
+ bool bBreakIgnored = false;
+ sal_Int32 nLen = rNewText.getLength();
+ for( sal_Int32 nPos = 0; nPos < nLen; ++nPos )
+ {
+ sal_Unicode aChar = aSource.charAt( nPos );
+ if( aChar != '\n' )
+ {
+ aUnstackedStr.append( aChar );
+ bBreakIgnored = false;
+ }
+ else if( aChar == '\n' && bBreakIgnored )
+ aUnstackedStr.append( aChar );
+ else
+ bBreakIgnored = true;
+ }
+ aNewText = aUnstackedStr.makeStringAndClear();
+ }
+
uno::Sequence< uno::Reference< XFormattedString > > aNewStringList(1);
uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText();
if( aOldStringList.getLength() )
{
aNewStringList[0].set( aOldStringList[0] );
- aNewStringList[0]->setString( rNewText );
+ aNewStringList[0]->setString( aNewText );
}
else
{
@@ -286,7 +318,7 @@ void TitleHelper::setCompleteString( const rtl::OUString& rNewText
if(xFormattedString.is())
{
- xFormattedString->setString( rNewText );
+ xFormattedString->setString( aNewText );
aNewStringList[0].set( xFormattedString );
if( pDefaultCharHeight != 0 )
{
diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx
index 1401ab43a159..0b1a17ca7701 100644
--- a/chart2/source/view/charttypes/AreaChart.cxx
+++ b/chart2/source/view/charttypes/AreaChart.cxx
@@ -89,7 +89,6 @@ AreaChart::AreaChart( const uno::Reference<XChartType>& xChartTypeModel
, m_bExpandIfValuesCloseToBorder( bExpandIfValuesCloseToBorder )
, m_nKeepAspectRatio(nKeepAspectRatio)
, m_aGivenAspectRatio(rAspectRatio)
- , m_eNanHandling( bCategoryXAxis ? NAN_AS_GAP : NAN_AS_INTERPOLATED )
, m_eCurveStyle(CurveStyle_LINES)
, m_nCurveResolution(20)
, m_nSplineOrder(3)
@@ -103,9 +102,6 @@ AreaChart::AreaChart( const uno::Reference<XChartType>& xChartTypeModel
PlotterBase::m_pPosHelper = m_pMainPosHelper;
VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper;
- if( m_bArea )
- m_eNanHandling = NAN_AS_ZERO;
-
try
{
if( m_xChartTypeModelProps.is() )
@@ -234,6 +230,12 @@ bool AreaChart::keepAspectRatio() const
void AreaChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot )
{
+ if( m_bArea && pSeries )
+ {
+ sal_Int32 nMissingValueTreatment = pSeries->getMissingValueTreatment();
+ if( nMissingValueTreatment == ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP )
+ pSeries->setMissingValueTreatment( ::com::sun::star::chart::MissingValueTreatment::USE_ZERO );
+ }
if( m_nDimension == 3 && !m_bCategoryXAxis )
{
//3D xy always deep
@@ -351,9 +353,10 @@ bool AreaChart::impl_createLine( VDataSeries* pSeries
if( m_bConnectLastToFirstPoint && !ShapeFactory::isPolygonEmptyOrSinglePoint(*pSeriesPoly) )
{
// do NOT connect last and first point, if one is NAN, and NAN handling is NAN_AS_GAP
- double fFirstY = pSeries->getY( 0 );
- double fLastY = pSeries->getY( VSeriesPlotter::getPointCount() - 1 );
- if( (m_eNanHandling != NAN_AS_GAP) || (::rtl::math::isFinite( fFirstY ) && ::rtl::math::isFinite( fLastY )) )
+ double fFirstY = pSeries->getYValue( 0 );
+ double fLastY = pSeries->getYValue( VSeriesPlotter::getPointCount() - 1 );
+ if( (pSeries->getMissingValueTreatment() != ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP)
+ || (::rtl::math::isFinite( fFirstY ) && ::rtl::math::isFinite( fLastY )) )
{
// connect last point in last polygon with first point in first polygon
::basegfx::B2DRectangle aScaledLogicClipDoubleRect( pPosHelper->getScaledLogicClipDoubleRect() );
@@ -573,13 +576,6 @@ void lcl_reorderSeries( ::std::vector< ::std::vector< VDataSeriesGroup > >& rZS
}//anonymous namespace
-void AreaChart::impl_maybeReplaceNanWithZero( double& rfValue )
-{
- if( m_eNanHandling == NAN_AS_ZERO &&
- ( ::rtl::math::isNan(rfValue) || ::rtl::math::isInf(rfValue) ) )
- rfValue = 0.0;
-}
-
//better performance for big data
struct FormerPoint
{
@@ -676,8 +672,7 @@ void AreaChart::createShapes()
pPosHelper = m_pMainPosHelper;
PlotterBase::m_pPosHelper = pPosHelper;
- double fAdd = pSeries->getY( nIndex );
- impl_maybeReplaceNanWithZero( fAdd );
+ double fAdd = pSeries->getYValue( nIndex );
if( !::rtl::math::isNan(fAdd) && !::rtl::math::isInf(fAdd) )
aLogicYSumMap[nAttachedAxisIndex] += fabs( fAdd );
}
@@ -709,23 +704,6 @@ void AreaChart::createShapes()
if(!pSeries)
continue;
- sal_Int32 nMissingValueTreatment = pSeries->getMissingValueTreatment();
- switch( nMissingValueTreatment )
- {
- case ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP:
- if( !m_bArea )
- m_eNanHandling = NAN_AS_GAP;
- break;
- case ::com::sun::star::chart::MissingValueTreatment::USE_ZERO:
- m_eNanHandling = NAN_AS_ZERO;
- break;
- case ::com::sun::star::chart::MissingValueTreatment::CONTINUE:
- m_eNanHandling = NAN_AS_INTERPOLATED;
- break;
- default:
- break;
- }
-
/* #i70133# ignore points outside of series length in standard area
charts. Stacked area charts will use missing points as zeros. In
standard charts, pSeriesList contains only one series. */
@@ -745,10 +723,8 @@ void AreaChart::createShapes()
(*aSeriesIter)->m_fLogicZPos = fLogicZ;
//collect data point information (logic coordinates, style ):
- double fLogicX = (*aSeriesIter)->getX(nIndex);
- double fLogicY = (*aSeriesIter)->getY(nIndex);
- impl_maybeReplaceNanWithZero( fLogicX );
- impl_maybeReplaceNanWithZero( fLogicY );
+ double fLogicX = (*aSeriesIter)->getXValue(nIndex);
+ double fLogicY = (*aSeriesIter)->getYValue(nIndex);
if( m_nDimension==3 && m_bArea && pSeriesList->size()!=1 )
fLogicY = fabs( fLogicY );
@@ -762,7 +738,7 @@ void AreaChart::createShapes()
|| ::rtl::math::isNan(fLogicY) || ::rtl::math::isInf(fLogicY)
|| ::rtl::math::isNan(fLogicZ) || ::rtl::math::isInf(fLogicZ) )
{
- if( m_eNanHandling == NAN_AS_GAP )
+ if( (*aSeriesIter)->getMissingValueTreatment() == ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP )
{
drawing::PolyPolygonShape3D& rPolygon = (*aSeriesIter)->m_aPolyPolygonShape3D;
sal_Int32& rIndex = (*aSeriesIter)->m_nPolygonIndex;
diff --git a/chart2/source/view/charttypes/AreaChart.hxx b/chart2/source/view/charttypes/AreaChart.hxx
index 89790912893d..ec56d9e2390b 100644
--- a/chart2/source/view/charttypes/AreaChart.hxx
+++ b/chart2/source/view/charttypes/AreaChart.hxx
@@ -104,8 +104,6 @@ private: //methods
, ::com::sun::star::drawing::PolyPolygonShape3D* pSeriesPoly
, PlottingPositionHelper* pPosHelper );
- void impl_maybeReplaceNanWithZero( double& rfValue );
-
private: //member
PlottingPositionHelper* m_pMainPosHelper;
@@ -118,14 +116,6 @@ private: //member
sal_Int32 m_nKeepAspectRatio; //0->no 1->yes other value->automatic
::com::sun::star::drawing::Direction3D m_aGivenAspectRatio; //only used if nKeepAspectRatio==1
- enum tNanHandling
- {
- NAN_AS_ZERO,
- NAN_AS_GAP,
- NAN_AS_INTERPOLATED
- };
- tNanHandling m_eNanHandling;
-
//Properties for splines:
::com::sun::star::chart2::CurveStyle m_eCurveStyle;
sal_Int32 m_nCurveResolution;
diff --git a/chart2/source/view/charttypes/BarChart.cxx b/chart2/source/view/charttypes/BarChart.cxx
index baeac4a29cf1..41cef61561bb 100644
--- a/chart2/source/view/charttypes/BarChart.cxx
+++ b/chart2/source/view/charttypes/BarChart.cxx
@@ -45,7 +45,6 @@
#include "Clipping.hxx"
#include <com/sun/star/chart/DataLabelPlacement.hpp>
-#include <com/sun/star/chart/MissingValueTreatment.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <tools/debug.hxx>
@@ -653,15 +652,10 @@ void BarChart::createShapes()
getSeriesGroupShape(*aSeriesIter, xSeriesTarget) );
//collect data point information (logic coordinates, style ):
- double fLogicX = pPosHelper->getSlotPos( (*aSeriesIter)->getX( nCatIndex ), fSlotX );
- double fLogicBarHeight = (*aSeriesIter)->getY( nCatIndex );
+ double fLogicX = pPosHelper->getSlotPos( (*aSeriesIter)->getXValue( nCatIndex ), fSlotX );
+ double fLogicBarHeight = (*aSeriesIter)->getYValue( nCatIndex );
if( ::rtl::math::isNan( fLogicBarHeight )) //no value at this category
- {
- if( pSeries->getMissingValueTreatment() == ::com::sun::star::chart::MissingValueTreatment::USE_ZERO )
- fLogicBarHeight = 0.0;
- else
- continue;
- }
+ continue;
double fLogicValueForLabeDisplay = fLogicBarHeight;
fLogicBarHeight-=fBaseValue;
diff --git a/chart2/source/view/charttypes/BubbleChart.cxx b/chart2/source/view/charttypes/BubbleChart.cxx
new file mode 100644
index 000000000000..b63603ef403a
--- /dev/null
+++ b/chart2/source/view/charttypes/BubbleChart.cxx
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_chart2.hxx"
+
+#include "BubbleChart.hxx"
+#include "PlottingPositionHelper.hxx"
+#include "ShapeFactory.hxx"
+#include "CommonConverters.hxx"
+#include "macros.hxx"
+#include "ViewDefines.hxx"
+#include "ObjectIdentifier.hxx"
+#include "Splines.hxx"
+#include "LabelPositionHelper.hxx"
+#include "Clipping.hxx"
+#include "Stripe.hxx"
+
+#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <tools/debug.hxx>
+#include <svx/unoprnms.hxx>
+#include <rtl/math.hxx>
+#include <com/sun/star/drawing/DoubleSequence.hpp>
+#include <com/sun/star/drawing/NormalsKind.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::rtl::math;
+using namespace ::com::sun::star::chart2;
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+BubbleChart::BubbleChart( const uno::Reference<XChartType>& xChartTypeModel
+ , sal_Int32 nDimensionCount )
+ : VSeriesPlotter( xChartTypeModel, nDimensionCount, false )
+ , m_bShowNegativeValues(false)
+ , m_bBubbleSizeAsArea(true)
+ , m_fBubbleSizeScaling(1.0)
+ , m_fMaxLogicBubbleSize( 0.0 )
+ , m_fBubbleSizeFactorToScreen( 1.0 )
+{
+ if( !m_pMainPosHelper )
+ m_pMainPosHelper = new PlottingPositionHelper();
+ PlotterBase::m_pPosHelper = m_pMainPosHelper;
+ VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper;
+}
+
+BubbleChart::~BubbleChart()
+{
+ delete m_pMainPosHelper;
+}
+
+void BubbleChart::calculateMaximumLogicBubbleSize()
+{
+ double fMaxSize = 0.0;
+
+ sal_Int32 nStartIndex = 0;
+ sal_Int32 nEndIndex = VSeriesPlotter::getPointCount();
+ for( sal_Int32 nIndex = nStartIndex; nIndex < nEndIndex; nIndex++ )
+ {
+ ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator aZSlotIter = m_aZSlots.begin();
+ const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end();
+ for( ; aZSlotIter != aZSlotEnd; aZSlotIter++ )
+ {
+ ::std::vector< VDataSeriesGroup >::iterator aXSlotIter = aZSlotIter->begin();
+ const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
+ for( ; aXSlotIter != aXSlotEnd; aXSlotIter++ )
+ {
+ ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
+ ::std::vector< VDataSeries* >::const_iterator aSeriesIter = pSeriesList->begin();
+ const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = pSeriesList->end();
+ for( ; aSeriesIter != aSeriesEnd; aSeriesIter++ )
+ {
+ VDataSeries* pSeries( *aSeriesIter );
+ if(!pSeries)
+ continue;
+
+ double fSize = pSeries->getBubble_Size( nIndex );
+ if( m_bShowNegativeValues )
+ fSize = abs(fSize);
+ if( fSize > fMaxSize )
+ fMaxSize = fSize;
+ }
+ }
+ }
+ }
+
+ m_fMaxLogicBubbleSize = fMaxSize;
+}
+
+void BubbleChart::calculateBubbleSizeScalingFactor()
+{
+ double fLogicZ=0.5;
+ drawing::Position3D aSceneMinPos( m_pMainPosHelper->transformLogicToScene( m_pMainPosHelper->getLogicMinX(),m_pMainPosHelper->getLogicMinY(),fLogicZ, false ) );
+ drawing::Position3D aSceneMaxPos( m_pMainPosHelper->transformLogicToScene( m_pMainPosHelper->getLogicMaxX(),m_pMainPosHelper->getLogicMaxY(),fLogicZ, false ) );
+
+ awt::Point aScreenMinPos( LabelPositionHelper(m_pMainPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory).transformSceneToScreenPosition( aSceneMinPos ) );
+ awt::Point aScreenMaxPos( LabelPositionHelper(m_pMainPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory).transformSceneToScreenPosition( aSceneMaxPos ) );
+
+ sal_Int32 nWidth = abs( aScreenMaxPos.X - aScreenMinPos.X );
+ sal_Int32 nHeight = abs( aScreenMaxPos.Y - aScreenMinPos.Y );
+
+ sal_Int32 nMinExtend = std::min( nWidth, nHeight );
+ m_fBubbleSizeFactorToScreen = nMinExtend * 0.25;//max bubble size is 25 percent of diagram size
+}
+
+drawing::Direction3D BubbleChart::transformToScreenBubbleSize( double fLogicSize )
+{
+ drawing::Direction3D aRet(0,0,0);
+
+ if( ::rtl::math::isNan(fLogicSize) || ::rtl::math::isInf(fLogicSize) )
+ return aRet;
+
+ if( m_bShowNegativeValues )
+ fLogicSize = abs(fLogicSize);
+
+ double fMaxSize = m_fMaxLogicBubbleSize;
+
+ double fMaxRadius = fMaxSize;
+ double fRaduis = fLogicSize;
+ if( m_bBubbleSizeAsArea )
+ {
+ fMaxRadius = sqrt( fMaxSize / F_PI );
+ fRaduis = sqrt( fLogicSize / F_PI );
+ }
+
+ aRet.DirectionX = m_fBubbleSizeScaling * m_fBubbleSizeFactorToScreen * fRaduis / fMaxRadius;
+ aRet.DirectionY = aRet.DirectionX;
+
+ return aRet;
+}
+
+bool BubbleChart::isExpandIfValuesCloseToBorder( sal_Int32 /*nDimensionIndex*/ )
+{
+ return true;
+}
+
+bool BubbleChart::isSeperateStackingForDifferentSigns( sal_Int32 /*nDimensionIndex*/ )
+{
+ return false;
+}
+
+//-----------------------------------------------------------------
+
+LegendSymbolStyle BubbleChart::getLegendSymbolStyle()
+{
+ return chart2::LegendSymbolStyle_CIRCLE;
+}
+
+drawing::Direction3D BubbleChart::getPreferredDiagramAspectRatio() const
+{
+ return drawing::Direction3D(-1,-1,-1);
+}
+
+void BubbleChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot )
+{
+ VSeriesPlotter::addSeries( pSeries, zSlot, xSlot, ySlot );
+}
+
+//better performance for big data
+struct FormerPoint
+{
+ FormerPoint( double fX, double fY, double fZ )
+ : m_fX(fX), m_fY(fY), m_fZ(fZ)
+ {}
+ FormerPoint()
+ {
+ ::rtl::math::setNan( &m_fX );
+ ::rtl::math::setNan( &m_fY );
+ ::rtl::math::setNan( &m_fZ );
+ }
+
+ double m_fX;
+ double m_fY;
+ double m_fZ;
+};
+
+void BubbleChart::createShapes()
+{
+ if( m_aZSlots.begin() == m_aZSlots.end() ) //no series
+ return;
+
+ DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"BubbleChart is not proper initialized");
+ if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
+ return;
+
+ //therefore create an own group for the texts and the error bars to move them to front
+ //(because the text group is created after the series group the texts are displayed on top)
+ uno::Reference< drawing::XShapes > xSeriesTarget(
+ createGroupShape( m_xLogicTarget,rtl::OUString() ));
+ uno::Reference< drawing::XShapes > xTextTarget(
+ m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() ));
+
+ //update/create information for current group
+ double fLogicZ = 0.5;//as defined
+
+ sal_Int32 nStartIndex = 0; // inclusive ;..todo get somehow from x scale
+ sal_Int32 nEndIndex = VSeriesPlotter::getPointCount();
+ if(nEndIndex<=0)
+ nEndIndex=1;
+
+ //better performance for big data
+ std::map< VDataSeries*, FormerPoint > aSeriesFormerPointMap;
+ m_bPointsWereSkipped = false;
+ sal_Int32 nSkippedPoints = 0;
+ sal_Int32 nCreatedPoints = 0;
+ //
+
+ calculateMaximumLogicBubbleSize();
+ calculateBubbleSizeScalingFactor();
+ if( m_fMaxLogicBubbleSize <= 0 || m_fBubbleSizeFactorToScreen <= 0 )
+ return;
+
+//=============================================================================
+ //iterate through all x values per indices
+ for( sal_Int32 nIndex = nStartIndex; nIndex < nEndIndex; nIndex++ )
+ {
+ ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator aZSlotIter = m_aZSlots.begin();
+ const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end();
+
+ aZSlotIter = m_aZSlots.begin();
+ for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; aZSlotIter++, nZ++ )
+ {
+ ::std::vector< VDataSeriesGroup >::iterator aXSlotIter = aZSlotIter->begin();
+ const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
+
+ aXSlotIter = aZSlotIter->begin();
+ for( sal_Int32 nX=0; aXSlotIter != aXSlotEnd; aXSlotIter++, nX++ )
+ {
+ ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
+ ::std::vector< VDataSeries* >::const_iterator aSeriesIter = pSeriesList->begin();
+ const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = pSeriesList->end();
+
+ //=============================================================================
+ //iterate through all series
+ for( sal_Int32 nSeriesIndex = 0; aSeriesIter != aSeriesEnd; aSeriesIter++, nSeriesIndex++ )
+ {
+ VDataSeries* pSeries( *aSeriesIter );
+ if(!pSeries)
+ continue;
+
+ uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShape(*aSeriesIter, xSeriesTarget);
+
+ sal_Int32 nAttachedAxisIndex = pSeries->getAttachedAxisIndex();
+ PlottingPositionHelper* pPosHelper = &(this->getPlottingPositionHelper( nAttachedAxisIndex ));
+ if(!pPosHelper)
+ pPosHelper = m_pMainPosHelper;
+ PlotterBase::m_pPosHelper = pPosHelper;
+
+ if(m_nDimension==3)
+ fLogicZ = nZ+0.5;
+
+ //collect data point information (logic coordinates, style ):
+ double fLogicX = pSeries->getXValue(nIndex);
+ double fLogicY = pSeries->getYValue(nIndex);
+ double fBubbleSize = pSeries->getBubble_Size( nIndex );
+
+ if( !m_bShowNegativeValues && fBubbleSize<0.0 )
+ continue;
+
+ if( ::rtl::math::approxEqual( fBubbleSize, 0.0 ) || ::rtl::math::isNan(fBubbleSize) )
+ continue;
+
+ if( ::rtl::math::isNan(fLogicX) || ::rtl::math::isInf(fLogicX)
+ || ::rtl::math::isNan(fLogicY) || ::rtl::math::isInf(fLogicY) )
+ continue;
+
+ bool bIsVisible = pPosHelper->isLogicVisible( fLogicX, fLogicY, fLogicZ );
+
+ drawing::Position3D aUnscaledLogicPosition( fLogicX, fLogicY, fLogicZ );
+ drawing::Position3D aScaledLogicPosition(aUnscaledLogicPosition);
+ pPosHelper->doLogicScaling( aScaledLogicPosition );
+
+ //transformation 3) -> 4)
+ drawing::Position3D aScenePosition( pPosHelper->transformLogicToScene( fLogicX,fLogicY,fLogicZ, false ) );
+
+ //better performance for big data
+ FormerPoint aFormerPoint( aSeriesFormerPointMap[pSeries] );
+ pPosHelper->setCoordinateSystemResolution( m_aCoordinateSystemResolution );
+ if( !pSeries->isAttributedDataPoint(nIndex)
+ &&
+ pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fY, aFormerPoint.m_fZ
+ , aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ ) )
+ {
+ nSkippedPoints++;
+ m_bPointsWereSkipped = true;
+ continue;
+ }
+ aSeriesFormerPointMap[pSeries] = FormerPoint(aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ);
+
+ //create a single datapoint if point is visible
+ if( !bIsVisible )
+ continue;
+
+ //create a group shape for this point and add to the series shape:
+ rtl::OUString aPointCID = ObjectIdentifier::createPointCID(
+ pSeries->getPointCID_Stub(), nIndex );
+ uno::Reference< drawing::XShapes > xPointGroupShape_Shapes(
+ createGroupShape(xSeriesGroupShape_Shapes,aPointCID) );
+ uno::Reference<drawing::XShape> xPointGroupShape_Shape =
+ uno::Reference<drawing::XShape>( xPointGroupShape_Shapes, uno::UNO_QUERY );
+
+ {
+ nCreatedPoints++;
+
+ //create data point
+ drawing::Direction3D aSymbolSize = transformToScreenBubbleSize( fBubbleSize );
+ if(m_nDimension!=3)
+ {
+ uno::Reference<drawing::XShape> xShape;
+ xShape = m_pShapeFactory->createCircle2D( xPointGroupShape_Shapes
+ , aScenePosition, aSymbolSize );
+
+ this->setMappedProperties( xShape
+ , pSeries->getPropertiesOfPoint( nIndex )
+ , PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
+
+ m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
+ }
+
+ //create data point label
+ if( (**aSeriesIter).getDataPointLabelIfLabel(nIndex) )
+ {
+ LabelAlignment eAlignment = LABEL_ALIGN_TOP;
+ drawing::Position3D aScenePosition3D( aScenePosition.PositionX
+ , aScenePosition.PositionY
+ , aScenePosition.PositionZ+this->getTransformedDepth() );
+
+ sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nIndex, m_xChartTypeModel, m_nDimension, pPosHelper->isSwapXAndY() );
+
+ switch(nLabelPlacement)
+ {
+ case ::com::sun::star::chart::DataLabelPlacement::TOP:
+ aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1);
+ eAlignment = LABEL_ALIGN_TOP;
+ break;
+ case ::com::sun::star::chart::DataLabelPlacement::BOTTOM:
+ aScenePosition3D.PositionY += (aSymbolSize.DirectionY/2+1);
+ eAlignment = LABEL_ALIGN_BOTTOM;
+ break;
+ case ::com::sun::star::chart::DataLabelPlacement::LEFT:
+ aScenePosition3D.PositionX -= (aSymbolSize.DirectionX/2+1);
+ eAlignment = LABEL_ALIGN_LEFT;
+ break;
+ case ::com::sun::star::chart::DataLabelPlacement::RIGHT:
+ aScenePosition3D.PositionX += (aSymbolSize.DirectionX/2+1);
+ eAlignment = LABEL_ALIGN_RIGHT;
+ break;
+ case ::com::sun::star::chart::DataLabelPlacement::CENTER:
+ eAlignment = LABEL_ALIGN_CENTER;
+ break;
+ default:
+ DBG_ERROR("this label alignment is not implemented yet");
+ aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1);
+ eAlignment = LABEL_ALIGN_TOP;
+ break;
+ }
+
+
+ awt::Point aScreenPosition2D( LabelPositionHelper(pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory)
+ .transformSceneToScreenPosition( aScenePosition3D ) );
+ sal_Int32 nOffset = 0;
+ if(LABEL_ALIGN_CENTER!=eAlignment)
+ nOffset = 100;//add some spacing //@todo maybe get more intelligent values
+ this->createDataLabel( xTextTarget, **aSeriesIter, nIndex
+ , fBubbleSize, fBubbleSize, aScreenPosition2D, eAlignment, nOffset );
+ }
+ }
+
+ //remove PointGroupShape if empty
+ if(!xPointGroupShape_Shapes->getCount())
+ xSeriesGroupShape_Shapes->remove(xPointGroupShape_Shape);
+
+ }//next series in x slot (next y slot)
+ }//next x slot
+ }//next z slot
+ }//next category
+//=============================================================================
+//=============================================================================
+//=============================================================================
+ OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< area chart :: createShapes():: skipped points: %d created points: %d", nSkippedPoints, nCreatedPoints );
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/view/charttypes/BubbleChart.hxx b/chart2/source/view/charttypes/BubbleChart.hxx
new file mode 100644
index 000000000000..4771a4cccee3
--- /dev/null
+++ b/chart2/source/view/charttypes/BubbleChart.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ,v $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _CHART2_BUBBLECHART_HXX
+#define _CHART2_BUBBLECHART_HXX
+
+#include "VSeriesPlotter.hxx"
+#include <com/sun/star/drawing/Direction3D.hpp>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+class BubbleChart : public VSeriesPlotter
+{
+ //-------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------
+public:
+ BubbleChart( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XChartType >& xChartTypeModel
+ , sal_Int32 nDimensionCount );
+ virtual ~BubbleChart();
+
+ //-------------------------------------------------------------------------
+ // chart2::XPlotter
+ //-------------------------------------------------------------------------
+
+ virtual void SAL_CALL createShapes();
+
+ virtual void addSeries( VDataSeries* pSeries, sal_Int32 zSlot = -1, sal_Int32 xSlot = -1,sal_Int32 ySlot = -1 );
+
+ //-------------------
+ virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const;
+
+ //-------------------------------------------------------------------------
+ // MinimumAndMaximumSupplier
+ //-------------------------------------------------------------------------
+ virtual bool isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex );
+ virtual bool isSeperateStackingForDifferentSigns( sal_Int32 nDimensionIndex );
+
+ //-------------------------------------------------------------------------
+
+ virtual ::com::sun::star::chart2::LegendSymbolStyle getLegendSymbolStyle();
+
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+private: //methods
+ //no default constructor
+ BubbleChart();
+
+ void calculateMaximumLogicBubbleSize();
+ void calculateBubbleSizeScalingFactor();
+
+ com::sun::star::drawing::Direction3D transformToScreenBubbleSize( double fLogicSize );
+
+private: //member
+
+ bool m_bShowNegativeValues;//input parameter
+ bool m_bBubbleSizeAsArea;//input parameter
+ double m_fBubbleSizeScaling;//input parameter
+
+ double m_fMaxLogicBubbleSize;//calculated values
+ double m_fBubbleSizeFactorToScreen;//calculated values
+};
+//.............................................................................
+} //namespace chart
+//.............................................................................
+#endif
diff --git a/chart2/source/view/charttypes/CandleStickChart.cxx b/chart2/source/view/charttypes/CandleStickChart.cxx
index 46fdf3d8f04d..e19a44cdcda6 100644
--- a/chart2/source/view/charttypes/CandleStickChart.cxx
+++ b/chart2/source/view/charttypes/CandleStickChart.cxx
@@ -250,7 +250,7 @@ void CandleStickChart::createShapes()
for( ; aSeriesIter != aSeriesEnd; aSeriesIter++ )
{
//collect data point information (logic coordinates, style ):
- double fLogicX = pPosHelper->getSlotPos( (*aSeriesIter)->getX( nIndex ), fSlotX );
+ double fLogicX = pPosHelper->getSlotPos( (*aSeriesIter)->getXValue( nIndex ), fSlotX );
double fY_First = (*aSeriesIter)->getY_First( nIndex );
double fY_Last = (*aSeriesIter)->getY_Last( nIndex );
double fY_Min = (*aSeriesIter)->getY_Min( nIndex );
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index 7759f3110cbd..608adb49290b 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -376,7 +376,7 @@ void PieChart::createShapes()
sal_Int32 nPointCount=pSeries->getTotalPointCount();
for( nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++ )
{
- double fY = pSeries->getY( nPointIndex );
+ double fY = pSeries->getYValue( nPointIndex );
if(fY<0.0)
{
//@todo warn somehow that negative values are treated as positive
@@ -402,7 +402,7 @@ void PieChart::createShapes()
uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShape(pSeries, xSeriesTarget);
//collect data point information (logic coordinates, style ):
- double fLogicYValue = fabs(pSeries->getY( nPointIndex ));
+ double fLogicYValue = fabs(pSeries->getYValue( nPointIndex ));
if( ::rtl::math::isNan(fLogicYValue) )
continue;
if(fLogicYValue==0.0)//@todo: continue also if the resolution to small
diff --git a/chart2/source/view/charttypes/Splines.cxx b/chart2/source/view/charttypes/Splines.cxx
index a684b9a3228e..6d37d7444868 100644
--- a/chart2/source/view/charttypes/Splines.cxx
+++ b/chart2/source/view/charttypes/Splines.cxx
@@ -318,108 +318,133 @@ void SplineCalculater::CalculateCubicSplines(
, sal_Int32 nGranularity )
{
DBG_ASSERT( nGranularity > 0, "Granularity is invalid" );
+
rResult.SequenceX.realloc(0);
rResult.SequenceY.realloc(0);
rResult.SequenceZ.realloc(0);
- if( !rInput.SequenceX.getLength() )
+ sal_Int32 nOuterCount = rInput.SequenceX.getLength();
+ if( !nOuterCount )
return;
- if( rInput.SequenceX[0].getLength() <= 1 )
- return; //we need at least two points
-
- sal_Int32 nMaxIndexPoints = rInput.SequenceX[0].getLength()-1; // is >=1
- const double* pOldX = rInput.SequenceX[0].getConstArray();
- const double* pOldY = rInput.SequenceY[0].getConstArray();
- const double* pOldZ = rInput.SequenceZ[0].getConstArray();
-
- // #i13699# The curve gets a parameter and then for each coordinate a
- // separate spline will be calculated using the parameter as first argument
- // and the point coordinate as second argument. Therefore the points need
- // not to be sorted in its x-coordinates. The parameter is sorted by
- // construction.
-
- ::std::vector < double > aParameter(nMaxIndexPoints+1);
- aParameter[0]=0.0;
- for( sal_Int32 nIndex=1; nIndex<=nMaxIndexPoints; nIndex++ )
- {
- // The euclidian distance leads to curve loops for functions having single extreme points
-// aParameter[nIndex]=aParameter[nIndex-1]+
-// sqrt( (pOldX[nIndex]-pOldX[nIndex-1])*(pOldX[nIndex]-pOldX[nIndex-1])+
-// (pOldY[nIndex]-pOldY[nIndex-1])*(pOldY[nIndex]-pOldY[nIndex-1])+
-// (pOldZ[nIndex]-pOldZ[nIndex-1])*(pOldZ[nIndex]-pOldZ[nIndex-1]));
-
- // use increment of 1 instead
- aParameter[nIndex]=aParameter[nIndex-1]+1;
- }
- // Split the calculation to X, Y and Z coordinate
- tPointVecType aInputX;
- aInputX.resize(nMaxIndexPoints+1);
- tPointVecType aInputY;
- aInputY.resize(nMaxIndexPoints+1);
- tPointVecType aInputZ;
- aInputZ.resize(nMaxIndexPoints+1);
- for (sal_Int32 nN=0;nN<=nMaxIndexPoints; nN++ )
- {
- aInputX[ nN ].first=aParameter[nN];
- aInputX[ nN ].second=pOldX[ nN ];
- aInputY[ nN ].first=aParameter[nN];
- aInputY[ nN ].second=pOldY[ nN ];
- aInputZ[ nN ].first=aParameter[nN];
- aInputZ[ nN ].second=pOldZ[ nN ];
- }
- // generate a spline for each coordinate. It holds the complete
- // information to calculate each point of the curve
-
- // generate the kind "natural spline"
- double fInfty;
- ::rtl::math::setInf( &fInfty, sal_False );
- lcl_SplineCalculation aSplineX( aInputX, fInfty, fInfty );
- lcl_SplineCalculation aSplineY( aInputY, fInfty, fInfty );
- lcl_SplineCalculation aSplineZ( aInputZ, fInfty, fInfty );
-
- // fill result polygon with calculated values
- rResult.SequenceX.realloc(1);
- rResult.SequenceY.realloc(1);
- rResult.SequenceZ.realloc(1);
- rResult.SequenceX[0].realloc( nMaxIndexPoints*nGranularity + 1);
- rResult.SequenceY[0].realloc( nMaxIndexPoints*nGranularity + 1);
- rResult.SequenceZ[0].realloc( nMaxIndexPoints*nGranularity + 1);
-
- double* pNewX = rResult.SequenceX[0].getArray();
- double* pNewY = rResult.SequenceY[0].getArray();
- double* pNewZ = rResult.SequenceZ[0].getArray();
-
- sal_Int32 nNewPointIndex = 0; // Index in result points
- // needed for inner loop
- double fInc; // step for intermediate points
- sal_Int32 nj; // for loop
- double fParam; // a intermediate parameter value
-
- for( sal_Int32 ni = 0; ni < nMaxIndexPoints; ni++ )
- {
- // given point is surely a curve point
- pNewX[nNewPointIndex] = pOldX[ni];
- pNewY[nNewPointIndex] = pOldY[ni];
- pNewZ[nNewPointIndex] = pOldZ[ni];
- nNewPointIndex++;
-
- // calculate intermediate points
- fInc = ( aParameter[ ni+1 ] - aParameter[ni] ) / static_cast< double >( nGranularity );
- for(nj = 1; nj < nGranularity; nj++)
+ rResult.SequenceX.realloc(nOuterCount);
+ rResult.SequenceY.realloc(nOuterCount);
+ rResult.SequenceZ.realloc(nOuterCount);
+
+ for( sal_Int32 nOuter = 0; nOuter < nOuterCount; ++nOuter )
+ {
+ if( rInput.SequenceX[nOuter].getLength() <= 1 )
+ continue; //we need at least two points
+
+ sal_Int32 nMaxIndexPoints = rInput.SequenceX[nOuter].getLength()-1; // is >=1
+ const double* pOldX = rInput.SequenceX[nOuter].getConstArray();
+ const double* pOldY = rInput.SequenceY[nOuter].getConstArray();
+ const double* pOldZ = rInput.SequenceZ[nOuter].getConstArray();
+
+ // #i13699# The curve gets a parameter and then for each coordinate a
+ // separate spline will be calculated using the parameter as first argument
+ // and the point coordinate as second argument. Therefore the points need
+ // not to be sorted in its x-coordinates. The parameter is sorted by
+ // construction.
+
+ ::std::vector < double > aParameter(nMaxIndexPoints+1);
+ aParameter[0]=0.0;
+ for( sal_Int32 nIndex=1; nIndex<=nMaxIndexPoints; nIndex++ )
+ {
+ // The euclidian distance leads to curve loops for functions having single extreme points
+ //aParameter[nIndex]=aParameter[nIndex-1]+
+ //sqrt( (pOldX[nIndex]-pOldX[nIndex-1])*(pOldX[nIndex]-pOldX[nIndex-1])+
+ //(pOldY[nIndex]-pOldY[nIndex-1])*(pOldY[nIndex]-pOldY[nIndex-1])+
+ //(pOldZ[nIndex]-pOldZ[nIndex-1])*(pOldZ[nIndex]-pOldZ[nIndex-1]));
+
+ // use increment of 1 instead
+ aParameter[nIndex]=aParameter[nIndex-1]+1;
+ }
+ // Split the calculation to X, Y and Z coordinate
+ tPointVecType aInputX;
+ aInputX.resize(nMaxIndexPoints+1);
+ tPointVecType aInputY;
+ aInputY.resize(nMaxIndexPoints+1);
+ tPointVecType aInputZ;
+ aInputZ.resize(nMaxIndexPoints+1);
+ for (sal_Int32 nN=0;nN<=nMaxIndexPoints; nN++ )
{
- fParam = aParameter[ni] + ( fInc * static_cast< double >( nj ) );
+ aInputX[ nN ].first=aParameter[nN];
+ aInputX[ nN ].second=pOldX[ nN ];
+ aInputY[ nN ].first=aParameter[nN];
+ aInputY[ nN ].second=pOldY[ nN ];
+ aInputZ[ nN ].first=aParameter[nN];
+ aInputZ[ nN ].second=pOldZ[ nN ];
+ }
- pNewX[nNewPointIndex]=aSplineX.GetInterpolatedValue( fParam );
- pNewY[nNewPointIndex]=aSplineY.GetInterpolatedValue( fParam );
- pNewZ[nNewPointIndex]=aSplineZ.GetInterpolatedValue( fParam );
+ // generate a spline for each coordinate. It holds the complete
+ // information to calculate each point of the curve
+ double fXDerivation;
+ double fYDerivation;
+ double fZDerivation;
+ if( pOldX[ 0 ] == pOldX[nMaxIndexPoints] &&
+ pOldY[ 0 ] == pOldY[nMaxIndexPoints] &&
+ pOldZ[ 0 ] == pOldZ[nMaxIndexPoints] )
+ {
+ // #i101050# avoid a corner in closed lines, which are smoothed by spline
+ // This derivation are special for parameter of kind 0,1,2,3... If you
+ // change generating parameters (see above), then adapt derivations too.)
+ fXDerivation = 0.5 * (pOldX[1]-pOldX[nMaxIndexPoints-1]);
+ fYDerivation = 0.5 * (pOldY[1]-pOldY[nMaxIndexPoints-1]);
+ fZDerivation = 0.5 * (pOldZ[1]-pOldZ[nMaxIndexPoints-1]);
+ }
+ else // generate the kind "natural spline"
+ {
+ double fInfty;
+ ::rtl::math::setInf( &fInfty, sal_False );
+ fXDerivation = fInfty;
+ fYDerivation = fInfty;
+ fZDerivation = fInfty;
+ }
+ lcl_SplineCalculation aSplineX( aInputX, fXDerivation, fXDerivation );
+ lcl_SplineCalculation aSplineY( aInputY, fYDerivation, fYDerivation );
+ lcl_SplineCalculation aSplineZ( aInputZ, fZDerivation, fZDerivation );
+
+ // fill result polygon with calculated values
+ rResult.SequenceX[nOuter].realloc( nMaxIndexPoints*nGranularity + 1);
+ rResult.SequenceY[nOuter].realloc( nMaxIndexPoints*nGranularity + 1);
+ rResult.SequenceZ[nOuter].realloc( nMaxIndexPoints*nGranularity + 1);
+
+ double* pNewX = rResult.SequenceX[nOuter].getArray();
+ double* pNewY = rResult.SequenceY[nOuter].getArray();
+ double* pNewZ = rResult.SequenceZ[nOuter].getArray();
+
+ sal_Int32 nNewPointIndex = 0; // Index in result points
+ // needed for inner loop
+ double fInc; // step for intermediate points
+ sal_Int32 nj; // for loop
+ double fParam; // a intermediate parameter value
+
+ for( sal_Int32 ni = 0; ni < nMaxIndexPoints; ni++ )
+ {
+ // given point is surely a curve point
+ pNewX[nNewPointIndex] = pOldX[ni];
+ pNewY[nNewPointIndex] = pOldY[ni];
+ pNewZ[nNewPointIndex] = pOldZ[ni];
nNewPointIndex++;
+
+ // calculate intermediate points
+ fInc = ( aParameter[ ni+1 ] - aParameter[ni] ) / static_cast< double >( nGranularity );
+ for(nj = 1; nj < nGranularity; nj++)
+ {
+ fParam = aParameter[ni] + ( fInc * static_cast< double >( nj ) );
+
+ pNewX[nNewPointIndex]=aSplineX.GetInterpolatedValue( fParam );
+ pNewY[nNewPointIndex]=aSplineY.GetInterpolatedValue( fParam );
+ pNewZ[nNewPointIndex]=aSplineZ.GetInterpolatedValue( fParam );
+ nNewPointIndex++;
+ }
}
+ // add last point
+ pNewX[nNewPointIndex] = pOldX[nMaxIndexPoints];
+ pNewY[nNewPointIndex] = pOldY[nMaxIndexPoints];
+ pNewZ[nNewPointIndex] = pOldZ[nMaxIndexPoints];
}
- // add last point
- pNewX[nNewPointIndex] = pOldX[nMaxIndexPoints];
- pNewY[nNewPointIndex] = pOldY[nMaxIndexPoints];
- pNewZ[nNewPointIndex] = pOldZ[nMaxIndexPoints];
}
void SplineCalculater::CalculateBSplines(
@@ -436,80 +461,85 @@ void SplineCalculater::CalculateBSplines(
rResult.SequenceY.realloc(0);
rResult.SequenceZ.realloc(0);
- if( !rInput.SequenceX.getLength() )
+ sal_Int32 nOuterCount = rInput.SequenceX.getLength();
+ if( !nOuterCount )
return; // no input
- if( rInput.SequenceX[0].getLength() <= 1 )
- return; // need at least 2 control points
-
- sal_Int32 n = rInput.SequenceX[0].getLength()-1; // maximum index of control points
-
- double fCurveparam =0.0; // parameter for the curve
- // 0<= fCurveparam < fMaxCurveparam
- double fMaxCurveparam = 2.0+ n - k;
- if (fMaxCurveparam <= 0.0)
- return; // not enough control points for desired spline order
-
- if (nGranularity < 1)
- return; //need at least 1 line for each part beween the control points
-
- const double* pOldX = rInput.SequenceX[0].getConstArray();
- const double* pOldY = rInput.SequenceY[0].getConstArray();
- const double* pOldZ = rInput.SequenceZ[0].getConstArray();
-
- // keep this amount of steps to go well with old version
- sal_Int32 nNewSectorCount = nGranularity * n;
- double fCurveStep = fMaxCurveparam/static_cast< double >(nNewSectorCount);
-
- double *b = new double [n + k + 1]; // values of blending functions
-
- const double* t = createTVector(n, k); // knot vector
-
- rResult.SequenceX.realloc(1);
- rResult.SequenceY.realloc(1);
- rResult.SequenceZ.realloc(1);
- rResult.SequenceX[0].realloc(nNewSectorCount+1);
- rResult.SequenceY[0].realloc(nNewSectorCount+1);
- rResult.SequenceZ[0].realloc(nNewSectorCount+1);
- double* pNewX = rResult.SequenceX[0].getArray();
- double* pNewY = rResult.SequenceY[0].getArray();
- double* pNewZ = rResult.SequenceZ[0].getArray();
-
- // variables needed inside loop, when calculating one point of output
- sal_Int32 nPointIndex =0; //index of given contol points
- double fX=0.0;
- double fY=0.0;
- double fZ=0.0; //coordinates of a new BSpline point
-
- for(sal_Int32 nNewSector=0; nNewSector<nNewSectorCount; nNewSector++)
- { // in first looping fCurveparam has value 0.0
-
- // Calculate the values of the blending functions for actual curve parameter
- BVector(fCurveparam, n, k, b, t);
-
- // output point(fCurveparam) = sum over {input point * value of blending function}
- fX = 0.0;
- fY = 0.0;
- fZ = 0.0;
- for (nPointIndex=0;nPointIndex<=n;nPointIndex++)
- {
- fX +=pOldX[nPointIndex]*b[nPointIndex];
- fY +=pOldY[nPointIndex]*b[nPointIndex];
- fZ +=pOldZ[nPointIndex]*b[nPointIndex];
+ rResult.SequenceX.realloc(nOuterCount);
+ rResult.SequenceY.realloc(nOuterCount);
+ rResult.SequenceZ.realloc(nOuterCount);
+
+ for( sal_Int32 nOuter = 0; nOuter < nOuterCount; ++nOuter )
+ {
+ if( rInput.SequenceX[nOuter].getLength() <= 1 )
+ continue; // need at least 2 control points
+
+ sal_Int32 n = rInput.SequenceX[nOuter].getLength()-1; // maximum index of control points
+
+ double fCurveparam =0.0; // parameter for the curve
+ // 0<= fCurveparam < fMaxCurveparam
+ double fMaxCurveparam = 2.0+ n - k;
+ if (fMaxCurveparam <= 0.0)
+ return; // not enough control points for desired spline order
+
+ if (nGranularity < 1)
+ return; //need at least 1 line for each part beween the control points
+
+ const double* pOldX = rInput.SequenceX[nOuter].getConstArray();
+ const double* pOldY = rInput.SequenceY[nOuter].getConstArray();
+ const double* pOldZ = rInput.SequenceZ[nOuter].getConstArray();
+
+ // keep this amount of steps to go well with old version
+ sal_Int32 nNewSectorCount = nGranularity * n;
+ double fCurveStep = fMaxCurveparam/static_cast< double >(nNewSectorCount);
+
+ double *b = new double [n + k + 1]; // values of blending functions
+
+ const double* t = createTVector(n, k); // knot vector
+
+ rResult.SequenceX[nOuter].realloc(nNewSectorCount+1);
+ rResult.SequenceY[nOuter].realloc(nNewSectorCount+1);
+ rResult.SequenceZ[nOuter].realloc(nNewSectorCount+1);
+ double* pNewX = rResult.SequenceX[nOuter].getArray();
+ double* pNewY = rResult.SequenceY[nOuter].getArray();
+ double* pNewZ = rResult.SequenceZ[nOuter].getArray();
+
+ // variables needed inside loop, when calculating one point of output
+ sal_Int32 nPointIndex =0; //index of given contol points
+ double fX=0.0;
+ double fY=0.0;
+ double fZ=0.0; //coordinates of a new BSpline point
+
+ for(sal_Int32 nNewSector=0; nNewSector<nNewSectorCount; nNewSector++)
+ { // in first looping fCurveparam has value 0.0
+
+ // Calculate the values of the blending functions for actual curve parameter
+ BVector(fCurveparam, n, k, b, t);
+
+ // output point(fCurveparam) = sum over {input point * value of blending function}
+ fX = 0.0;
+ fY = 0.0;
+ fZ = 0.0;
+ for (nPointIndex=0;nPointIndex<=n;nPointIndex++)
+ {
+ fX +=pOldX[nPointIndex]*b[nPointIndex];
+ fY +=pOldY[nPointIndex]*b[nPointIndex];
+ fZ +=pOldZ[nPointIndex]*b[nPointIndex];
+ }
+ pNewX[nNewSector] = fX;
+ pNewY[nNewSector] = fY;
+ pNewZ[nNewSector] = fZ;
+
+ fCurveparam += fCurveStep; //for next looping
}
- pNewX[nNewSector] = fX;
- pNewY[nNewSector] = fY;
- pNewZ[nNewSector] = fZ;
+ // add last control point to BSpline curve
+ pNewX[nNewSectorCount] = pOldX[n];
+ pNewY[nNewSectorCount] = pOldY[n];
+ pNewZ[nNewSectorCount] = pOldZ[n];
- fCurveparam += fCurveStep; //for next looping
+ delete[] t;
+ delete[] b;
}
- // add last control point to BSpline curve
- pNewX[nNewSectorCount] = pOldX[n];
- pNewY[nNewSectorCount] = pOldY[n];
- pNewZ[nNewSectorCount] = pOldZ[n];
-
- delete[] t;
- delete[] b;
}
//.............................................................................
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 71f753afa5c6..73fa9039bf44 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -61,6 +61,7 @@
#include "PieChart.hxx"
#include "AreaChart.hxx"
#include "CandleStickChart.hxx"
+#include "BubbleChart.hxx"
//
#include <com/sun/star/chart/ErrorBarStyle.hpp>
@@ -389,7 +390,7 @@ OUString VSeriesPlotter::getLabelTextForValue( VDataSeries& rDataSeries
}
else
{
- if( m_aAxesNumberFormats.hasFormat(1,rDataSeries.getAttachedAxisIndex()) ) //y-axis
+ if( rDataSeries.shouldLabelNumberFormatKeyBeDetectedFromYAxis() && m_aAxesNumberFormats.hasFormat(1,rDataSeries.getAttachedAxisIndex()) ) //y-axis
nNumberFormatKey = m_aAxesNumberFormats.getFormat(1,rDataSeries.getAttachedAxisIndex());
else
nNumberFormatKey = rDataSeries.detectNumberFormatKey( nPointIndex );
@@ -1409,7 +1410,7 @@ void VDataSeriesGroup::getMinimumAndMaximiumX( double& rfMinimum, double& rfMaxi
sal_Int32 nPointCount = (*aSeriesIter)->getTotalPointCount();
for(sal_Int32 nN=0;nN<nPointCount;nN++)
{
- double fX = (*aSeriesIter)->getX( nN );
+ double fX = (*aSeriesIter)->getXValue( nN );
if( ::rtl::math::isNan(fX) )
continue;
if(rfMaximum<fX)
@@ -1441,12 +1442,12 @@ void VDataSeriesGroup::getMinimumAndMaximiumYInContinuousXRange( double& rfMinY,
if( nAxisIndex != (*aSeriesIter)->getAttachedAxisIndex() )
continue;
- double fX = (*aSeriesIter)->getX( nN );
+ double fX = (*aSeriesIter)->getXValue( nN );
if( ::rtl::math::isNan(fX) )
continue;
if( fX < fMinX || fX > fMaxX )
continue;
- double fY = (*aSeriesIter)->getY( nN );
+ double fY = (*aSeriesIter)->getYValue( nN );
if( ::rtl::math::isNan(fY) )
continue;
if(rfMaxY<fY)
@@ -2063,6 +2064,8 @@ VSeriesPlotter* VSeriesPlotter::createSeriesPlotter(
pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,true);
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
pRet = new AreaChart(xChartTypeModel,nDimensionCount,false,true);
+ else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ pRet = new BubbleChart(xChartTypeModel,nDimensionCount);
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
pRet = new PieChart(xChartTypeModel,nDimensionCount);
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
diff --git a/chart2/source/view/charttypes/makefile.mk b/chart2/source/view/charttypes/makefile.mk
index 434db9304788..1da5697fd25f 100644
--- a/chart2/source/view/charttypes/makefile.mk
+++ b/chart2/source/view/charttypes/makefile.mk
@@ -51,7 +51,8 @@ SLOFILES = $(SLO)$/Splines.obj \
$(SLO)$/BarChart.obj \
$(SLO)$/PieChart.obj \
$(SLO)$/AreaChart.obj \
- $(SLO)$/CandleStickChart.obj
+ $(SLO)$/CandleStickChart.obj \
+ $(SLO)$/BubbleChart.obj
# --- Targets -----------------------------------------------------------------
diff --git a/chart2/source/view/diagram/VDiagram.cxx b/chart2/source/view/diagram/VDiagram.cxx
index 70f930aa8623..5e0db2644cc5 100644
--- a/chart2/source/view/diagram/VDiagram.cxx
+++ b/chart2/source/view/diagram/VDiagram.cxx
@@ -553,13 +553,13 @@ void VDiagram::createShapes_3d()
CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
if( CuboidPlanePosition_Right==eLeftWallPos )
xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
- Stripe aStripe( drawing::Position3D(xPos,0,0)
- , drawing::Direction3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
+ Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
+ , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
, drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
uno::Reference< drawing::XShape > xShape =
m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe
- , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true );
+ , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true, true );
if( !bAddFloorAndWall )
{
//we always need this object as dummy object for correct scene dimensions
@@ -573,9 +573,9 @@ void VDiagram::createShapes_3d()
CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
if( CuboidPlanePosition_Front==eBackWallPos )
zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
- Stripe aStripe( drawing::Position3D(0,0,zPos)
+ Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
, drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
- , drawing::Direction3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
+ , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
uno::Reference< drawing::XShape > xShape =
m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe
diff --git a/chart2/source/view/inc/ShapeFactory.hxx b/chart2/source/view/inc/ShapeFactory.hxx
index 63a7c7558a5b..a03bbd3237d8 100644
--- a/chart2/source/view/inc/ShapeFactory.hxx
+++ b/chart2/source/view/inc/ShapeFactory.hxx
@@ -122,7 +122,7 @@ public:
, const Stripe& rStripe
, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSourceProp
, const tPropertyNameMap& rPropertyNameMap
- , sal_Bool bDoubleSided = true);
+ , sal_Bool bDoubleSided = true, bool bRotatedTexture=false );
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
createArea3D( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
@@ -159,6 +159,11 @@ public:
, const ::com::sun::star::drawing::PolyPolygonShape3D& rPoints
, const VLineProperties& rLineProperties );
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createCircle2D( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
+ , const ::com::sun::star::drawing::Position3D& rPos
+ , const ::com::sun::star::drawing::Direction3D& rSize );
+
//------------------- create 2D elements:
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
diff --git a/chart2/source/view/inc/Stripe.hxx b/chart2/source/view/inc/Stripe.hxx
index fe3a728daa02..dc017fc7aaba 100644
--- a/chart2/source/view/inc/Stripe.hxx
+++ b/chart2/source/view/inc/Stripe.hxx
@@ -65,7 +65,7 @@ public:
::com::sun::star::uno::Any getPolyPolygonShape3D() const;
::com::sun::star::uno::Any getNormalsPolygon() const;
- ::com::sun::star::uno::Any getTexturePolygon() const;
+ ::com::sun::star::uno::Any getTexturePolygon( bool bRotatedTexture ) const;
::com::sun::star::drawing::Position3D GetPosition1() const { return m_aPoint1; }
::com::sun::star::drawing::Position3D GetPosition2() const { return m_aPoint2; }
diff --git a/chart2/source/view/inc/VDataSeries.hxx b/chart2/source/view/inc/VDataSeries.hxx
index 61c0a15bc402..9426c1e9256c 100644
--- a/chart2/source/view/inc/VDataSeries.hxx
+++ b/chart2/source/view/inc/VDataSeries.hxx
@@ -89,14 +89,16 @@ public:
void setPageReferenceSize( const ::com::sun::star::awt::Size & rPageRefSize );
sal_Int32 getTotalPointCount() const;
- double getX( sal_Int32 index ) const;
- double getY( sal_Int32 index ) const;
+ double getXValue( sal_Int32 index ) const;
+ double getYValue( sal_Int32 index ) const;
double getY_Min( sal_Int32 index ) const;
double getY_Max( sal_Int32 index ) const;
double getY_First( sal_Int32 index ) const;
double getY_Last( sal_Int32 index ) const;
+ double getBubble_Size( sal_Int32 index ) const;
+
double getMinimumofAllDifferentYValues( sal_Int32 index ) const;
double getMaximumofAllDifferentYValues( sal_Int32 index ) const;
@@ -108,6 +110,7 @@ public:
bool hasExplicitNumberFormat( sal_Int32 nPointIndex, bool bForPercentage ) const;
sal_Int32 getExplicitNumberFormat( sal_Int32 nPointIndex, bool bForPercentage ) const;
sal_Int32 detectNumberFormatKey( sal_Int32 nPointIndex ) const;
+ bool shouldLabelNumberFormatKeyBeDetectedFromYAxis() const;
sal_Int32 getLabelPlacement( sal_Int32 nPointIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType
, sal_Int32 nDimensionCount, sal_Bool bSwapXAndY ) const;
@@ -141,6 +144,8 @@ public:
void setStartingAngle( sal_Int32 nStartingAngle );
sal_Int32 getStartingAngle() const;
+ void setRoleOfSequenceForDataLabelNumberFormatDetection( const rtl::OUString& rRole );
+
//this is only temporarily here for area chart:
::com::sun::star::drawing::PolyPolygonShape3D m_aPolyPolygonShape3D;
sal_Int32 m_nPolygonIndex;
@@ -207,6 +212,10 @@ private: //member
VDataSequence m_aValues_Y_First;
VDataSequence m_aValues_Y_Last;
+ VDataSequence m_aValues_Bubble_Size;
+
+ VDataSequence* m_pValueSequenceForDataLabelNumberFormatDetection;
+
mutable double m_fYMeanValue;
::com::sun::star::uno::Sequence< sal_Int32 > m_aAttributedDataPointIndexList;
@@ -248,7 +257,8 @@ private: //member
::com::sun::star::awt::Size m_aReferenceSize;
//
- sal_Int32 m_nMissingValueTreatment;
+ sal_Int32 m_nMissingValueTreatment;
+ bool m_bAllowPercentValueInDataLabel;
};
//.............................................................................
diff --git a/chart2/source/view/main/ChartItemPool.cxx b/chart2/source/view/main/ChartItemPool.cxx
index 63c5656a83e0..f3024a10e958 100644
--- a/chart2/source/view/main/ChartItemPool.cxx
+++ b/chart2/source/view/main/ChartItemPool.cxx
@@ -66,6 +66,7 @@ ChartItemPool::ChartItemPool():
ppPoolDefaults[SCHATTR_DATADESCR_PLACEMENT - SCHATTR_START] = new SfxInt32Item(SCHATTR_DATADESCR_PLACEMENT,0);
SvULongs aTmp;
ppPoolDefaults[SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS - SCHATTR_START] = new SfxIntegerListItem(SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS,aTmp);
+ ppPoolDefaults[SCHATTR_DATADESCR_NO_PERCENTVALUE - SCHATTR_START] = new SfxBoolItem(SCHATTR_DATADESCR_NO_PERCENTVALUE);
ppPoolDefaults[SCHATTR_LEGEND_POS - SCHATTR_START] = new SvxChartLegendPosItem( CHLEGEND_RIGHT, SCHATTR_LEGEND_POS );
// ppPoolDefaults[SCHATTR_TEXT_ORIENT - SCHATTR_START] = new SvxChartTextOrientItem;
diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx
index 237985cd160c..31e44dbc245b 100644
--- a/chart2/source/view/main/ChartView.cxx
+++ b/chart2/source/view/main/ChartView.cxx
@@ -86,7 +86,6 @@
#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/XDiagram.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
@@ -726,6 +725,9 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
rtl::OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCS, nT, nS ) );
pSeries->setParticle(aSeriesParticle);
+ OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
+ pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole);
+
//ignore secondary axis for charttypes that do not suppoert them
if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX &&
!ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, 1 ) )
@@ -1743,7 +1745,7 @@ sal_Int32 lcl_getExplicitNumberFormatKeyForAxis(
for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
{
if( nDimensionIndex != 0 )
- aRoleToMatch = aChartTypes[nCTIdx]->getRoleOfSequenceForSeriesLabel();
+ aRoleToMatch = ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( aChartTypes[nCTIdx] );
Reference< XDataSeriesContainer > xDSCnt( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
Sequence< Reference< XDataSeries > > aDataSeriesSeq( xDSCnt->getDataSeries());
for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aDataSeriesSeq.getLength(); ++nSeriesIdx )
@@ -1856,24 +1858,36 @@ sal_Int32 ExplicitValueProvider::getPercentNumberFormat( const Reference< util::
}
-sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForLabel(
+sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
const uno::Reference< XDataSeries >& xSeries,
sal_Int32 nPointIndex /*-1 for whole series*/,
- const uno::Reference< beans::XPropertySet >& xAttachedAxisProps
+ const uno::Reference< XDiagram >& xDiagram
)
{
sal_Int32 nFormat=0;
if( !xSeriesOrPointProp.is() )
return nFormat;
+
rtl::OUString aPropName( C2U( "NumberFormat" ) );
if( !(xSeriesOrPointProp->getPropertyValue(aPropName) >>= nFormat) )
{
- if( xAttachedAxisProps.is() && !( xAttachedAxisProps->getPropertyValue( aPropName ) >>= nFormat ) )
+ uno::Reference< chart2::XChartType > xChartType( DataSeriesHelper::getChartTypeOfSeries( xSeries, xDiagram ) );
+
+ bool bFormatFound = false;
+ if( ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( xChartType ) )
+ {
+ uno::Reference< beans::XPropertySet > xAttachedAxisProps( DiagramHelper::getAttachedAxis( xSeries, xDiagram ), uno::UNO_QUERY );
+ if( xAttachedAxisProps.is() && ( xAttachedAxisProps->getPropertyValue( aPropName ) >>= nFormat ) )
+ bFormatFound = true;
+ }
+ if( !bFormatFound )
{
Reference< chart2::data::XDataSource > xSeriesSource( xSeries, uno::UNO_QUERY );
+ OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
+
Reference< data::XLabeledDataSequence > xLabeledSequence(
- DataSeriesHelper::getDataSequenceByRole( xSeriesSource, C2U("values-y"), false ));
+ DataSeriesHelper::getDataSequenceByRole( xSeriesSource, aRole, false ));
if( xLabeledSequence.is() )
{
Reference< data::XDataSequence > xValues( xLabeledSequence->getValues() );
@@ -1887,7 +1901,7 @@ sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForLabel(
return nFormat;
}
-sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForLabel(
+sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
{
diff --git a/chart2/source/view/main/PlottingPositionHelper.cxx b/chart2/source/view/main/PlottingPositionHelper.cxx
index 2d58a25f3808..e99c260c6d04 100644
--- a/chart2/source/view/main/PlottingPositionHelper.cxx
+++ b/chart2/source/view/main/PlottingPositionHelper.cxx
@@ -142,19 +142,6 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale
std::swap(nXAxisOrientation,nYAxisOrientation);
}
- if( AxisOrientation_MATHEMATICAL==nXAxisOrientation )
- aMatrix.translate(-MinX, 0.0, 0.0);
- else
- aMatrix.translate(-MaxX, 0.0, 0.0);
- if( AxisOrientation_MATHEMATICAL==nYAxisOrientation )
- aMatrix.translate(0.0, -MinY, 0.0);
- else
- aMatrix.translate(0.0, -MaxY, 0.0);
- if( AxisOrientation_MATHEMATICAL==nZAxisOrientation )
- aMatrix.translate(0.0, 0.0, -MaxZ);//z direction in draw is reverse mathematical direction
- else
- aMatrix.translate(0.0, 0.0, -MinZ);
-
double fWidthX = MaxX - MinX;
double fWidthY = MaxY - MinY;
double fWidthZ = MaxZ - MinZ;
@@ -163,9 +150,24 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale
double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0;
double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0;
- aMatrix.scale(fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX,
- fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY,
- fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ);
+ double fScaleX = fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX;
+ double fScaleY = fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY;
+ double fScaleZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
+
+ aMatrix.scale(fScaleX, fScaleY, fScaleZ);
+
+ if( AxisOrientation_MATHEMATICAL==nXAxisOrientation )
+ aMatrix.translate(-MinX*fScaleX, 0.0, 0.0);
+ else
+ aMatrix.translate(-MaxX*fScaleX, 0.0, 0.0);
+ if( AxisOrientation_MATHEMATICAL==nYAxisOrientation )
+ aMatrix.translate(0.0, -MinY*fScaleY, 0.0);
+ else
+ aMatrix.translate(0.0, -MaxY*fScaleY, 0.0);
+ if( AxisOrientation_MATHEMATICAL==nZAxisOrientation )
+ aMatrix.translate(0.0, 0.0, -MaxZ*fScaleZ);//z direction in draw is reverse mathematical direction
+ else
+ aMatrix.translate(0.0, 0.0, -MinZ*fScaleZ);
aMatrix = m_aMatrixScreenToScene*aMatrix;
diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx
index 21bf943c9899..8a19e66334fb 100644
--- a/chart2/source/view/main/ShapeFactory.cxx
+++ b/chart2/source/view/main/ShapeFactory.cxx
@@ -1023,7 +1023,8 @@ uno::Reference< drawing::XShape >
, const Stripe& rStripe
, const uno::Reference< beans::XPropertySet >& xSourceProp
, const tPropertyNameMap& rPropertyNameMap
- , sal_Bool bDoubleSided )
+ , sal_Bool bDoubleSided
+ , bool bRotatedTexture )
{
if( !xTarget.is() )
return 0;
@@ -1047,7 +1048,7 @@ uno::Reference< drawing::XShape >
//TexturePolygon
xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTUREPOLYGON3D )
- , rStripe.getTexturePolygon() );
+ , rStripe.getTexturePolygon( bRotatedTexture ) );
//Normals Polygon
@@ -1573,6 +1574,53 @@ uno::Reference< drawing::XShapes >
}
uno::Reference< drawing::XShape >
+ ShapeFactory::createCircle2D( const uno::Reference< drawing::XShapes >& xTarget
+ , const drawing::Position3D& rPosition
+ , const drawing::Direction3D& rSize )
+{
+ if( !xTarget.is() )
+ return 0;
+
+ //create shape
+ uno::Reference< drawing::XShape > xShape(
+ m_xShapeFactory->createInstance( C2U(
+ "com.sun.star.drawing.EllipseShape") ), uno::UNO_QUERY );
+ xTarget->add(xShape);
+
+ try
+ {
+ drawing::Position3D aCenterPosition(
+ rPosition.PositionX - (rSize.DirectionX / 2.0),
+ rPosition.PositionY - (rSize.DirectionY / 2.0),
+ rPosition.PositionZ );
+ xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
+ xShape->setSize( Direction3DToAWTSize( rSize ));
+ }
+ catch( const uno::Exception & e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+
+ //set properties
+ uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
+ DBG_ASSERT(xProp.is(), "created shape offers no XPropertySet");
+ if( xProp.is())
+ {
+ try
+ {
+ drawing::CircleKind eKind = drawing::CircleKind_FULL;
+ xProp->setPropertyValue( C2U( UNO_NAME_CIRCKIND )
+ , uno::makeAny( eKind ) );
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ return xShape;
+}
+
+uno::Reference< drawing::XShape >
ShapeFactory::createLine3D( const uno::Reference< drawing::XShapes >& xTarget
, const drawing::PolyPolygonShape3D& rPoints
, const VLineProperties& rLineProperties )
diff --git a/chart2/source/view/main/Stripe.cxx b/chart2/source/view/main/Stripe.cxx
index 67b2396682aa..cb35e0e010b9 100644
--- a/chart2/source/view/main/Stripe.cxx
+++ b/chart2/source/view/main/Stripe.cxx
@@ -161,7 +161,7 @@ uno::Any Stripe::getNormalsPolygon() const
return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) );
}
-uno::Any Stripe::getTexturePolygon() const
+uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const
{
drawing::PolyPolygonShape3D aPP;
@@ -181,21 +181,42 @@ uno::Any Stripe::getTexturePolygon() const
double* pInnerSequenceY = pOuterSequenceY->getArray();
double* pInnerSequenceZ = pOuterSequenceZ->getArray();
- *pInnerSequenceX++ = 0.0;
- *pInnerSequenceY++ = 0.0;
- *pInnerSequenceZ++ = 0.0;
+ if( !bRotatedTexture )
+ {
+ *pInnerSequenceX++ = 0.0;
+ *pInnerSequenceY++ = 0.0;
+ *pInnerSequenceZ++ = 0.0;
+
+ *pInnerSequenceX++ = 1.0;
+ *pInnerSequenceY++ = 0.0;
+ *pInnerSequenceZ++ = 0.0;
- *pInnerSequenceX++ = 1.0;
- *pInnerSequenceY++ = 0.0;
- *pInnerSequenceZ++ = 0.0;
+ *pInnerSequenceX++ = 1.0;
+ *pInnerSequenceY++ = 1.0;
+ *pInnerSequenceZ++ = 0.0;
- *pInnerSequenceX++ = 1.0;
- *pInnerSequenceY++ = 1.0;
- *pInnerSequenceZ++ = 0.0;
+ *pInnerSequenceX++ = 0.0;
+ *pInnerSequenceY++ = 1.0;
+ *pInnerSequenceZ++ = 0.0;
+ }
+ else
+ {
+ *pInnerSequenceX++ = 1.0;
+ *pInnerSequenceY++ = 0.0;
+ *pInnerSequenceZ++ = 0.0;
- *pInnerSequenceX++ = 0.0;
- *pInnerSequenceY++ = 1.0;
- *pInnerSequenceZ++ = 0.0;
+ *pInnerSequenceX++ = 1.0;
+ *pInnerSequenceY++ = 1.0;
+ *pInnerSequenceZ++ = 0.0;
+
+ *pInnerSequenceX++ = 0.0;
+ *pInnerSequenceY++ = 1.0;
+ *pInnerSequenceZ++ = 0.0;
+
+ *pInnerSequenceX++ = 0.0;
+ *pInnerSequenceY++ = 0.0;
+ *pInnerSequenceZ++ = 0.0;
+ }
return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) );
}
diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx
index f3e8f4a19739..d2456110b79b 100644
--- a/chart2/source/view/main/VDataSeries.cxx
+++ b/chart2/source/view/main/VDataSeries.cxx
@@ -124,20 +124,35 @@ struct lcl_LessXOfPoint
}
};
-void lcl_clearIfTextIsContained( VDataSequence& rData, const uno::Reference<data::XDataSequence>& xDataSequence )
+void lcl_clearIfNoValuesButTextIsContained( VDataSequence& rData, const uno::Reference<data::XDataSequence>& xDataSequence )
{
+ //#i71686#, #i101968#, #i102428#
+ sal_Int32 nCount = rData.Doubles.getLength();
+ for( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ if( !::rtl::math::isNan( rData.Doubles[i] ) )
+ return;
+ }
+ //no double value is countained
+ //is there any text?
uno::Sequence< rtl::OUString > aStrings( DataSequenceToStringSequence( xDataSequence ) );
- for( sal_Int32 i = 0; i < rData.Doubles.getLength(); ++i )
+ sal_Int32 nTextCount = aStrings.getLength();
+ for( sal_Int32 j = 0; j < nTextCount; ++j )
{
- if( ::rtl::math::isNan( rData.Doubles[i] ) )
+ if( aStrings[j].getLength() )
{
- if( i < aStrings.getLength() && aStrings[i].getLength() )
- {
- rData.clear();
- break;
- }
+ rData.clear();
+ return;
}
}
+ //no content at all
+}
+
+void lcl_maybeReplaceNanWithZero( double& rfValue, sal_Int32 nMissingValueTreatment )
+{
+ if( nMissingValueTreatment == ::com::sun::star::chart::MissingValueTreatment::USE_ZERO
+ && ::rtl::math::isNan(rfValue) || ::rtl::math::isInf(rfValue) )
+ rfValue = 0.0;
}
}
@@ -163,6 +178,8 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
, m_aValues_Y_Max()
, m_aValues_Y_First()
, m_aValues_Y_Last()
+ , m_aValues_Bubble_Size()
+ , m_pValueSequenceForDataLabelNumberFormatDetection(&m_aValues_Y)
, m_fYMeanValue(1.0)
@@ -193,6 +210,7 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
, m_apSymbolProperties_InvisibleSymbolForSelection(NULL)
, m_nCurrentAttributedPoint(-1)
, m_nMissingValueTreatment(::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP)
+ , m_bAllowPercentValueInDataLabel(false)
{
::rtl::math::setNan( & m_fYMeanValue );
@@ -218,7 +236,7 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
if( aRole.equals(C2U("values-x")) )
{
m_aValues_X.init( xDataSequence );
- lcl_clearIfTextIsContained( m_aValues_X, xDataSequence );
+ lcl_clearIfNoValuesButTextIsContained( m_aValues_X, xDataSequence );
}
else if( aRole.equals(C2U("values-y")) )
m_aValues_Y.init( xDataSequence );
@@ -230,7 +248,8 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
m_aValues_Y_First.init( xDataSequence );
else if( aRole.equals(C2U("values-last")) )
m_aValues_Y_Last.init( xDataSequence );
- //@todo assign the other roles (+ error for unknown?)
+ else if( aRole.equals(C2U("values-size")) )
+ m_aValues_Bubble_Size.init( xDataSequence );
}
catch( uno::Exception& e )
{
@@ -242,13 +261,15 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
//determine the point count
m_nPointCount = m_aValues_Y.getLength();
{
+ if( m_nPointCount < m_aValues_Bubble_Size.getLength() )
+ m_nPointCount = m_aValues_Bubble_Size.getLength();
if( m_nPointCount < m_aValues_Y_Min.getLength() )
m_nPointCount = m_aValues_Y_Min.getLength();
- if( m_nPointCount < m_aValues_Y_Max.getLength() )
+ if( m_nPointCount < m_aValues_Y_Max.getLength() )
m_nPointCount = m_aValues_Y_Max.getLength();
- if( m_nPointCount < m_aValues_Y_First.getLength() )
+ if( m_nPointCount < m_aValues_Y_First.getLength() )
m_nPointCount = m_aValues_Y_First.getLength();
- if( m_nPointCount < m_aValues_Y_Last.getLength() )
+ if( m_nPointCount < m_aValues_Y_Last.getLength() )
m_nPointCount = m_aValues_Y_Last.getLength();
}
@@ -331,6 +352,7 @@ void VDataSeries::releaseShapes()
void VDataSeries::setCategoryXAxis()
{
m_aValues_X.clear();
+ m_bAllowPercentValueInDataLabel = true;
}
void VDataSeries::setGlobalSeriesIndex( sal_Int32 nGlobalSeriesIndex )
@@ -445,27 +467,48 @@ sal_Int32 VDataSeries::getTotalPointCount() const
return m_nPointCount;
}
-double VDataSeries::getX( sal_Int32 index ) const
+double VDataSeries::getXValue( sal_Int32 index ) const
{
+ double fRet = 0.0;
if(m_aValues_X.is())
{
if( 0<=index && index<m_aValues_X.getLength() )
- return m_aValues_X.Doubles[index];
+ fRet = m_aValues_X.Doubles[index];
+ else
+ ::rtl::math::setNan( &fRet );
}
else
{
// #i70133# always return correct X position - needed for short data series
if( 0<=index /*&& index < m_nPointCount*/ )
- return index+1;//first category (index 0) matches with real number 1.0
+ fRet = index+1;//first category (index 0) matches with real number 1.0
+ else
+ ::rtl::math::setNan( &fRet );
}
- double fNan;
- ::rtl::math::setNan( & fNan );
- return fNan;
+ lcl_maybeReplaceNanWithZero( fRet, getMissingValueTreatment() );
+ return fRet;
}
-double VDataSeries::getY( sal_Int32 index ) const
+double VDataSeries::getYValue( sal_Int32 index ) const
{
- return m_aValues_Y.getValue( index );
+ double fRet = 0.0;
+ if(m_aValues_Y.is())
+ {
+ if( 0<=index && index<m_aValues_Y.getLength() )
+ fRet = m_aValues_Y.Doubles[index];
+ else
+ ::rtl::math::setNan( &fRet );
+ }
+ else
+ {
+ // #i70133# always return correct X position - needed for short data series
+ if( 0<=index /*&& index < m_nPointCount*/ )
+ fRet = index+1;//first category (index 0) matches with real number 1.0
+ else
+ ::rtl::math::setNan( &fRet );
+ }
+ lcl_maybeReplaceNanWithZero( fRet, getMissingValueTreatment() );
+ return fRet;
}
double VDataSeries::getY_Min( sal_Int32 index ) const
@@ -484,6 +527,10 @@ double VDataSeries::getY_Last( sal_Int32 index ) const
{
return m_aValues_Y_Last.getValue( index );
}
+double VDataSeries::getBubble_Size( sal_Int32 index ) const
+{
+ return m_aValues_Bubble_Size.getValue( index );
+}
bool VDataSeries::hasExplicitNumberFormat( sal_Int32 nPointIndex, bool bForPercentage ) const
{
@@ -504,9 +551,37 @@ sal_Int32 VDataSeries::getExplicitNumberFormat( sal_Int32 nPointIndex, bool bFor
xPointProp->getPropertyValue(aPropName) >>= nNumberFormat;
return nNumberFormat;
}
+void VDataSeries::setRoleOfSequenceForDataLabelNumberFormatDetection( const rtl::OUString& rRole )
+{
+ if( rRole.equals(C2U("values-y")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y;
+ else if( rRole.equals(C2U("values-size")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Bubble_Size;
+ else if( rRole.equals(C2U("values-min")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Min;
+ else if( rRole.equals(C2U("values-max")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Max;
+ else if( rRole.equals(C2U("values-first")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_First;
+ else if( rRole.equals(C2U("values-last")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Last;
+ else if( rRole.equals(C2U("values-x")) )
+ m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_X;
+}
+bool VDataSeries::shouldLabelNumberFormatKeyBeDetectedFromYAxis() const
+{
+ if( m_pValueSequenceForDataLabelNumberFormatDetection == &m_aValues_Bubble_Size )
+ return false;
+ else if( m_pValueSequenceForDataLabelNumberFormatDetection == &m_aValues_X )
+ return false;
+ return true;
+}
sal_Int32 VDataSeries::detectNumberFormatKey( sal_Int32 index ) const
{
- return m_aValues_Y.detectNumberFormatKey( index );
+ sal_Int32 nRet = 0;
+ if( m_pValueSequenceForDataLabelNumberFormatDetection )
+ nRet = m_pValueSequenceForDataLabelNumberFormatDetection->detectNumberFormatKey( index );
+ return nRet;
}
sal_Int32 VDataSeries::getLabelPlacement( sal_Int32 nPointIndex, const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Bool bSwapXAndY ) const
@@ -545,7 +620,7 @@ sal_Int32 VDataSeries::getLabelPlacement( sal_Int32 nPointIndex, const uno::Refe
double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
{
- double fY = getY( index );
+ double fY = getYValue( index );
double fY_Min = getY_Min( index );
double fY_Max = getY_Max( index );
double fY_First = getY_First( index );
@@ -572,7 +647,7 @@ double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
double VDataSeries::getMaximumofAllDifferentYValues( sal_Int32 index ) const
{
- double fY = getY( index );
+ double fY = getYValue( index );
double fY_Min = getY_Min( index );
double fY_Max = getY_Max( index );
double fY_First = getY_First( index );
@@ -612,6 +687,14 @@ uno::Sequence< double > VDataSeries::getAllX() const
uno::Sequence< double > VDataSeries::getAllY() const
{
+ if(!m_aValues_Y.is() && !m_aValues_Y.getLength() && m_nPointCount)
+ {
+ //init y values from indexes
+ //first y-value (index 0) matches with real number 1.0
+ m_aValues_Y.Doubles.realloc( m_nPointCount );
+ for(sal_Int32 nN=m_aValues_Y.getLength();nN--;)
+ m_aValues_Y.Doubles[nN] = nN+1;
+ }
return m_aValues_Y.Doubles;
}
@@ -806,6 +889,11 @@ DataPointLabel* VDataSeries::getDataPointLabel( sal_Int32 index ) const
m_apLabel_Series = getDataPointLabelFromPropertySet( this->getPropertiesOfPoint( index ) );
pRet = m_apLabel_Series.get();
}
+ if( !m_bAllowPercentValueInDataLabel )
+ {
+ if( pRet )
+ pRet->ShowNumberInPercent = false;
+ }
return pRet;
}
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 7ba5aa9c1f32..f1859be15fcf 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -791,12 +791,14 @@ template< typename T > void PutInOrder( T& nStart, T& nEnd )
bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
SCTAB nDefTab, ScRefAddress& rRefAddress,
- const ScAddress::Details& rDetails = ScAddress::detailsOOOa1);
+ const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
+ ScAddress::ExternalInfo* pExtInfo = NULL );
bool ConvertDoubleRef(ScDocument* pDoc, const String& rRefString,
SCTAB nDefTab, ScRefAddress& rStartRefAddress,
ScRefAddress& rEndRefAddress,
- const ScAddress::Details& rDetails = ScAddress::detailsOOOa1);
+ const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
+ ScAddress::ExternalInfo* pExtInfo = NULL );
/// append alpha representation of column to buffer
SC_DLLPUBLIC void ScColToAlpha( rtl::OUStringBuffer& rBuffer, SCCOL nCol);
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 2d4bba295547..10de035abf7c 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -102,7 +102,7 @@ public:
/** Returns a clone of this cell, clones cell note and caption object too
(unless SC_CLONECELL_NOCAPTION flag is set). Broadcaster will not be cloned. */
- ScBaseCell* CloneWithNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
+ ScBaseCell* CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
/** Due to the fact that ScBaseCell does not have a vtable, this function
deletes the cell by calling the appropriate d'tor of the derived class. */
@@ -387,13 +387,23 @@ public:
inline USHORT GetSeenInIteration() const { return nSeenInIteration; }
BOOL HasOneReference( ScRange& r ) const;
+ /* Checks if the formula contains reference list that can be
+ expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
+ reference list is not required to be sorted (i.e. A3;A1;A2 is
+ still recognized as A1:A3), but no overlapping is allowed.
+ If one reference is recognized, the rRange is filled.
+
+ It is similar to HasOneReference(), but more general.
+ */
+ bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
BOOL HasRelNameReference() const;
BOOL HasColRowName() const;
void UpdateReference(UpdateRefMode eUpdateRefMode,
const ScRange& r,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
- ScDocument* pUndoDoc = NULL );
+ ScDocument* pUndoDoc = NULL,
+ const ScAddress* pUndoCellPos = NULL );
void TransposeReference();
void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx
index e73869489ebc..2dd0bd6cc16e 100644
--- a/sc/inc/cellsuno.hxx
+++ b/sc/inc/cellsuno.hxx
@@ -629,9 +629,10 @@ protected:
throw(::com::sun::star::lang::IndexOutOfBoundsException,
::com::sun::star::uno::RuntimeException);
- void SetArrayFormula_Impl( const rtl::OUString& aFormula,
- const formula::FormulaGrammar::Grammar eGrammar )
- throw(::com::sun::star::uno::RuntimeException);
+ void SetArrayFormula_Impl( const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp,
+ const formula::FormulaGrammar::Grammar eGrammar )
+ throw(::com::sun::star::uno::RuntimeException);
public:
ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR);
@@ -650,7 +651,8 @@ public:
virtual void RefChanged();
// via getImplementation()
- virtual void SetArrayFormulaWithGrammar( const ::rtl::OUString& aFormula,
+ virtual void SetArrayFormulaWithGrammar( const ::rtl::OUString& rFormula,
+ const ::rtl::OUString& rFormulaNmsp,
const formula::FormulaGrammar::Grammar )
throw(::com::sun::star::uno::RuntimeException);
@@ -869,7 +871,7 @@ public:
void SetFormulaResultString( const ::rtl::OUString& rResult );
void SetFormulaResultDouble( double fResult );
void SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
- const formula::FormulaGrammar::Grammar );
+ const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar );
const ScAddress& GetPosition() const { return aCellPos; }
// XText
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index c026e0cb5cf9..76293479660c 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -311,9 +311,11 @@ private:
const CharClass* pCharClass; // which character classification is used for parseAnyToken
USHORT mnPredetectedReference; // reference when reading ODF, 0 (none), 1 (single) or 2 (double)
SCsTAB nMaxTab; // last sheet in document
+ sal_Int32 mnRangeOpPosInSymbol; // if and where a range operator is in symbol
const Convention *pConv;
bool mbCloseBrackets; // whether to close open brackets automatically, default TRUE
bool mbExtendedErrorDetection;
+ bool mbRewind; // whether symbol is to be rewound to some step during lexical analysis
BOOL NextNewToken(bool bInArray = false);
@@ -352,14 +354,14 @@ public:
const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO );
static BOOL EnQuote( String& rStr );
+ sal_Unicode GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const;
// Check if it is a valid english function name
bool IsEnglishSymbol( const String& rName );
//! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
- void SetCompileForFAP( BOOL bVal )
- { bCompileForFAP = bVal; bIgnoreErrors = bVal; }
+ // #i101512# SetCompileForFAP is in formula::FormulaCompiler
void SetAutoCorrection( BOOL bVal )
{ bAutoCorrect = bVal; bIgnoreErrors = bVal; }
void SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; }
@@ -394,6 +396,8 @@ public:
maExternalLinks = rLinks;
}
+ void CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp );
+
void SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; }
BOOL IsCorrected() { return bCorrected; }
@@ -401,12 +405,13 @@ public:
// Use convention from this->aPos by default
ScTokenArray* CompileString( const String& rFormula );
+ ScTokenArray* CompileString( const String& rFormula, const String& rFormulaNmsp );
const ScDocument* GetDoc() const { return pDoc; }
const ScAddress& GetPos() const { return aPos; }
- void MoveRelWrap();
- static void MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc,
- const ScAddress& rPos );
+ void MoveRelWrap( SCCOL nMaxCol, SCROW nMaxRow );
+ static void MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc, const ScAddress& rPos,
+ SCCOL nMaxCol, SCROW nMaxRow );
BOOL UpdateNameReference( UpdateRefMode eUpdateRefMode,
const ScRange&,
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 42a030b8e809..edb0f9371788 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -84,7 +84,10 @@ class SC_DLLPUBLIC ScConditionEntry
double nVal2;
String aStrVal1; // eingegeben oder berechnet
String aStrVal2;
- formula::FormulaGrammar::Grammar eTempGrammar; // grammar to be used on (re)compilation, e.g. in XML import
+ String aStrNmsp1; // namespace to be used on (re)compilation, e.g. in XML import
+ String aStrNmsp2; // namespace to be used on (re)compilation, e.g. in XML import
+ formula::FormulaGrammar::Grammar eTempGrammar1; // grammar to be used on (re)compilation, e.g. in XML import
+ formula::FormulaGrammar::Grammar eTempGrammar2; // grammar to be used on (re)compilation, e.g. in XML import
BOOL bIsStr1; // um auch leere Strings zu erkennen
BOOL bIsStr2;
ScTokenArray* pFormula1; // eingegebene Formel
@@ -101,7 +104,10 @@ class SC_DLLPUBLIC ScConditionEntry
void MakeCells( const ScAddress& rPos );
void Compile( const String& rExpr1, const String& rExpr2,
- const formula::FormulaGrammar::Grammar eGrammar, BOOL bTextToReal );
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ formula::FormulaGrammar::Grammar eGrammar1,
+ formula::FormulaGrammar::Grammar eGrammar2,
+ BOOL bTextToReal );
void Interpret( const ScAddress& rPos );
BOOL IsValid( double nArg ) const;
@@ -111,7 +117,9 @@ public:
ScConditionEntry( ScConditionMode eOper,
const String& rExpr1, const String& rExpr2,
ScDocument* pDocument, const ScAddress& rPos,
- const formula::FormulaGrammar::Grammar eGrammar );
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ formula::FormulaGrammar::Grammar eGrammar1,
+ formula::FormulaGrammar::Grammar eGrammar2 );
ScConditionEntry( ScConditionMode eOper,
const ScTokenArray* pArr1, const ScTokenArray* pArr2,
ScDocument* pDocument, const ScAddress& rPos );
@@ -174,7 +182,10 @@ public:
const String& rExpr1, const String& rExpr2,
ScDocument* pDocument, const ScAddress& rPos,
const String& rStyle,
- const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT );
+ const String& rExprNmsp1 = EMPTY_STRING,
+ const String& rExprNmsp2 = EMPTY_STRING,
+ formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
+ formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
ScCondFormatEntry( ScConditionMode eOper,
const ScTokenArray* pArr1, const ScTokenArray* pArr2,
ScDocument* pDocument, const ScAddress& rPos,
diff --git a/sc/inc/datauno.hxx b/sc/inc/datauno.hxx
index 405d49e2a6b2..a93bfc341573 100644
--- a/sc/inc/datauno.hxx
+++ b/sc/inc/datauno.hxx
@@ -50,6 +50,7 @@
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase4.hxx>
@@ -340,8 +341,9 @@ public:
// to uno, all three look the same
-class ScFilterDescriptorBase : public cppu::WeakImplHelper3<
+class ScFilterDescriptorBase : public cppu::WeakImplHelper4<
com::sun::star::sheet::XSheetFilterDescriptor,
+ com::sun::star::sheet::XSheetFilterDescriptor2,
com::sun::star::beans::XPropertySet,
com::sun::star::lang::XServiceInfo >,
public SfxListener
@@ -368,6 +370,13 @@ public:
::com::sun::star::sheet::TableFilterField >& aFilterFields )
throw(::com::sun::star::uno::RuntimeException);
+ // XSheetFilterDescriptor2
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField2 > SAL_CALL
+ getFilterFields2() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setFilterFields2( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::sheet::TableFilterField2 >& aFilterFields )
+ throw(::com::sun::star::uno::RuntimeException);
+
// XPropertySet
virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
SAL_CALL getPropertySetInfo()
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 66f52fa5c2a8..c8d3751a7aaf 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -90,6 +90,7 @@ class ScDBData;
class ScDetOpData;
class ScDetOpList;
class ScDocOptions;
+class ScDocProtection;
class ScDocumentPool;
class ScDrawLayer;
class ScExtDocOptions;
@@ -108,6 +109,7 @@ class ScRangeName;
class ScStyleSheet;
class ScStyleSheetPool;
class ScTable;
+class ScTableProtection;
class ScTokenArray;
class ScValidationData;
class ScValidationDataList;
@@ -137,6 +139,7 @@ class ScTemporaryChartLock;
class ScLookupCache;
struct ScLookupCacheMapImpl;
class SfxUndoManager;
+class ScFormulaParserPool;
namespace com { namespace sun { namespace star {
namespace lang {
@@ -286,9 +289,14 @@ private:
ScFieldEditEngine* pCacheFieldEditEngine;
- com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
+ ::std::auto_ptr<ScDocProtection> pDocProtection;
::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
+
+ // mutable for lazy construction
+ mutable ::std::auto_ptr< ScFormulaParserPool >
+ mxFormulaParserPool; /// Pool for all external formula parsers used by this document.
+
String aDocName; // opt: Dokumentname
ScRangePairListRef xColNameRanges;
ScRangePairListRef xRowNameRanges;
@@ -350,7 +358,6 @@ private:
ScLkUpdMode eLinkMode;
- BOOL bProtected;
BOOL bAutoCalc; // Automatisch Berechnen
BOOL bAutoCalcShellDisabled; // in/von/fuer ScDocShell disabled
// ob noch ForcedFormulas berechnet werden muessen,
@@ -530,13 +537,14 @@ public:
SC_DLLPUBLIC inline SCTAB GetTableCount() const { return nMaxTableNumber; }
SvNumberFormatterIndexTable* GetFormatExchangeList() const { return pFormatExchangeList; }
- SC_DLLPUBLIC void SetDocProtection( BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
- SC_DLLPUBLIC void SetTabProtection( SCTAB nTab, BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
+ SC_DLLPUBLIC ScDocProtection* GetDocProtection() const;
+ SC_DLLPUBLIC void SetDocProtection(const ScDocProtection* pProtect);
SC_DLLPUBLIC BOOL IsDocProtected() const;
BOOL IsDocEditable() const;
SC_DLLPUBLIC BOOL IsTabProtected( SCTAB nTab ) const;
- const com::sun::star::uno::Sequence <sal_Int8>& GetDocPassword() const;
- const com::sun::star::uno::Sequence <sal_Int8>& GetTabPassword( SCTAB nTab ) const;
+ SC_DLLPUBLIC ScTableProtection* GetTabProtection( SCTAB nTab ) const;
+ SC_DLLPUBLIC void SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect);
+ void CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest);
void LockTable(SCTAB nTab);
void UnlockTable(SCTAB nTab);
@@ -578,6 +586,8 @@ public:
SC_DLLPUBLIC void TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos);
SC_DLLPUBLIC void SetVisible( SCTAB nTab, BOOL bVisible );
SC_DLLPUBLIC BOOL IsVisible( SCTAB nTab ) const;
+ BOOL IsPendingRowHeights( SCTAB nTab ) const;
+ void SetPendingRowHeights( SCTAB nTab, BOOL bSet );
SC_DLLPUBLIC void SetLayoutRTL( SCTAB nTab, BOOL bRTL );
SC_DLLPUBLIC BOOL IsLayoutRTL( SCTAB nTab ) const;
BOOL IsNegativePage( SCTAB nTab ) const;
@@ -591,7 +601,7 @@ public:
SC_DLLPUBLIC BOOL IsActiveScenario( SCTAB nTab ) const;
SC_DLLPUBLIC void SetActiveScenario( SCTAB nTab, BOOL bActive ); // nur fuer Undo etc.
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const;
- formula::FormulaGrammar::Grammar GetGrammar() const;
+ SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const;
void SetGrammar( formula::FormulaGrammar::Grammar eGram );
SC_DLLPUBLIC BYTE GetLinkMode( SCTAB nTab ) const;
BOOL IsLinked( SCTAB nTab ) const;
@@ -615,6 +625,10 @@ public:
void MarkUsedExternalReferences();
bool MarkUsedExternalReferences( ScTokenArray & rArr );
+ /** Returns the pool containing external formula parsers. Creates the pool
+ on first call. */
+ ScFormulaParserPool& GetFormulaParserPool() const;
+
BOOL HasDdeLinks() const;
BOOL HasAreaLinks() const;
void UpdateExternalRefLinks();
@@ -772,6 +786,12 @@ public:
SC_DLLPUBLIC ScPostIt* GetOrCreateNote( const ScAddress& rPos );
/** Deletes the note at the passed cell address. */
void DeleteNote( const ScAddress& rPos );
+ /** Creates the captions of all uninitialized cell notes in the specified sheet.
+ @param bForced True = always create all captions, false = skip when Undo is disabled. */
+ void InitializeNoteCaptions( SCTAB nTab, bool bForced = false );
+ /** Creates the captions of all uninitialized cell notes in all sheets.
+ @param bForced True = always create all captions, false = skip when Undo is disabled. */
+ void InitializeAllNoteCaptions( bool bForced = false );
BOOL ExtendMergeSel( SCCOL nStartCol, SCROW nStartRow,
SCCOL& rEndCol, SCROW& rEndRow, const ScMarkData& rMark,
@@ -889,22 +909,26 @@ public:
BOOL InsertRow( SCCOL nStartCol, SCTAB nStartTab,
SCCOL nEndCol, SCTAB nEndTab,
- SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL );
+ SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL,
+ const ScMarkData* pTabMark = NULL );
SC_DLLPUBLIC BOOL InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
void DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
SCCOL nEndCol, SCTAB nEndTab,
SCROW nStartRow, SCSIZE nSize,
- ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
+ ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL,
+ const ScMarkData* pTabMark = NULL );
void DeleteRow( const ScRange& rRange,
ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
BOOL InsertCol( SCROW nStartRow, SCTAB nStartTab,
SCROW nEndRow, SCTAB nEndTab,
- SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL );
+ SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL,
+ const ScMarkData* pTabMark = NULL );
SC_DLLPUBLIC BOOL InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc = NULL );
void DeleteCol( SCROW nStartRow, SCTAB nStartTab,
SCROW nEndRow, SCTAB nEndTab,
SCCOL nStartCol, SCSIZE nSize,
- ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
+ ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL,
+ const ScMarkData* pTabMark = NULL );
void DeleteCol( const ScRange& rRange,
ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
@@ -1234,7 +1258,8 @@ public:
BOOL bShrink );
void UpdateAllRowHeights( OutputDevice* pDev,
double nPPTX, double nPPTY,
- const Fraction& rZoomX, const Fraction& rZoomY );
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ const ScMarkData* pTabMark = NULL );
long GetNeededSize( SCCOL nCol, SCROW nRow, SCTAB nTab,
OutputDevice* pDev,
double nPPTX, double nPPTY,
@@ -1471,7 +1496,8 @@ public:
private:
-//UNUSED2008-05 void SetAutoFilterFlags();
+ ScDocument(const ScDocument& r); // disabled with no definition
+
void FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
SCCOL nX1, SCCOL nX2 ) const;
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index 3f960e446611..defe627dd812 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -125,7 +125,7 @@ public:
ScDocument* GetDocument() const;
SfxObjectShell* GetEmbeddedObject() const;
- void UpdateAllRowHeights();
+ void UpdateAllRowHeights( const ScMarkData* pTabMark = NULL );
ScDrawLayer* MakeDrawLayer();
void BeforeXMLLoading();
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 5f3dfe9eb489..cffe735f287a 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -126,7 +126,8 @@ public:
void InvalidateData();
void InvalidateSource();
- void Output();
+
+ void Output( const ScAddress& rPos );
ScRange GetNewOutputRange( BOOL& rOverflow );
const ScRange GetOutputRangeByType( sal_Int32 nType );
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index cf1c151fa05d..a0492d82a2f3 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -115,11 +115,7 @@ private:
void MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
SCsCOL nDx,SCsROW nDy );
- void RecalcPos( SdrObject* pObj,
- const ScDrawObjData& rData,
- const ScAddress& rOldStart,
- const ScAddress& rOldEnd,
- bool bNegativePage );
+ void RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage );
public:
ScDrawLayer( ScDocument* pDocument, const String& rName );
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 07c8a6a6697f..9b12dba52f1f 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -132,15 +132,27 @@ public:
class Table
{
public:
+
+ enum ReferencedFlag
+ {
+ UNREFERENCED,
+ REFERENCED_MARKED, // marked as referenced during store to file
+ REFERENCED_PERMANENT // permanently marked, e.g. from within interpreter
+ };
+
Table();
~Table();
SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0);
TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const;
bool hasRow( SCROW nRow ) const;
- /// A temporary state used only during store to file.
- bool isReferenced() const;
+ /** Set/clear referenced status flag only if current status is not
+ REFERENCED_PERMANENT. */
void setReferenced( bool bReferenced );
+ /// Unconditionally set the reference status flag.
+ void setReferencedFlag( ReferencedFlag eFlag );
+ ReferencedFlag getReferencedFlag() const;
+ bool isReferenced() const;
/// Obtain a sorted vector of rows.
void getAllRows(::std::vector<SCROW>& rRows) const;
/// Obtain a sorted vector of columns.
@@ -148,8 +160,8 @@ public:
void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
private:
- RowsDataType maRows;
- bool mbReferenced;
+ RowsDataType maRows;
+ ReferencedFlag meReferenced;
};
typedef ::boost::shared_ptr<Table> TableTypeRef;
@@ -219,9 +231,16 @@ public:
* Set a table as referenced, used only during store-to-file.
* @returns <TRUE/> if ALL tables of ALL documents are marked.
*/
- bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName );
+ bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets, bool bPermanent );
void setAllCacheTableReferencedStati( bool bReferenced );
bool areAllCacheTablesReferenced() const;
+
+ /**
+ * Set a table as permanently referenced, to be called if not in
+ * mark-during-store-to-file cycle.
+ */
+ void setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
+
private:
struct ReferencedStatus
{
@@ -497,10 +516,16 @@ public:
* Set a table as referenced, used only during store-to-file.
* @returns <TRUE/> if ALL tables of ALL external documents are marked.
*/
- bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName );
+ bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
void setAllCacheTableReferencedStati( bool bReferenced );
/**
+ * Set a table as permanently referenced, to be called if not in
+ * mark-during-store-to-file cycle.
+ */
+ void setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets );
+
+ /**
* @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called,
* <FALSE/> if setAllCacheTableReferencedStati(true) was called.
*/
diff --git a/sc/inc/fmtuno.hxx b/sc/inc/fmtuno.hxx
index ba4e02041faa..6005a849fb0f 100644
--- a/sc/inc/fmtuno.hxx
+++ b/sc/inc/fmtuno.hxx
@@ -32,7 +32,8 @@
#define SC_FMTUNO_HXX
#include "address.hxx"
-#include "formula/grammar.hxx"
+#include "conditio.hxx"
+#include <formula/grammar.hxx>
#include <tools/list.hxx>
#include <svtools/itemprop.hxx>
#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
@@ -61,16 +62,19 @@ struct ScCondFormatEntryItem
{
::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > maTokens1;
::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > maTokens2;
- String maExpr1;
- String maExpr2;
- String maPosStr; // formula position as text
- String maStyle; // display name as stored in ScStyleSheet
- ScAddress maPos;
- formula::FormulaGrammar::Grammar meGrammar; // grammar used with maExpr1 and maExpr2
- USHORT mnMode; // stores enum ScConditionMode
+ String maExpr1;
+ String maExpr2;
+ String maExprNmsp1;
+ String maExprNmsp2;
+ String maPosStr; // formula position as text
+ String maStyle; // display name as stored in ScStyleSheet
+ ScAddress maPos;
+ formula::FormulaGrammar::Grammar meGrammar1; // grammar used with maExpr1
+ formula::FormulaGrammar::Grammar meGrammar2; // grammar used with maExpr2
+ ScConditionMode meMode;
// Make sure the grammar is initialized for API calls.
- ScCondFormatEntryItem() : meGrammar( formula::FormulaGrammar::GRAM_UNSPECIFIED ) {}
+ ScCondFormatEntryItem();
};
class ScTableConditionalFormat : public cppu::WeakImplHelper5<
@@ -89,11 +93,11 @@ private:
ScTableConditionalFormat(); // disable
public:
ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
- const formula::FormulaGrammar::Grammar eGrammar);
+ formula::FormulaGrammar::Grammar eGrammar);
virtual ~ScTableConditionalFormat();
- void FillFormat( ScConditionalFormat& rFormat,
- ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar ) const;
+ void FillFormat( ScConditionalFormat& rFormat, ScDocument* pDoc,
+ formula::FormulaGrammar::Grammar eGrammar) const;
void DataChanged();
// XSheetConditionalEntries
@@ -211,7 +215,10 @@ private:
USHORT nMode; // enum ScConditionMode
String aExpr1;
String aExpr2;
- formula::FormulaGrammar::Grammar meGrammar; // grammar used with aExpr1 and aExpr2
+ String maExprNmsp1;
+ String maExprNmsp2;
+ formula::FormulaGrammar::Grammar meGrammar1; // grammar used with aExpr1 and aExpr2
+ formula::FormulaGrammar::Grammar meGrammar2; // grammar used with aExpr1 and aExpr2
::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > aTokens1;
::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > aTokens2;
ScAddress aSrcPos;
diff --git a/sc/inc/formulaparserpool.hxx b/sc/inc/formulaparserpool.hxx
new file mode 100644
index 000000000000..af6b0ed3ebf1
--- /dev/null
+++ b/sc/inc/formulaparserpool.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulaparserpool.hxx,v $
+ * $Revision: 1.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_FORMULAPARSERPOOL_HXX
+#define SC_FORMULAPARSERPOOL_HXX
+
+#include <hash_map>
+#include <com/sun/star/sheet/XFormulaParser.hpp>
+
+class ScDocument;
+
+// ============================================================================
+
+/** Stores the used instances of the FilterFormulaParser service
+ implementations, mapped by the formula namespace they support. */
+class ScFormulaParserPool
+{
+public:
+ explicit ScFormulaParserPool( const ScDocument& rDoc );
+ ~ScFormulaParserPool();
+
+ /** Returns true, if a formula parser is registered for the passed namespace. */
+ bool hasFormulaParser( const ::rtl::OUString& rNamespace );
+
+ /** Returns the formula parser that is registered for the passed namespace. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >
+ getFormulaParser( const ::rtl::OUString& rNamespace );
+
+private:
+ typedef ::std::hash_map<
+ ::rtl::OUString,
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >,
+ ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > ParserMap;
+
+ const ScDocument& mrDoc;
+ ParserMap maParsers;
+};
+
+// ============================================================================
+
+#endif
+
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 45df07deaf6c..e329f477d824 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -238,6 +238,7 @@ const USHORT IDF_ATTRIB = IDF_HARDATTR | IDF_STYLES;
const USHORT IDF_CONTENTS = IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_NOTE | IDF_FORMULA;
const USHORT IDF_ALL = IDF_CONTENTS | IDF_ATTRIB | IDF_OBJECTS;
const USHORT IDF_NOCAPTIONS = 0x0200; /// Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
+const USHORT IDF_ADDNOTES = 0x0400; /// Internal use only (copy from clip): do not delete existing cell contents when pasting notes.
/// Copy flags for auto/series fill functions: do not touch notes and drawing objects.
const USHORT IDF_AUTOFILL = IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS);
@@ -727,7 +728,13 @@ enum ScQueryOp
SC_TOPVAL,
SC_BOTVAL,
SC_TOPPERC,
- SC_BOTPERC
+ SC_BOTPERC,
+ SC_CONTAINS,
+ SC_DOES_NOT_CONTAIN,
+ SC_BEGINS_WITH,
+ SC_DOES_NOT_BEGIN_WITH,
+ SC_ENDS_WITH,
+ SC_DOES_NOT_END_WITH
};
// -----------------------------------------------------------------------
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index db35cb50969e..97d77dc06fc5 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -84,7 +84,6 @@
#define STR_MSSG_PASTEFROMCLIP_0 48
#define STR_MSSG_PASTEFROMCLIP_1 49
#define STR_MSSG_MOVEBLOCKTO_0 50
-#define STR_MSSG_APPLYPATTLINES_0 51
#define STR_MSSG_INSERTCELLS_0 52
#define STR_MSSG_DELETECELLS_0 53
#define STR_MSSG_MERGECELLS_0 54
diff --git a/sc/inc/pch/precompiled_sc.hxx b/sc/inc/pch/precompiled_sc.hxx
index db4e87d3cdb7..b905bb19db03 100644
--- a/sc/inc/pch/precompiled_sc.hxx
+++ b/sc/inc/pch/precompiled_sc.hxx
@@ -36,6 +36,7 @@
#include <algorithm>
#include <assert.h>
+#include <deque>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
@@ -49,6 +50,8 @@
#include <new>
#include <cfloat>
+#include <boost/bind.hpp>
+
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b3dpolygon.hxx>
#include <basegfx/polygon/b3dpolypolygon.hxx>
diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx
index 979fea65264f..ee90a71375b4 100644
--- a/sc/inc/postit.hxx
+++ b/sc/inc/postit.hxx
@@ -31,30 +31,42 @@
#ifndef SC_POSTIT_HXX
#define SC_POSTIT_HXX
+#include <boost/shared_ptr.hpp>
+#include <rtl/ustring.hxx>
#include <tools/gen.hxx>
#include "address.hxx"
#include "scdllapi.h"
class EditTextObject;
+class OutlinerParaObject;
class SdrCaptionObj;
class SdrPage;
class SfxItemSet;
class ScDocument;
+struct ScCaptionInitData;
// ============================================================================
+/** Internal data for a cell annotation. */
struct SC_DLLPUBLIC ScNoteData
{
- String maDate; /// Creation date of the note.
- String maAuthor; /// Author of the note.
+ typedef ::boost::shared_ptr< ScCaptionInitData > ScCaptionInitDataRef;
+
+ ::rtl::OUString maDate; /// Creation date of the note.
+ ::rtl::OUString maAuthor; /// Author of the note.
+ ScCaptionInitDataRef mxInitData; /// Initial data for invisible notes without SdrObject.
SdrCaptionObj* mpCaption; /// Drawing object representing the cell note.
bool mbShown; /// True = note is visible.
explicit ScNoteData( bool bShown = false );
+ ~ScNoteData();
};
// ============================================================================
+/** An additional class held by an ScBaseCell instance containing all
+ information for a cell annotation.
+ */
class SC_DLLPUBLIC ScPostIt
{
public:
@@ -65,76 +77,98 @@ public:
/** Copy constructor. Clones the note and its caption to a new document. */
explicit ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote );
- /** Creates a note from the passed note data with existing caption object. */
- explicit ScPostIt( ScDocument& rDoc, const ScNoteData& rNoteData );
+ /** Creates a note from the passed note data with existing caption object.
+
+ @param bAlwaysCreateCaption Instead of a pointer to an existing
+ caption object, the passed note data structure may contain a
+ reference to an ScCaptionInitData structure containing information
+ about how to construct a missing caption object. If TRUE is passed,
+ the caption drawing object will be created immediately from that
+ data. If FALSE is passed and the note is not visible, it will
+ continue to cache that data until the caption object is requested.
+ */
+ explicit ScPostIt(
+ ScDocument& rDoc, const ScAddress& rPos,
+ const ScNoteData& rNoteData, bool bAlwaysCreateCaption );
/** Removes the caption object from drawing layer, if this note is its owner. */
~ScPostIt();
- /** Returns the data struct containing note settings. */
+ /** Clones this note and its caption object, if specified.
+
+ @param bCloneCaption If TRUE is passed, clones the caption object and
+ inserts it into the drawing layer of the destination document. If
+ FALSE is passed, the cloned note will refer to the old caption
+ object (used e.g. in Undo documents to restore the pointer to the
+ existing caption object).
+ */
+ ScPostIt* Clone(
+ const ScAddress& rOwnPos,
+ ScDocument& rDestDoc, const ScAddress& rDestPos,
+ bool bCloneCaption ) const;
+
+ /** Returns the data struct containing all note settings. */
inline const ScNoteData& GetNoteData() const { return maNoteData; }
/** Returns the creation date of this note. */
- inline const String& GetDate() const { return maNoteData.maDate; }
+ inline const ::rtl::OUString& GetDate() const { return maNoteData.maDate; }
/** Sets a new creation date for this note. */
- inline void SetDate( const String& rDate ) { maNoteData.maDate = rDate; }
+ inline void SetDate( const ::rtl::OUString& rDate ) { maNoteData.maDate = rDate; }
/** Returns the author date of this note. */
- inline const String& GetAuthor() const { return maNoteData.maAuthor; }
+ inline const ::rtl::OUString& GetAuthor() const { return maNoteData.maAuthor; }
/** Sets a new author date for this note. */
- inline void SetAuthor( const String& rAuthor ) { maNoteData.maAuthor = rAuthor; }
+ inline void SetAuthor( const ::rtl::OUString& rAuthor ) { maNoteData.maAuthor = rAuthor; }
/** Sets date and author from system settings. */
void AutoStamp();
+ /** Returns the pointer to the current outliner object, or null. */
+ const OutlinerParaObject* GetOutlinerObject() const;
/** Returns the pointer to the current edit text object, or null. */
const EditTextObject* GetEditTextObject() const;
+
/** Returns the caption text of this note. */
- String GetText() const;
+ ::rtl::OUString GetText() const;
/** Returns true, if the caption text of this note contains line breaks. */
bool HasMultiLineText() const;
/** Changes the caption text of this note. All text formatting will be lost. */
- void SetText( const String& rText );
+ void SetText( const ScAddress& rPos, const ::rtl::OUString& rText );
- /** Returns the note caption object. */
+ /** Returns an existing note caption object. returns null, if the note
+ contains initial caption data needed to construct a caption object. */
inline SdrCaptionObj* GetCaption() const { return maNoteData.mpCaption; }
- /** Returns and forgets the note caption object. */
- inline SdrCaptionObj* ForgetCaption() { SdrCaptionObj* pCapt = maNoteData.mpCaption; maNoteData.mpCaption = 0; return pCapt; }
+ /** Returns the caption object of this note. Creates the caption object, if
+ the note contains initial caption data instead of the caption. */
+ SdrCaptionObj* GetOrCreateCaption( const ScAddress& rPos ) const;
+ /** Forgets the pointer to the note caption object. */
+ void ForgetCaption();
/** Shows or hides the note caption object. */
- void ShowCaption( bool bShow = true );
- /** Hides the note caption object. */
- inline void HideCaption() { ShowCaption( false ); }
+ void ShowCaption( const ScAddress& rPos, bool bShow = true );
/** Returns true, if the caption object is visible. */
inline bool IsCaptionShown() const { return maNoteData.mbShown; }
/** Shows or hides the caption temporarily (does not change internal visibility state). */
- void ShowCaptionTemp( bool bShow = true );
- /** Hides caption if it has been shown temporarily (does not change internal visibility state). */
- inline void HideCaptionTemp() { ShowCaptionTemp( false ); }
+ void ShowCaptionTemp( const ScAddress& rPos, bool bShow = true );
/** Updates caption position according to position of the passed cell. */
void UpdateCaptionPos( const ScAddress& rPos );
- /** Sets caption itemset to default items. */
- void SetCaptionDefaultItems();
- /** Updates caption itemset according to the passed item set while removing shadow items. */
- void SetCaptionItems( const SfxItemSet& rItemSet );
-
private:
ScPostIt( const ScPostIt& );
ScPostIt& operator=( const ScPostIt& );
+ /** Creates the caption object from initial caption data if existing. */
+ void CreateCaptionFromInitData( const ScAddress& rPos ) const;
/** Creates a new caption object at the passed cell position, clones passed existing caption. */
void CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption = 0 );
/** Removes the caption object from the drawing layer, if this note is its owner. */
void RemoveCaption();
- /** Updates caption visibility. */
- void UpdateCaptionLayer( bool bShow );
private:
ScDocument& mrDoc; /// Parent document containing the note.
- ScNoteData maNoteData; /// Note data with pointer to caption object.
+ mutable ScNoteData maNoteData; /// Note data with pointer to caption object.
};
// ============================================================================
@@ -142,24 +176,89 @@ private:
class SC_DLLPUBLIC ScNoteUtil
{
public:
- /** Clones the note and its caption object, if specified.
- @param bCloneCaption True = clones the caption object and inserts it
- into the drawing layer of the destination document. False = the
- cloned note will refer to the old caption object. */
- static ScPostIt* CloneNote( ScDocument& rDoc, const ScAddress& rPos,
- const ScPostIt& rNote, bool bCloneCaption );
-
/** Tries to update the position of note caption objects in the specified range. */
static void UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange );
/** Creates and returns a caption object for a temporary caption. */
static SdrCaptionObj* CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos,
- SdrPage& rPage, const String& rUserText,
+ SdrPage& rDrawPage, const ::rtl::OUString& rUserText,
const Rectangle& rVisRect, bool bTailFront );
- /** Creates a cell note based on the passed string and inserts it into the document. */
- static ScPostIt* CreateNoteFromString( ScDocument& rDoc, const ScAddress& rPos,
- const String& rNoteText, bool bShown );
+ /** Creates a cell note using the passed caption drawing object.
+
+ This function is used in import filters to reuse the imported drawing
+ object as note caption object.
+
+ @param rCaption The drawing object for the cell note. This object MUST
+ be inserted into the document at the correct drawing page already.
+
+ @return Pointer to the new cell note object if insertion was
+ successful (i.e. the passed cell position was valid), null
+ otherwise. The Calc document is the owner of the note object. The
+ passed item set and outliner object are deleted automatically if
+ creation of the note was not successful.
+ */
+ static ScPostIt* CreateNoteFromCaption(
+ ScDocument& rDoc, const ScAddress& rPos,
+ SdrCaptionObj& rCaption, bool bShown );
+
+ /** Creates a cell note based on the passed caption object data.
+
+ This function is used in import filters to use an existing imported
+ item set and outliner object to create a note caption object. For
+ performance reasons, it is possible to specify that the caption drawing
+ object for the cell note is not created yet but the note caches the
+ passed data needed to create the caption object on demand (see
+ parameter bAlwaysCreateCaption).
+
+ @param pItemSet Pointer to an item set on heap memory containing all
+ formatting attributes of the caption object. This function takes
+ ownership of the passed item set.
+
+ @param pOutlinerObj Pointer to an outliner object on heap memory
+ containing (formatted) text for the caption object. This function
+ takes ownership of the passed outliner object.
+
+ @param rCaptionRect The absolute position and size of the caption
+ object. The rectangle may be empty, in this case the default
+ position and size is used.
+
+ @param bAlwaysCreateCaption If TRUE is passed, the caption drawing
+ object will be created immediately. If FALSE is passed, the caption
+ drawing object will not be created if the note is not visible
+ (bShown = FALSE), but the cell note will cache the passed data.
+ MUST be set to FALSE outside of import filter implementations!
+
+ @return Pointer to the new cell note object if insertion was
+ successful (i.e. the passed cell position was valid), null
+ otherwise. The Calc document is the owner of the note object.
+ */
+ static ScPostIt* CreateNoteFromObjectData(
+ ScDocument& rDoc, const ScAddress& rPos,
+ SfxItemSet* pItemSet, OutlinerParaObject* pOutlinerObj,
+ const Rectangle& rCaptionRect, bool bShown,
+ bool bAlwaysCreateCaption );
+
+ /** Creates a cell note based on the passed string and inserts it into the
+ document.
+
+ @param rNoteText The text used to create the note caption object. Must
+ not be empty.
+
+ @param bAlwaysCreateCaption If TRUE is passed, the caption drawing
+ object will be created immediately. If FALSE is passed, the caption
+ drawing object will not be created if the note is not visible
+ (bShown = FALSE), but the cell note will cache the passed data.
+ MUST be set to FALSE outside of import filter implementations!
+
+ @return Pointer to the new cell note object if insertion was
+ successful (i.e. the passed cell position was valid), null
+ otherwise. The Calc document is the owner of the note object.
+ */
+ static ScPostIt* CreateNoteFromString(
+ ScDocument& rDoc, const ScAddress& rPos,
+ const ::rtl::OUString& rNoteText, bool bShown,
+ bool bAlwaysCreateCaption );
};
// ============================================================================
diff --git a/sc/inc/progress.hxx b/sc/inc/progress.hxx
index b30cf6d9dc70..c7706c2bc26b 100644
--- a/sc/inc/progress.hxx
+++ b/sc/inc/progress.hxx
@@ -36,6 +36,17 @@
class ScDocument;
+/*
+ * #i102566
+ * Drawing a progress bar update is not cheap, so if we draw it on every
+ * percentage change of 200 calculations we get one progress draw per 2
+ * calculations which is slower than doing the calculations themselves. So as a
+ * rough guide only do an update per MIN_NO_CODES_PER_PROGRESS_UPDATE
+ * calculations
+ */
+#define MIN_NO_CODES_PER_PROGRESS_UPDATE 100
+
+
class SC_DLLPUBLIC ScProgress
{
private:
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 962aff918e7b..002adf9b77ce 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -81,6 +81,11 @@ private:
USHORT nIndex;
BOOL bModified; // wird bei UpdateReference gesetzt/geloescht
+ // max row and column to use for wrapping of references. If -1 use the
+ // application's default.
+ SCROW mnMaxRow;
+ SCCOL mnMaxCol;
+
friend class ScRangeName;
ScRangeData( USHORT nIndex );
public:
@@ -153,6 +158,11 @@ public:
static void MakeValidName( String& rName );
SC_DLLPUBLIC static BOOL IsNameValid( const String& rName, ScDocument* pDoc );
+
+ SC_DLLPUBLIC void SetMaxRow(SCROW nRow);
+ SCROW GetMaxRow() const;
+ SC_DLLPUBLIC void SetMaxCol(SCCOL nCol);
+ SCCOL GetMaxCol() const;
};
inline BOOL ScRangeData::HasType( RangeType nType ) const
diff --git a/sc/inc/refdata.hxx b/sc/inc/refdata.hxx
index 6a51d66fdc07..12f29943fce0 100644
--- a/sc/inc/refdata.hxx
+++ b/sc/inc/refdata.hxx
@@ -109,6 +109,8 @@ struct SC_DLLPUBLIC ScSingleRefData // Single reference (one address) int
inline BOOL IsRelName() const { return Flags.bRelName; }
inline BOOL Valid() const;
+ /// In external references nTab is -1
+ inline bool ValidExternal() const;
void SmartRelAbs( const ScAddress& rPos );
void CalcRelFromAbs( const ScAddress& rPos );
@@ -147,6 +149,13 @@ inline BOOL ScSingleRefData::Valid() const
nTab >= 0 && nTab <= MAXTAB;
}
+inline bool ScSingleRefData::ValidExternal() const
+{
+ return nCol >= 0 && nCol <= MAXCOL &&
+ nRow >= 0 && nRow <= MAXROW &&
+ nTab == -1;
+}
+
struct ScComplexRefData // Complex reference (a range) into the sheet
{
@@ -181,6 +190,10 @@ struct ScComplexRefData // Complex reference (a range) into the sheet
{ return Ref1.IsDeleted() || Ref2.IsDeleted(); }
inline BOOL Valid() const
{ return Ref1.Valid() && Ref2.Valid(); }
+ /** In external references nTab is -1 for the start tab and -1 for the end
+ tab if one sheet, or >=0 if more than one sheets. */
+ inline bool ValidExternal() const;
+
/// Absolute references have to be up-to-date when calling this!
void PutInOrder();
inline BOOL operator==( const ScComplexRefData& r ) const
@@ -192,4 +205,12 @@ struct ScComplexRefData // Complex reference (a range) into the sheet
ScComplexRefData& Extend( const ScComplexRefData & rRef, const ScAddress & rPos );
};
+inline bool ScComplexRefData::ValidExternal() const
+{
+ return Ref1.ValidExternal() &&
+ Ref2.nCol >= 0 && Ref2.nCol <= MAXCOL &&
+ Ref2.nRow >= 0 && Ref2.nRow <= MAXROW &&
+ Ref2.nTab >= Ref1.nTab;
+}
+
#endif
diff --git a/sc/inc/reftokenhelper.hxx b/sc/inc/reftokenhelper.hxx
index 37f82337f654..5b06450ea56f 100644
--- a/sc/inc/reftokenhelper.hxx
+++ b/sc/inc/reftokenhelper.hxx
@@ -56,7 +56,8 @@ public:
* The source range may consist of multiple ranges separated by ';'s.
*/
static void compileRangeRepresentation(
- ::std::vector<ScSharedTokenRef>& rRefTokens, const ::rtl::OUString& rRangeStr, ScDocument* pDoc);
+ ::std::vector<ScSharedTokenRef>& rRefTokens, const ::rtl::OUString& rRangeStr, ScDocument* pDoc,
+ ::formula::FormulaGrammar::Grammar eGrammar = ::formula::FormulaGrammar::GRAM_ENGLISH);
static bool getRangeFromToken(ScRange& rRange, const ScSharedTokenRef& pToken, bool bExternal = false);
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 35b6a403816d..8fb6b929337b 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -1630,8 +1630,13 @@
#define RID_SCDLG_CONFLICTS (SC_DIALOGS_START + 145)
#define RID_SCDLG_SHAREDOCUMENT (SC_DIALOGS_START + 146)
+#define RID_SCDLG_SORT_WARNING (SC_DIALOGS_START + 147)
+#define RID_SCDLG_TABPROTECTION (SC_DIALOGS_START + 148)
+#define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 149)
+#define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 150)
+#define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151)
-#define SC_DIALOGS_END (SC_DIALOGS_START + 150)
+#define SC_DIALOGS_END (SC_DIALOGS_START + 152)
#ifndef STD_MASKCOLOR
#define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx
index ec381ce2ef07..f9895ff15ebb 100644
--- a/sc/inc/scabstdlg.hxx
+++ b/sc/inc/scabstdlg.hxx
@@ -314,6 +314,7 @@ public:
const String& rStrLabel,
int nId,
BOOL bColDefault = TRUE ) = 0;
+ virtual VclAbstractDialog * CreateScSortWarningDlg ( Window* pParent, const String& rExtendText, const String& rCurrentText, int nId ) = 0; //add for ScSortWarningDlg
virtual AbstractScDataPilotDatabaseDlg * CreateScDataPilotDatabaseDlg (Window* pParent ,int nId ) = 0; //add for ScDataPilotDatabaseDlg
virtual AbstractScDataPilotSourceTypeDlg * CreateScDataPilotSourceTypeDlg ( Window* pParent, BOOL bEnableExternal, int nId ) = 0; //add for ScDataPilotSourceTypeDlg
diff --git a/sc/inc/scextopt.hxx b/sc/inc/scextopt.hxx
index 4b3f763b4e8c..fdf05430cc69 100644
--- a/sc/inc/scextopt.hxx
+++ b/sc/inc/scextopt.hxx
@@ -46,8 +46,6 @@ struct ScExtDocSettings
double mfTabBarWidth; /// Width of the tabbar, relative to frame window width (0.0 ... 1.0).
sal_uInt32 mnLinkCnt; /// Recursive counter for loading external documents.
SCTAB mnDisplTab; /// Index of displayed sheet.
- bool mbWinProtected; /// true = Window properties are protected.
- bool mbEncrypted; /// true = Imported file was encrypted.
explicit ScExtDocSettings();
};
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e738ff5fbdb8..8b2227d48dbb 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -32,6 +32,8 @@
#define SC_TABLE_HXX
#include <vector>
+#include <memory>
+#include <utility>
#include <tools/gen.hxx>
#include <tools/color.hxx>
#include <com/sun/star/uno/Sequence.hxx>
@@ -39,6 +41,8 @@
#include "sortparam.hxx"
#include "compressedarray.hxx"
+#include <memory>
+
namespace utl {
class SearchParam;
class TextSearch;
@@ -65,6 +69,7 @@ class ScRangeList;
class ScSortInfoArray;
class ScStyleSheet;
class ScTableLink;
+class ScTableProtection;
class ScUserListData;
class ScIndexMap;
struct RowInfo;
@@ -77,6 +82,10 @@ class ScTable
{
private:
typedef ::std::vector< ScRange > ScRangeVec;
+ typedef ::std::pair< SCCOL, SCROW > ScAddress2D;
+ typedef ::std::vector< ScAddress2D > ScAddress2DVec;
+ typedef ::std::auto_ptr< ScAddress2DVec > ScAddress2DVecPtr;
+
// Daten pro Tabelle ------------------
ScColumn aCol[MAXCOLCOUNT];
@@ -102,8 +111,7 @@ private:
SCROW nRepeatStartY;
SCROW nRepeatEndY;
- BOOL bProtected;
- com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
+ ::std::auto_ptr<ScTableProtection> pTabProtection;
USHORT* pColWidth;
ScSummableCompressedArray< SCROW, USHORT>* pRowHeight;
@@ -119,6 +127,7 @@ private:
// interne Verwaltung ------------------
BOOL bVisible;
+ BOOL bPendingRowHeights;
SCTAB nTab;
USHORT nRecalcLvl; // Rekursionslevel Size-Recalc
@@ -128,6 +137,8 @@ private:
mutable String aUpperName; // #i62977# filled only on demand, reset in SetName
+ ScAddress2DVecPtr mxUninitNotes;
+
// SortierParameter um den Stackbedarf von Quicksort zu Minimieren
ScSortParam aSortParam;
CollatorWrapper* pSortCollator;
@@ -182,6 +193,9 @@ public:
BOOL IsVisible() const { return bVisible; }
void SetVisible( BOOL bVis );
+ BOOL IsPendingRowHeights() const { return bPendingRowHeights; }
+ void SetPendingRowHeights( BOOL bSet );
+
BOOL IsLayoutRTL() const { return bLayoutRTL; }
BOOL IsLoadingRTL() const { return bLoadingRTL; }
void SetLayoutRTL( BOOL bSet );
@@ -218,10 +232,9 @@ public:
void SetPageStyle( const String& rName );
void PageStyleModified( const String& rNewName );
- BOOL IsProtected() const { return bProtected; }
- const com::sun::star::uno::Sequence<sal_Int8>& GetPassword() const { return aProtectPass; }
- void SetProtection( BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd )
- { bProtected = bProtect; aProtectPass = rPasswd; }
+ BOOL IsProtected() const;
+ void SetProtection(const ScTableProtection* pProtect);
+ ScTableProtection* GetProtection();
Size GetPageSize() const;
void SetPageSize( const Size& rSize );
@@ -254,16 +267,28 @@ public:
void GetString( SCCOL nCol, SCROW nRow, String& rString );
void GetInputString( SCCOL nCol, SCROW nRow, String& rString );
double GetValue( const ScAddress& rPos ) const
- { return aCol[rPos.Col()].GetValue( rPos.Row() ); }
+ {
+ return ValidColRow(rPos.Col(),rPos.Row()) ?
+ aCol[rPos.Col()].GetValue( rPos.Row() ) :
+ 0.0;
+ }
double GetValue( SCCOL nCol, SCROW nRow );
void GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
BOOL bAsciiExport = FALSE );
CellType GetCellType( const ScAddress& rPos ) const
- { return aCol[rPos.Col()].GetCellType( rPos.Row() ); }
+ {
+ return ValidColRow(rPos.Col(),rPos.Row()) ?
+ aCol[rPos.Col()].GetCellType( rPos.Row() ) :
+ CELLTYPE_NONE;
+ }
CellType GetCellType( SCCOL nCol, SCROW nRow ) const;
ScBaseCell* GetCell( const ScAddress& rPos ) const
- { return aCol[rPos.Col()].GetCell( rPos.Row() ); }
+ {
+ return ValidColRow(rPos.Col(),rPos.Row()) ?
+ aCol[rPos.Col()].GetCell( rPos.Row() ) :
+ NULL;
+ }
ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const;
void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
@@ -276,6 +301,9 @@ public:
ScPostIt* ReleaseNote( SCCOL nCol, SCROW nRow );
/** Deletes the note at the passed cell address. */
void DeleteNote( SCCOL nCol, SCROW nRow );
+ /** Creates the captions of all uninitialized cell notes.
+ @param bForced True = always create all captions, false = skip when Undo is disabled. */
+ void InitializeNoteCaptions( bool bForced = false );
BOOL TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize );
void InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize );
@@ -362,7 +390,11 @@ public:
SCCOL nEndCol, SCROW nEndRow ) const;
USHORT GetErrCode( const ScAddress& rPos ) const
- { return aCol[rPos.Col()].GetErrCode( rPos.Row() ); }
+ {
+ return ValidColRow(rPos.Col(),rPos.Row()) ?
+ aCol[rPos.Col()].GetErrCode( rPos.Row() ) :
+ 0;
+ }
//UNUSED2008-05 USHORT GetErrCode( SCCOL nCol, SCROW nRow ) const;
void ResetChanged( const ScRange& rRange );
@@ -438,7 +470,11 @@ public:
const ScPatternAttr* GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const;
ULONG GetNumberFormat( const ScAddress& rPos ) const
- { return aCol[rPos.Col()].GetNumberFormat( rPos.Row() ); }
+ {
+ return ValidColRow(rPos.Col(),rPos.Row()) ?
+ aCol[rPos.Col()].GetNumberFormat( rPos.Row() ) :
+ 0;
+ }
ULONG GetNumberFormat( SCCOL nCol, SCROW nRow ) const;
void MergeSelectionPattern( ScMergePatternState& rState,
const ScMarkData& rMark, BOOL bDeep ) const;
@@ -457,7 +493,10 @@ public:
void ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr );
void ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScPatternAttr& rAttr );
void SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr, BOOL bPutToPool = FALSE )
- { aCol[rPos.Col()].SetPattern( rPos.Row(), rAttr, bPutToPool ); }
+ {
+ if (ValidColRow(rPos.Col(),rPos.Row()))
+ aCol[rPos.Col()].SetPattern( rPos.Row(), rAttr, bPutToPool );
+ }
void SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr, BOOL bPutToPool = FALSE );
void ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
const ScPatternAttr& rPattern, short nNewType );
diff --git a/sc/inc/tabprotection.hxx b/sc/inc/tabprotection.hxx
new file mode 100644
index 000000000000..a11355833e4c
--- /dev/null
+++ b/sc/inc/tabprotection.hxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tabprotection.hxx,v $
+ * $Revision: 1.1.4.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_TAB_PROTECTION_HXX
+#define SC_TAB_PROTECTION_HXX
+
+#include "sal/types.h"
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "global.hxx"
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#define ENABLE_SHEET_PROTECTION 0
+
+class ScDocument;
+class ScTableProtectionImpl;
+
+enum ScPasswordHash
+{
+ PASSHASH_OOO = 0,
+ PASSHASH_XL
+};
+
+class ScPassHashHelper
+{
+public:
+ /** Check for the compatibility of all password hashes. If there is at
+ least one hash that needs to be regenerated, it returns true. If all
+ hash values are compatible with the specified hash type, then it
+ returns false. */
+ static bool needsPassHashRegen(const ScDocument& rDoc, ScPasswordHash eHash);
+
+private:
+ ScPassHashHelper();
+ ~ScPassHashHelper();
+};
+
+// ============================================================================
+
+class SAL_NO_VTABLE ScPassHashProtectable
+{
+public:
+ virtual ~ScPassHashProtectable() = 0;
+
+ virtual bool isProtected() const = 0;
+ virtual bool isProtectedWithPass() const = 0;
+ virtual void setProtected(bool bProtected) = 0;
+
+ virtual bool isPasswordEmpty() const = 0;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const = 0;
+ virtual void setPassword(const String& aPassText) = 0;
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const = 0;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO) = 0;
+ virtual bool verifyPassword(const String& aPassText) const = 0;
+};
+
+// ============================================================================
+
+class SC_DLLPUBLIC ScDocProtection : public ScPassHashProtectable
+{
+public:
+ enum Option
+ {
+ STRUCTURE = 0,
+ WINDOWS,
+ CONTENT,
+ NONE // last item - used to resize the vector
+ };
+
+ explicit ScDocProtection();
+ explicit ScDocProtection(const ScDocProtection& r);
+ virtual ~ScDocProtection();
+
+ virtual bool isProtected() const;
+ virtual bool isProtectedWithPass() const;
+ virtual void setProtected(bool bProtected);
+
+ virtual bool isPasswordEmpty() const;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPassword(const String& aPassText);
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO);
+ virtual bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(Option eOption) const;
+ void setOption(Option eOption, bool bEnabled);
+
+private:
+ ::boost::shared_ptr<ScTableProtectionImpl> mpImpl;
+};
+
+// ============================================================================
+
+/** sheet protection state container
+
+ This class stores sheet's protection state: 1) whether the protection
+ is on, 2) password and/or password hash, and 3) any associated
+ protection options. This class is also used as a protection state
+ container for the undo/redo stack, in which case the password, hash and
+ the options need to be preserved even when the protection flag is
+ off. */
+class SC_DLLPUBLIC ScTableProtection : public ScPassHashProtectable
+{
+public:
+ enum Option
+ {
+ AUTOFILTER = 0,
+ DELETE_COLUMNS,
+ DELETE_ROWS,
+ FORMAT_CELLS,
+ FORMAT_COLUMNS,
+ FORMAT_ROWS,
+ INSERT_COLUMNS,
+ INSERT_HYPERLINKS,
+ INSERT_ROWS,
+ OBJECTS,
+ PIVOT_TABLES,
+ SCENARIOS,
+ SELECT_LOCKED_CELLS,
+ SELECT_UNLOCKED_CELLS,
+ SHEET,
+ SORT,
+ NONE // last item - used to resize the vector
+ };
+
+ explicit ScTableProtection();
+ explicit ScTableProtection(const ScTableProtection& r);
+ virtual ~ScTableProtection();
+
+ virtual bool isProtected() const;
+ virtual bool isProtectedWithPass() const;
+ virtual void setProtected(bool bProtected);
+
+ virtual bool isPasswordEmpty() const;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPassword(const String& aPassText);
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO);
+ virtual bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(Option eOption) const;
+ void setOption(Option eOption, bool bEnabled);
+
+private:
+ ::boost::shared_ptr<ScTableProtectionImpl> mpImpl;
+};
+
+
+#endif
diff --git a/sc/inc/tokenuno.hxx b/sc/inc/tokenuno.hxx
index abb9d1d06a22..bcd3435668be 100644
--- a/sc/inc/tokenuno.hxx
+++ b/sc/inc/tokenuno.hxx
@@ -31,15 +31,14 @@
#ifndef SC_TOKENUNO_HXX
#define SC_TOKENUNO_HXX
-#include <svtools/lstner.hxx>
-#include <com/sun/star/sheet/FormulaToken.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/sheet/XFormulaParser.hpp>
-#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/sheet/XFormulaParser.hpp>
#include <cppuhelper/implbase3.hxx>
+#include <svtools/lstner.hxx>
#include <formula/FormulaOpCodeMapperObj.hxx>
#include "address.hxx"
#include "compiler.hxx"
@@ -47,6 +46,7 @@
class ScTokenArray;
class ScDocShell;
+// ============================================================================
class ScTokenConversion
{
@@ -61,6 +61,7 @@ public:
const ScTokenArray& rTokenArray );
};
+// ============================================================================
class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
::com::sun::star::sheet::XFormulaParser,
@@ -73,7 +74,6 @@ private:
::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
ScCompiler::OpCodeMapPtr mxOpCodeMap;
ScDocShell* mpDocShell;
- ScAddress maRefPos;
sal_Int16 mnConv;
bool mbEnglish;
bool mbIgnoreSpaces;
@@ -89,10 +89,12 @@ public:
// XFormulaParser
virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL parseFormula(
- const ::rtl::OUString& aFormula )
+ const ::rtl::OUString& aFormula,
+ const ::com::sun::star::table::CellAddress& rReferencePos )
throw (::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL printFormula( const ::com::sun::star::uno::Sequence<
- ::com::sun::star::sheet::FormulaToken >& aTokens )
+ ::com::sun::star::sheet::FormulaToken >& aTokens,
+ const ::com::sun::star::table::CellAddress& rReferencePos )
throw (::com::sun::star::uno::RuntimeException);
// XPropertySet
@@ -145,11 +147,15 @@ public:
throw(::com::sun::star::uno::RuntimeException);
};
+// ============================================================================
+
class ScFormulaOpCodeMapperObj : public formula::FormulaOpCodeMapperObj
{
public:
ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler);
};
+// ============================================================================
+
#endif
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 367e7d7cfe35..010e420feb42 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -318,7 +318,10 @@
#define SC_UNONAME_FORMULA2 "Formula2"
#define SC_UNONAME_SOURCEPOS "SourcePosition"
#define SC_UNONAME_SOURCESTR "SourcePositionAsString" // only for use in XML filter
-#define SC_UNONAME_GRAMMAR "Grammar" // only for use in XML filter
+#define SC_UNONAME_FORMULANMSP1 "FormulaNamespace1" // only for use in XML filter
+#define SC_UNONAME_FORMULANMSP2 "FormulaNamespace2" // only for use in XML filter
+#define SC_UNONAME_GRAMMAR1 "Grammar1" // only for use in XML filter
+#define SC_UNONAME_GRAMMAR2 "Grammar2" // only for use in XML filter
#define SC_UNONAME_STYLENAME "StyleName"
// validation
@@ -599,7 +602,6 @@
// <--
// FormulaParser
-#define SC_UNO_REFERENCEPOS "ReferencePosition"
#define SC_UNO_COMPILEENGLISH "CompileEnglish"
#define SC_UNO_FORMULACONVENTION "FormulaConvention"
#define SC_UNO_IGNORELEADING "IgnoreLeadingSpaces"
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index d3588c366a7c..cea9c154f04a 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -93,7 +93,9 @@ public:
ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
const String& rExpr1, const String& rExpr2,
ScDocument* pDocument, const ScAddress& rPos,
- const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT );
+ const String& rExprNmsp1 = EMPTY_STRING, const String& rExprNmsp2 = EMPTY_STRING,
+ formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
+ formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
const ScTokenArray* pArr1, const ScTokenArray* pArr2,
ScDocument* pDocument, const ScAddress& rPos );
diff --git a/sc/prj/build.lst b/sc/prj/build.lst
index 066d2883d1f7..c893349232e7 100644
--- a/sc/prj/build.lst
+++ b/sc/prj/build.lst
@@ -1,4 +1,4 @@
-sc sc : oovbaapi svx stoc uui BOOST:boost formula oox NULL
+sc sc : l10n oovbaapi svx stoc uui BOOST:boost formula oox NULL
sc sc usr1 - all sc_mkout NULL
sc sc\inc nmake - all sc_inc NULL
sc sc\prj get - all sc_prj NULL
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index fc33c75306cc..00992cbf962a 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -2104,9 +2104,8 @@ void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
// im eingefuegten Bereich ist nichts zusammengefasst
}
- // Flags nicht duplizieren
- //! direkt am Pattern testen ??
- RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
+ // Don't duplicate the merge flags in the inserted row.
+ RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_ALL );
}
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index 75699e8b0a10..ff82d1fd362f 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -113,7 +113,7 @@ bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
DBG_ASSERT( pShell, "Missing DocShell :-/" );
if ( pShell )
- pShell->SetError( SCWARN_CORE_HARD_RECALC );
+ pShell->SetError( SCWARN_CORE_HARD_RECALC, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
pDoc->SetAutoCalc( FALSE );
pDoc->SetHardRecalcState( 2 );
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index c43e1eebc6cd..da2de0b68099 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -148,7 +148,7 @@ ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, const ScAddress&
return lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
}
-ScBaseCell* ScBaseCell::CloneWithNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
+ScBaseCell* ScBaseCell::CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
{
ScBaseCell* pNewCell = lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
if( mpNote )
@@ -156,7 +156,7 @@ ScBaseCell* ScBaseCell::CloneWithNote( ScDocument& rDestDoc, const ScAddress& rD
if( !pNewCell )
pNewCell = new ScNoteCell;
bool bCloneCaption = (nCloneFlags & SC_CLONECELL_NOCAPTION) == 0;
- pNewCell->TakeNote( ScNoteUtil::CloneNote( rDestDoc, rDestPos, *mpNote, bCloneCaption ) );
+ pNewCell->TakeNote( mpNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
}
return pNewCell;
}
@@ -1016,15 +1016,15 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
ScCompiler aComp( pDocument, aPos, *pCode);
aComp.SetGrammar(eTempGrammar);
- String aFormula;
- aComp.CreateStringFromTokenArray( aFormula );
+ String aFormula, aFormulaNmsp;
+ aComp.CreateStringFromXMLTokenArray( aFormula, aFormulaNmsp );
pDocument->DecXMLImportedFormulaCount( aFormula.Len() );
rProgress.SetStateCountDownOnPercent( pDocument->GetXMLImportedFormulaCount() );
// pCode darf fuer Abfragen noch nicht geloescht, muss aber leer sein
if ( pCode )
pCode->Clear();
ScTokenArray* pCodeOld = pCode;
- pCode = aComp.CompileString( aFormula );
+ pCode = aComp.CompileString( aFormula, aFormulaNmsp );
delete pCodeOld;
if( !pCode->GetCodeError() )
{
@@ -1701,7 +1701,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// Reschedule verlangsamt das ganze erheblich, nur bei Prozentaenderung ausfuehren
ScProgress::GetInterpretProgress()->SetStateCountDownOnPercent(
- pDocument->GetFormulaCodeInTree() );
+ pDocument->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE );
}
else
{
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 86c87c0445d8..a0e776458ca2 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -34,6 +34,11 @@
// INCLUDE ---------------------------------------------------------------
+#include <algorithm>
+#include <deque>
+
+#include <boost/bind.hpp>
+
#include <vcl/mapmod.hxx>
#include <svx/editobj.hxx>
#include <svx/editstat.hxx>
@@ -175,6 +180,223 @@ void ScEditCell::SetTextObject( const EditTextObject* pObject,
// ============================================================================
+namespace
+{
+
+using std::deque;
+
+typedef SCCOLROW(*DimensionSelector)(const ScSingleRefData&);
+
+
+static SCCOLROW lcl_GetCol(const ScSingleRefData& rData)
+{
+ return rData.nCol;
+}
+
+
+static SCCOLROW lcl_GetRow(const ScSingleRefData& rData)
+{
+ return rData.nRow;
+}
+
+
+static SCCOLROW lcl_GetTab(const ScSingleRefData& rData)
+{
+ return rData.nTab;
+}
+
+
+/** Check if both references span the same range in selected dimension.
+ */
+static bool
+lcl_checkRangeDimension(
+ const SingleDoubleRefProvider& rRef1,
+ const SingleDoubleRefProvider& rRef2,
+ const DimensionSelector aWhich)
+{
+ return
+ aWhich(rRef1.Ref1) == aWhich(rRef2.Ref1)
+ && aWhich(rRef1.Ref2) == aWhich(rRef2.Ref2);
+}
+
+
+static bool
+lcl_checkRangeDimensions(
+ const SingleDoubleRefProvider& rRef1,
+ const SingleDoubleRefProvider& rRef2,
+ bool& bCol, bool& bRow, bool& bTab)
+{
+ const bool bSameCols(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetCol));
+ const bool bSameRows(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetRow));
+ const bool bSameTabs(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetTab));
+
+ // Test if exactly two dimensions are equal
+ if (!(bSameCols ^ bSameRows ^ bSameTabs)
+ && (bSameCols || bSameRows || bSameTabs))
+ {
+ bCol = !bSameCols;
+ bRow = !bSameRows;
+ bTab = !bSameTabs;
+ return true;
+ }
+ return false;
+}
+
+
+/** Check if references in given reference list can possibly
+ form a range. To do that, two of their dimensions must be the same.
+ */
+static bool
+lcl_checkRangeDimensions(
+ const deque<ScToken*>::const_iterator aBegin,
+ const deque<ScToken*>::const_iterator aEnd,
+ bool& bCol, bool& bRow, bool& bTab)
+{
+ deque<ScToken*>::const_iterator aCur(aBegin);
+ ++aCur;
+ const SingleDoubleRefProvider aRef(**aBegin);
+ bool bOk(false);
+ {
+ const SingleDoubleRefProvider aRefCur(**aCur);
+ bOk = lcl_checkRangeDimensions(aRef, aRefCur, bCol, bRow, bTab);
+ }
+ while (bOk && aCur != aEnd)
+ {
+ const SingleDoubleRefProvider aRefCur(**aCur);
+ bool bColTmp(false);
+ bool bRowTmp(false);
+ bool bTabTmp(false);
+ bOk = lcl_checkRangeDimensions(aRef, aRefCur, bColTmp, bRowTmp, bTabTmp);
+ bOk = bOk && (bCol == bColTmp && bRow == bRowTmp && bTab == bTabTmp);
+ ++aCur;
+ }
+
+ if (bOk && aCur == aEnd)
+ {
+ bCol = bCol;
+ bRow = bRow;
+ bTab = bTab;
+ return true;
+ }
+ return false;
+}
+
+
+bool
+lcl_lessReferenceBy(
+ const ScToken* const pRef1, const ScToken* const pRef2,
+ const DimensionSelector aWhich)
+{
+ const SingleDoubleRefProvider rRef1(*pRef1);
+ const SingleDoubleRefProvider rRef2(*pRef2);
+ return aWhich(rRef1.Ref1) < aWhich(rRef2.Ref1);
+}
+
+
+/** Returns true if range denoted by token pRef2 starts immediately after
+ range denoted by token pRef1. Dimension, in which the comparison takes
+ place, is given by aWhich.
+ */
+bool
+lcl_isImmediatelyFollowing(
+ const ScToken* const pRef1, const ScToken* const pRef2,
+ const DimensionSelector aWhich)
+{
+ const SingleDoubleRefProvider rRef1(*pRef1);
+ const SingleDoubleRefProvider rRef2(*pRef2);
+ return aWhich(rRef2.Ref1) - aWhich(rRef1.Ref2) == 1;
+}
+
+
+static bool
+lcl_checkIfAdjacent(
+ const deque<ScToken*>& rReferences,
+ const DimensionSelector aWhich)
+{
+ typedef deque<ScToken*>::const_iterator Iter;
+ Iter aBegin(rReferences.begin());
+ Iter aEnd(rReferences.end());
+ Iter aBegin1(aBegin);
+ ++aBegin1, --aEnd;
+ return std::equal(
+ aBegin, aEnd, aBegin1,
+ boost::bind(lcl_isImmediatelyFollowing, _1, _2, aWhich));
+}
+
+
+static void
+lcl_fillRangeFromRefList(
+ const deque<ScToken*>& rReferences, ScRange& rRange)
+{
+ const ScSingleRefData aStart(
+ SingleDoubleRefProvider(*rReferences.front()).Ref1);
+ rRange.aStart.Set(aStart.nCol, aStart.nRow, aStart.nTab);
+ const ScSingleRefData aEnd(
+ SingleDoubleRefProvider(*rReferences.back()).Ref2);
+ rRange.aEnd.Set(aEnd.nCol, aEnd.nRow, aEnd.nTab);
+}
+
+
+static bool
+lcl_refListFormsOneRange(
+ const ScAddress& aPos, deque<ScToken*>& rReferences,
+ ScRange& rRange)
+{
+ std::for_each(
+ rReferences.begin(), rReferences.end(),
+ bind(&ScToken::CalcAbsIfRel, _1, aPos))
+ ;
+ if (rReferences.size() == 1) {
+ lcl_fillRangeFromRefList(rReferences, rRange);
+ return true;
+ }
+
+ bool bCell(false);
+ bool bRow(false);
+ bool bTab(false);
+ if (lcl_checkRangeDimensions(rReferences.begin(), rReferences.end(),
+ bCell, bRow, bTab))
+ {
+ DimensionSelector aWhich;
+ if (bCell)
+ {
+ aWhich = lcl_GetCol;
+ }
+ else if (bRow)
+ {
+ aWhich = lcl_GetRow;
+ }
+ else if (bTab)
+ {
+ aWhich = lcl_GetTab;
+ }
+ else
+ {
+ OSL_ENSURE(false, "lcl_checkRangeDimensions shouldn't allow that!");
+ aWhich = lcl_GetRow; // initialize to avoid warning
+ }
+ // Sort the references by start of range
+ std::sort(rReferences.begin(), rReferences.end(),
+ boost::bind(lcl_lessReferenceBy, _1, _2, aWhich));
+ if (lcl_checkIfAdjacent(rReferences, aWhich))
+ {
+ lcl_fillRangeFromRefList(rReferences, rRange);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool lcl_isReference(const FormulaToken& rToken)
+{
+ return
+ rToken.GetType() == svSingleRef ||
+ rToken.GetType() == svDoubleRef;
+}
+
+}
+
BOOL ScFormulaCell::IsEmpty()
{
if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
@@ -449,6 +671,52 @@ BOOL ScFormulaCell::HasOneReference( ScRange& r ) const
return FALSE;
}
+bool
+ScFormulaCell::HasRefListExpressibleAsOneReference(ScRange& rRange) const
+{
+ /* If there appears just one reference in the formula, it's the same
+ as HasOneReference(). If there are more of them, they can denote
+ one range if they are (sole) arguments of one function.
+ Union of these references must form one range and their
+ intersection must be empty set.
+ */
+ pCode->Reset();
+ // Get first reference, if any
+ ScToken* const pFirstReference(
+ dynamic_cast<ScToken*>(pCode->GetNextReferenceRPN()));
+ if (pFirstReference)
+ {
+ // Collect all consecutive references, starting by the one
+ // already found
+ std::deque<ScToken*> aReferences;
+ aReferences.push_back(pFirstReference);
+ FormulaToken* pToken(pCode->NextRPN());
+ FormulaToken* pFunction(0);
+ while (pToken)
+ {
+ if (lcl_isReference(*pToken))
+ {
+ aReferences.push_back(dynamic_cast<ScToken*>(pToken));
+ pToken = pCode->NextRPN();
+ }
+ else
+ {
+ if (pToken->IsFunction())
+ {
+ pFunction = pToken;
+ }
+ break;
+ }
+ }
+ if (pFunction && !pCode->GetNextReferenceRPN()
+ && (pFunction->GetParamCount() == aReferences.size()))
+ {
+ return lcl_refListFormsOneRange(aPos, aReferences, rRange);
+ }
+ }
+ return false;
+}
+
BOOL ScFormulaCell::HasRelNameReference() const
{
pCode->Reset();
@@ -472,7 +740,7 @@ BOOL ScFormulaCell::HasColRowName() const
void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
const ScRange& r,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
- ScDocument* pUndoDoc )
+ ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
{
SCCOL nCol1 = r.aStart.Col();
SCROW nRow1 = r.aStart.Row();
@@ -484,6 +752,8 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
SCROW nRow = aPos.Row();
SCTAB nTab = aPos.Tab();
ScAddress aUndoPos( aPos ); // position for undo cell in pUndoDoc
+ if ( pUndoCellPos )
+ aUndoPos = *pUndoCellPos;
ScAddress aOldPos( aPos );
// BOOL bPosChanged = FALSE; // ob diese Zelle bewegt wurde
BOOL bIsInsert = FALSE;
@@ -706,10 +976,15 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
// (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
// is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
- ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
- pOld, eTempGrammar, cMatrixFlag );
- pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
- pUndoDoc->PutCell( aUndoPos, pFCell );
+ // If there is already a formula cell in the undo document, don't overwrite it,
+ // the first (oldest) is the important cell.
+ if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
+ pOld, eTempGrammar, cMatrixFlag );
+ pFCell->aResult.SetToken( NULL); // to recognize it as changed later (Cut/Paste!)
+ pUndoDoc->PutCell( aUndoPos, pFCell );
+ }
}
bValChanged = FALSE;
if ( pRangeData )
@@ -792,7 +1067,7 @@ void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
pCode = new ScTokenArray( *pRangeData->GetCode() );
ScCompiler aComp2(pDocument, aPos, *pCode);
aComp2.SetGrammar(pDocument->GetGrammar());
- aComp2.MoveRelWrap();
+ aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
aComp2.UpdateInsertTab( nTable, FALSE );
// If the shared formula contained a named range/formula containing
// an absolute reference to a sheet, those have to be readjusted.
@@ -828,7 +1103,7 @@ BOOL ScFormulaCell::UpdateDeleteTab(SCTAB nTable, BOOL bIsMove)
ScCompiler aComp2(pDocument, aPos, *pCode);
aComp2.SetGrammar(pDocument->GetGrammar());
aComp2.CompileTokenArray();
- aComp2.MoveRelWrap();
+ aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
aComp2.UpdateDeleteTab( nTable, FALSE, FALSE, bRefChanged );
// If the shared formula contained a named range/formula containing
// an absolute reference to a sheet, those have to be readjusted.
@@ -865,7 +1140,7 @@ void ScFormulaCell::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
ScCompiler aComp2(pDocument, aPos, *pCode);
aComp2.SetGrammar(pDocument->GetGrammar());
aComp2.CompileTokenArray();
- aComp2.MoveRelWrap();
+ aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
aComp2.UpdateMoveTab( nOldPos, nNewPos, TRUE );
bCompile = TRUE;
}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 4c3c86c51971..3238607fd613 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1272,11 +1272,14 @@ void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, BOOL bKee
{
int nCloneFlags = bCloneNoteCaptions ? SC_CLONECELL_DEFAULT : SC_CLONECELL_NOCAPTION;
rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
- ScAddress aPos( rColumn.nCol, 0, rColumn.nTab );
+ ScAddress aOwnPos( nCol, 0, nTab );
+ ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
for (i = nStartIndex; i <= nEndIndex; i++)
{
- aPos.SetRow( pItems[i].nRow );
- rColumn.Append( aPos.Row(), pItems[i].pCell->CloneWithNote( *rColumn.pDocument, aPos, nCloneFlags ) );
+ aOwnPos.SetRow( pItems[i].nRow );
+ aDestPos.SetRow( pItems[i].nRow );
+ ScBaseCell* pNewCell = pItems[i].pCell->CloneWithNote( aOwnPos, *rColumn.pDocument, aDestPos, nCloneFlags );
+ rColumn.Append( aDestPos.Row(), pNewCell );
}
}
}
@@ -1376,16 +1379,18 @@ void ScColumn::UndoToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarke
void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
{
ScDocument& rDestDoc = *rDestCol.pDocument;
+ ScAddress aOwnPos( nCol, 0, nTab );
ScAddress aDestPos( rDestCol.nCol, 0, rDestCol.nTab );
SCSIZE nPosCount = rPosCol.nCount;
for (SCSIZE nPosIndex = 0; nPosIndex < nPosCount; nPosIndex++)
{
- aDestPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
+ aOwnPos.SetRow( rPosCol.pItems[nPosIndex].nRow );
+ aDestPos.SetRow( aOwnPos.Row() );
SCSIZE nThisIndex;
if ( Search( aDestPos.Row(), nThisIndex ) )
{
- ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( rDestDoc, aDestPos );
+ ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( aOwnPos, rDestDoc, aDestPos );
rDestCol.Insert( aDestPos.Row(), pNew );
}
}
@@ -1673,7 +1678,10 @@ void ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
if( pCell->GetCellType() == CELLTYPE_FORMULA)
{
SCROW nRow = pItems[i].nRow;
- ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc );
+ // When deleting rows on several sheets, the formula's position may be updated with the first call,
+ // so the undo position must be passed from here.
+ ScAddress aUndoPos( nCol, nRow, nTab );
+ ((ScFormulaCell*)pCell)->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc, &aUndoPos );
if ( nRow != pItems[i].nRow )
Search( nRow, i ); // Listener removed/inserted?
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index bfb1890d70b0..5726862366cf 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -521,6 +521,15 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, USHORT nDelFla
for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
(*aIt)->EndListeningTo( pDocument );
+ // #i101869# if the note cell with the broadcaster was deleted in EndListening,
+ // forget the pointer to the broadcaster
+ for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
+ {
+ SCSIZE nIndex;
+ if ( !Search( (*aIt)->aPos.Row(), nIndex ) )
+ (*aIt)->ReleaseBroadcaster();
+ }
+
// broadcast SC_HINT_DYING for all cells and delete them
for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
{
@@ -739,6 +748,9 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
Resize( nNew );
}
+ // IDF_ADDNOTES must be passed without other content flags than IDF_NOTE
+ bool bAddNotes = (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES);
+
BOOL bAtEnd = FALSE;
for (SCSIZE i = 0; i < nColCount && !bAtEnd; i++)
{
@@ -751,12 +763,38 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
// nDestRow may be negative then
ScAddress aDestPos( nCol, (SCROW)nDestRow, nTab );
- ScBaseCell* pNew = bAsLink ?
- rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) :
- rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos );
- if (pNew)
- Insert((SCROW)nDestRow, pNew);
+ /* #i102056# Paste from clipboard needs to paste the cell notes in
+ a second pass. This must not overwrite the existing cells
+ already copied to the destination position in the first pass.
+ To indicate this special case, the modifier IDF_ADDNOTES is
+ passed together with IDF_NOTE in nInsFlag. Of course, there is
+ still the need to create a new cell, if there is no cell at the
+ destination position at all. */
+ ScBaseCell* pAddNoteCell = bAddNotes ? GetCell( aDestPos.Row() ) : 0;
+ if (pAddNoteCell)
+ {
+ // do nothing if source cell does not contain a note
+ const ScBaseCell* pSourceCell = rColumn.pItems[i].pCell;
+ const ScPostIt* pSourceNote = pSourceCell ? pSourceCell->GetNote() : 0;
+ if (pSourceNote)
+ {
+ DBG_ASSERT( !pAddNoteCell->HasNote(), "ScColumn::CopyFromClip - unexpected note at destination cell" );
+ bool bCloneCaption = (nInsFlag & IDF_NOCAPTIONS) == 0;
+ // #i52342# if caption is cloned, the note must be constructed with the destination document
+ ScAddress aSourcePos( rColumn.nCol, rColumn.pItems[i].nRow, rColumn.nTab );
+ ScPostIt* pNewNote = pSourceNote->Clone( aSourcePos, *pDocument, aDestPos, bCloneCaption );
+ pAddNoteCell->TakeNote( pNewNote );
+ }
+ }
+ else
+ {
+ ScBaseCell* pNewCell = bAsLink ?
+ rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) :
+ rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos );
+ if (pNewCell)
+ Insert( aDestPos.Row(), pNewCell );
+ }
}
}
}
@@ -870,7 +908,8 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestD
{
bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0;
// #i52342# if caption is cloned, the note must be constructed with the destination document
- ScPostIt* pNewNote = ScNoteUtil::CloneNote( rDestDoc, rDestPos, *pNote, bCloneCaption );
+ ScAddress aOwnPos( nCol, pItems[nIndex].nRow, nTab );
+ ScPostIt* pNewNote = pNote->Clone( aOwnPos, rDestDoc, rDestPos, bCloneCaption );
if (!pNew)
pNew = new ScNoteCell( pNewNote );
else
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 12dbf77e88e6..3c636d9049d4 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -130,7 +130,10 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
nVal2(r.nVal2),
aStrVal1(r.aStrVal1),
aStrVal2(r.aStrVal2),
- eTempGrammar(r.eTempGrammar),
+ aStrNmsp1(r.aStrNmsp1),
+ aStrNmsp2(r.aStrNmsp2),
+ eTempGrammar1(r.eTempGrammar1),
+ eTempGrammar2(r.eTempGrammar2),
bIsStr1(r.bIsStr1),
bIsStr2(r.bIsStr2),
pFormula1(NULL),
@@ -161,7 +164,10 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr
nVal2(r.nVal2),
aStrVal1(r.aStrVal1),
aStrVal2(r.aStrVal2),
- eTempGrammar(r.eTempGrammar),
+ aStrNmsp1(r.aStrNmsp1),
+ aStrNmsp2(r.aStrNmsp2),
+ eTempGrammar1(r.eTempGrammar1),
+ eTempGrammar2(r.eTempGrammar2),
bIsStr1(r.bIsStr1),
bIsStr2(r.bIsStr2),
pFormula1(NULL),
@@ -187,14 +193,17 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr
}
ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
- const String& rExpr1, const String& rExpr2,
- ScDocument* pDocument, const ScAddress& rPos,
- const FormulaGrammar::Grammar eGrammar ) :
+ const String& rExpr1, const String& rExpr2, ScDocument* pDocument, const ScAddress& rPos,
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
eOp(eOper),
nOptions(0), // spaeter...
nVal1(0.0),
nVal2(0.0),
- eTempGrammar(eGrammar),
+ aStrNmsp1(rExprNmsp1),
+ aStrNmsp2(rExprNmsp2),
+ eTempGrammar1(eGrammar1),
+ eTempGrammar2(eGrammar2),
bIsStr1(FALSE),
bIsStr2(FALSE),
pFormula1(NULL),
@@ -207,7 +216,7 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
bRelRef2(FALSE),
bFirstRun(TRUE)
{
- Compile( rExpr1, rExpr2, eGrammar, FALSE );
+ Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, FALSE );
// Formelzellen werden erst bei IsValid angelegt
}
@@ -219,7 +228,8 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
nOptions(0), // spaeter...
nVal1(0.0),
nVal2(0.0),
- eTempGrammar(FormulaGrammar::GRAM_DEFAULT),
+ eTempGrammar1(FormulaGrammar::GRAM_DEFAULT),
+ eTempGrammar2(FormulaGrammar::GRAM_DEFAULT),
bIsStr1(FALSE),
bIsStr2(FALSE),
pFormula1(NULL),
@@ -294,15 +304,16 @@ ScConditionEntry::~ScConditionEntry()
}
void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
- const FormulaGrammar::Grammar eGrammar, BOOL bTextToReal )
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, BOOL bTextToReal )
{
if ( rExpr1.Len() || rExpr2.Len() )
{
ScCompiler aComp( pDoc, aSrcPos );
- aComp.SetGrammar(eGrammar);
if ( rExpr1.Len() )
{
+ aComp.SetGrammar( eGrammar1 );
if ( pDoc->IsImportingXML() && !bTextToReal )
{
// temporary formula string as string tokens
@@ -313,7 +324,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
}
else
{
- pFormula1 = aComp.CompileString( rExpr1 );
+ pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
if ( pFormula1->GetLen() == 1 )
{
// einzelne (konstante Zahl) ?
@@ -339,6 +350,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
if ( rExpr2.Len() )
{
+ aComp.SetGrammar( eGrammar2 );
if ( pDoc->IsImportingXML() && !bTextToReal )
{
// temporary formula string as string tokens
@@ -349,7 +361,7 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
}
else
{
- pFormula2 = aComp.CompileString( rExpr2 );
+ pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
if ( pFormula2->GetLen() == 1 )
{
// einzelne (konstante Zahl) ?
@@ -429,9 +441,9 @@ void ScConditionEntry::CompileXML()
// Convert the text tokens that were created during XML import into real tokens.
- Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar),
- GetExpression(aSrcPos, 1, 0, eTempGrammar),
- eTempGrammar, TRUE );
+ Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
+ GetExpression(aSrcPos, 1, 0, eTempGrammar2),
+ aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, TRUE );
}
void ScConditionEntry::SetSrcString( const String& rNew )
@@ -1129,8 +1141,10 @@ ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
const String& rExpr1, const String& rExpr2,
ScDocument* pDocument, const ScAddress& rPos,
const String& rStyle,
- const FormulaGrammar::Grammar eGrammar ) :
- ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, eGrammar ),
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ FormulaGrammar::Grammar eGrammar1,
+ FormulaGrammar::Grammar eGrammar2 ) :
+ ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
aStyleName( rStyle ),
pParent( NULL )
{
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index f5dbb14e9ff9..16613fbcbab4 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -94,6 +94,8 @@
#include "recursionhelper.hxx"
#include "lookupcache.hxx"
#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
// pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
// dtor plus helpers are convenient.
@@ -152,7 +154,7 @@ ScDocument::ScDocument( ScDocumentMode eMode,
pChangeViewSettings( NULL ),
pScriptTypeData( NULL ),
pCacheFieldEditEngine( NULL ),
- pExternalRefMgr( NULL ),
+ pDocProtection( NULL ),
pViewOptions( NULL ),
pDocOptions( NULL ),
pExtDocOptions( NULL ),
@@ -175,7 +177,6 @@ ScDocument::ScDocument( ScDocumentMode eMode,
nHardRecalcState(0),
nVisibleTab( 0 ),
eLinkMode(LM_UNKNOWN),
- bProtected( FALSE ),
bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
bAutoCalcShellDisabled( FALSE ),
bForcedFormulaPending( FALSE ),
@@ -383,15 +384,14 @@ ScDocument::~ScDocument()
pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
}
- if (pExternalRefMgr.get())
- // Destroy the external ref mgr instance here because it has a timer
- // which needs to be stopped before the app closes.
- pExternalRefMgr.reset(NULL);
+ mxFormulaParserPool.reset();
+ // Destroy the external ref mgr instance here because it has a timer
+ // which needs to be stopped before the app closes.
+ pExternalRefMgr.reset();
ScAddInAsync::RemoveDocument( this );
ScAddInListener::RemoveDocument( this );
- delete pChartListenerCollection; // vor pBASM wg. evtl. Listener!
- pChartListenerCollection = NULL;
+ DELETEZ( pChartListenerCollection); // vor pBASM wg. evtl. Listener!
DELETEZ( pLookupCacheMapImpl); // before pBASM because of listeners
// BroadcastAreas vor allen Zellen zerstoeren um unnoetige
// Einzel-EndListenings der Formelzellen zu vermeiden
@@ -931,6 +931,7 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
+ pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
// Update cells containing external references.
if (pExternalRefMgr.get())
@@ -1109,6 +1110,8 @@ ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
if (bInsertNew)
TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
+
+ pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
}
if (!bValid)
nRetVal = 0;
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 2b3fbb359988..08170fd6cdc9 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -40,6 +40,7 @@
#include <sfx2/bindings.hxx>
#include <sfx2/objsh.hxx>
#include <svtools/zforlist.hxx>
+#include <svtools/PasswordHelper.hxx>
#include <vcl/svapp.hxx>
#include "document.hxx"
#include "attrib.hxx"
@@ -77,6 +78,8 @@
#include "drwlayer.hxx"
#include "unoreflist.hxx"
#include "listenercalls.hxx"
+#include "tabprotection.hxx"
+#include "formulaparserpool.hxx"
#include <memory>
@@ -507,6 +510,13 @@ void ScDocument::MarkUsedExternalReferences()
* collecting them during export. */
}
+ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
+{
+ if( !mxFormulaParserPool.get() )
+ mxFormulaParserPool.reset( new ScFormulaParserPool( *this ) );
+ return *mxFormulaParserPool;
+}
+
ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate )
{
ScOutlineTable* pVal = NULL;
@@ -1701,28 +1711,28 @@ void ScDocument::SnapVisArea( Rectangle& rRect ) const
ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle
}
-void ScDocument::SetDocProtection( BOOL bProtect, const uno::Sequence<sal_Int8>& rPasswd )
+ScDocProtection* ScDocument::GetDocProtection() const
{
- bProtected = bProtect;
- aProtectPass = rPasswd;
+ return pDocProtection.get();
}
-void ScDocument::SetTabProtection( SCTAB nTab, BOOL bProtect, const uno::Sequence<sal_Int8>& rPasswd )
+void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
{
- if (VALIDTAB(nTab))
- if (pTab[nTab])
- pTab[nTab]->SetProtection( bProtect, rPasswd );
+ if (pProtect)
+ pDocProtection.reset(new ScDocProtection(*pProtect));
+ else
+ pDocProtection.reset(NULL);
}
BOOL ScDocument::IsDocProtected() const
{
- return bProtected;
+ return pDocProtection.get() && pDocProtection->isProtected();
}
BOOL ScDocument::IsDocEditable() const
{
// import into read-only document is possible
- return !bProtected && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
+ return !IsDocProtected() && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
}
BOOL ScDocument::IsTabProtected( SCTAB nTab ) const
@@ -1734,18 +1744,28 @@ BOOL ScDocument::IsTabProtected( SCTAB nTab ) const
return FALSE;
}
-const uno::Sequence<sal_Int8>& ScDocument::GetDocPassword() const
+ScTableProtection* ScDocument::GetTabProtection( SCTAB nTab ) const
{
- return aProtectPass;
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetProtection();
+
+ return NULL;
}
-const uno::Sequence<sal_Int8>& ScDocument::GetTabPassword( SCTAB nTab ) const
+void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
{
- if (VALIDTAB(nTab) && pTab[nTab])
- return pTab[nTab]->GetPassword();
+ if (!ValidTab(nTab))
+ return;
- DBG_ERROR("Falsche Tabellennummer");
- return aProtectPass;
+ pTab[nTab]->SetProtection(pProtect);
+}
+
+void ScDocument::CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest)
+{
+ if (!ValidTab(nTabSrc) || !ValidTab(nTabDest))
+ return;
+
+ pTab[nTabDest]->SetProtection( pTab[nTabSrc]->GetProtection() );
}
const ScDocOptions& ScDocument::GetDocOptions() const
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 3c72baff5ba4..7313ebbf83f5 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -311,9 +311,16 @@ bool ScDocument::MarkUsedExternalReferences( ScTokenArray & rArr )
switch (t->GetType())
{
case svExternalSingleRef:
- case svExternalDoubleRef:
bAllMarked = pRefMgr->setCacheTableReferenced(
- t->GetIndex(), t->GetString());
+ t->GetIndex(), t->GetString(), 1);
+ break;
+ case svExternalDoubleRef:
+ {
+ const ScComplexRefData& rRef = t->GetDoubleRef();
+ size_t nSheets = rRef.Ref2.nTab - rRef.Ref1.nTab + 1;
+ bAllMarked = pRefMgr->setCacheTableReferenced(
+ t->GetIndex(), t->GetString(), nSheets);
+ }
break;
case svExternalName:
/* TODO: external names aren't supported yet, but would
diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx
index 8d528db34118..0be1e6717891 100644
--- a/sc/source/core/data/documen5.cxx
+++ b/sc/source/core/data/documen5.cxx
@@ -130,6 +130,7 @@ void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartD
if( xLabel.is())
{
+ // the range string must be in Calc A1 format.
uno::Reference< chart2::data::XDataSequence > xNewSeq(
xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
@@ -145,6 +146,7 @@ void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartD
if( xValues.is())
{
+ // the range string must be in Calc A1 format.
uno::Reference< chart2::data::XDataSequence > xNewSeq(
xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] ));
@@ -391,7 +393,7 @@ void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRang
for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ )
{
ScRangeList aRanges;
- aRanges.Parse( aRangeStrings[nN], pSheetNameDoc );
+ aRanges.Parse( aRangeStrings[nN], pSheetNameDoc, SCA_VALID, pSheetNameDoc->GetAddressConvention() );
rRangesVector.push_back(aRanges);
}
}
@@ -407,8 +409,8 @@ void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector<
for( sal_Int32 nN=0; nN<nCount; nN++ )
{
ScRangeList aScRangeList( rRangesVector[nN] );
- String sRangeStr;
- aScRangeList.Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
+ String sRangeStr; // This range must be in Calc A1 format.
+ aScRangeList.Format( sRangeStr, SCR_ABS_3D, this );
aRangeStrings[nN]=sRangeStr;
}
lcl_SetChartRanges( xChartDoc, aRangeStrings );
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 0d12c82dec87..c34e93f10d66 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -44,6 +44,7 @@
#include <svx/linkmgr.hxx>
#include <svx/scripttypeitem.hxx>
#include <svx/unolingu.hxx>
+#include <sfx2/bindings.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/viewfrm.hxx>
@@ -1046,6 +1047,18 @@ void ScDocument::UpdateExternalRefLinks()
TrackFormulas();
pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
ResetChanged( ScRange(0, 0, 0, MAXCOL, MAXROW, MAXTAB) );
+
+ // #i101960# set document modified, as in TrackTimeHdl for DDE links
+ if (!pShell->IsModified())
+ {
+ pShell->SetModified( TRUE );
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_SAVEDOC );
+ pBindings->Invalidate( SID_DOC_MODIFIED );
+ }
+ }
}
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index bdca03b861c1..61cf3ab94b35 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -93,6 +93,7 @@
#include "bcaslot.hxx"
#include "postit.hxx"
#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
@@ -506,6 +507,22 @@ BOOL ScDocument::IsVisible( SCTAB nTab ) const
}
+BOOL ScDocument::IsPendingRowHeights( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->IsPendingRowHeights();
+
+ return FALSE;
+}
+
+
+void ScDocument::SetPendingRowHeights( SCTAB nTab, BOOL bSet )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetPendingRowHeights( bSet );
+}
+
+
void ScDocument::SetLayoutRTL( SCTAB nTab, BOOL bRTL )
{
if ( ValidTab(nTab) && pTab[nTab] )
@@ -657,6 +674,43 @@ void ScDocument::LimitChartIfAll( ScRangeListRef& rRangeList )
}
+void lcl_GetFirstTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark )
+{
+ // without ScMarkData, leave start/end unchanged
+ if ( pTabMark )
+ {
+ for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
+ if (pTabMark->GetTableSelect(nTab))
+ {
+ // find first range of consecutive selected sheets
+ rTabRangeStart = nTab;
+ while ( nTab+1 <= MAXTAB && pTabMark->GetTableSelect(nTab+1) )
+ ++nTab;
+ rTabRangeEnd = nTab;
+ return;
+ }
+ }
+}
+
+bool lcl_GetNextTabRange( SCTAB& rTabRangeStart, SCTAB& rTabRangeEnd, const ScMarkData* pTabMark )
+{
+ if ( pTabMark )
+ {
+ // find next range of consecutive selected sheets after rTabRangeEnd
+ for (SCTAB nTab=rTabRangeEnd+1; nTab<=MAXTAB; ++nTab)
+ if (pTabMark->GetTableSelect(nTab))
+ {
+ rTabRangeStart = nTab;
+ while ( nTab+1 <= MAXTAB && pTabMark->GetTableSelect(nTab+1) )
+ ++nTab;
+ rTabRangeEnd = nTab;
+ return true;
+ }
+ }
+ return false;
+}
+
+
BOOL ScDocument::CanInsertRow( const ScRange& rRange ) const
{
SCCOL nStartCol = rRange.aStart.Col();
@@ -681,39 +735,60 @@ BOOL ScDocument::CanInsertRow( const ScRange& rRange ) const
BOOL ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
SCCOL nEndCol, SCTAB nEndTab,
- SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc )
+ SCROW nStartRow, SCSIZE nSize, ScDocument* pRefUndoDoc,
+ const ScMarkData* pTabMark )
{
SCTAB i;
PutInOrder( nStartCol, nEndCol );
PutInOrder( nStartTab, nEndTab );
+ if ( pTabMark )
+ {
+ nStartTab = 0;
+ nEndTab = MAXTAB;
+ }
BOOL bTest = TRUE;
BOOL bRet = FALSE;
BOOL bOldAutoCalc = GetAutoCalc();
SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
for ( i = nStartTab; i <= nEndTab && bTest; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
bTest &= pTab[i]->TestInsertRow( nStartCol, nEndCol, nSize );
if (bTest)
{
// UpdateBroadcastAreas muss vor UpdateReference gerufen werden, damit nicht
// Eintraege verschoben werden, die erst bei UpdateReference neu erzeugt werden
- UpdateBroadcastAreas( URM_INSDEL, ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( nEndCol, MAXROW, nEndTab )), 0, static_cast<SCsROW>(nSize), 0 );
- UpdateReference( URM_INSDEL, nStartCol, nStartRow, nStartTab,
- nEndCol, MAXROW, nEndTab,
- 0, static_cast<SCsROW>(nSize), 0, pRefUndoDoc, FALSE ); // without drawing objects
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateBroadcastAreas( URM_INSDEL, ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, static_cast<SCsROW>(nSize), 0 );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart,
+ nEndCol, MAXROW, nTabRangeEnd,
+ 0, static_cast<SCsROW>(nSize), 0, pRefUndoDoc, FALSE ); // without drawing objects
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
for (i=nStartTab; i<=nEndTab; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
pTab[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize );
// #82991# UpdateRef for drawing layer must be after inserting,
// when the new row heights are known.
for (i=nStartTab; i<=nEndTab; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
pTab[i]->UpdateDrawRef( URM_INSDEL,
nStartCol, nStartRow, nStartTab, nEndCol, MAXROW, nEndTab,
0, static_cast<SCsROW>(nSize), 0 );
@@ -756,42 +831,61 @@ BOOL ScDocument::InsertRow( const ScRange& rRange, ScDocument* pRefUndoDoc )
void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
SCCOL nEndCol, SCTAB nEndTab,
SCROW nStartRow, SCSIZE nSize,
- ScDocument* pRefUndoDoc, BOOL* pUndoOutline )
+ ScDocument* pRefUndoDoc, BOOL* pUndoOutline,
+ const ScMarkData* pTabMark )
{
SCTAB i;
PutInOrder( nStartCol, nEndCol );
PutInOrder( nStartTab, nEndTab );
+ if ( pTabMark )
+ {
+ nStartTab = 0;
+ nEndTab = MAXTAB;
+ }
BOOL bOldAutoCalc = GetAutoCalc();
SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
- if ( ValidRow(nStartRow+nSize) )
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
{
- DelBroadcastAreasInRange( ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( nEndCol, nStartRow+nSize-1, nEndTab ) ) );
- UpdateBroadcastAreas( URM_INSDEL, ScRange(
- ScAddress( nStartCol, nStartRow+nSize, nStartTab ),
- ScAddress( nEndCol, MAXROW, nEndTab )), 0, -(static_cast<SCsROW>(nSize)), 0 );
+ if ( ValidRow(nStartRow+nSize) )
+ {
+ DelBroadcastAreasInRange( ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( nEndCol, nStartRow+nSize-1, nTabRangeEnd ) ) );
+ UpdateBroadcastAreas( URM_INSDEL, ScRange(
+ ScAddress( nStartCol, nStartRow+nSize, nTabRangeStart ),
+ ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, -(static_cast<SCsROW>(nSize)), 0 );
+ }
+ else
+ DelBroadcastAreasInRange( ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( nEndCol, MAXROW, nTabRangeEnd ) ) );
}
- else
- DelBroadcastAreasInRange( ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( nEndCol, MAXROW, nEndTab ) ) );
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
if ( ValidRow(nStartRow+nSize) )
{
- UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nStartTab,
- nEndCol, MAXROW, nEndTab,
- 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc );
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nTabRangeStart,
+ nEndCol, MAXROW, nTabRangeEnd,
+ 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
}
if (pUndoOutline)
*pUndoOutline = FALSE;
for ( i = nStartTab; i <= nEndTab; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
pTab[i]->DeleteRow( nStartCol, nEndCol, nStartRow, nSize, pUndoOutline );
if ( ValidRow(nStartRow+nSize) )
@@ -844,30 +938,51 @@ BOOL ScDocument::CanInsertCol( const ScRange& rRange ) const
BOOL ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
SCROW nEndRow, SCTAB nEndTab,
- SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc )
+ SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
+ const ScMarkData* pTabMark )
{
SCTAB i;
PutInOrder( nStartRow, nEndRow );
PutInOrder( nStartTab, nEndTab );
+ if ( pTabMark )
+ {
+ nStartTab = 0;
+ nEndTab = MAXTAB;
+ }
BOOL bTest = TRUE;
BOOL bRet = FALSE;
BOOL bOldAutoCalc = GetAutoCalc();
SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
for ( i = nStartTab; i <= nEndTab && bTest; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
bTest &= pTab[i]->TestInsertCol( nStartRow, nEndRow, nSize );
if (bTest)
{
- UpdateBroadcastAreas( URM_INSDEL, ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( MAXCOL, nEndRow, nEndTab )), static_cast<SCsCOL>(nSize), 0, 0 );
- UpdateReference( URM_INSDEL, nStartCol, nStartRow, nStartTab,
- MAXCOL, nEndRow, nEndTab,
- static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc );
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateBroadcastAreas( URM_INSDEL, ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), static_cast<SCsCOL>(nSize), 0, 0 );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart,
+ MAXCOL, nEndRow, nTabRangeEnd,
+ static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
+
for (i=nStartTab; i<=nEndTab; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
pTab[i]->InsertCol( nStartCol, nStartRow, nEndRow, nSize );
if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
@@ -907,42 +1022,60 @@ BOOL ScDocument::InsertCol( const ScRange& rRange, ScDocument* pRefUndoDoc )
void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab,
SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc,
- BOOL* pUndoOutline )
+ BOOL* pUndoOutline, const ScMarkData* pTabMark )
{
SCTAB i;
PutInOrder( nStartRow, nEndRow );
PutInOrder( nStartTab, nEndTab );
+ if ( pTabMark )
+ {
+ nStartTab = 0;
+ nEndTab = MAXTAB;
+ }
BOOL bOldAutoCalc = GetAutoCalc();
SetAutoCalc( FALSE ); // Mehrfachberechnungen vermeiden
- if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
+ // handle chunks of consecutive selected sheets together
+ SCTAB nTabRangeStart = nStartTab;
+ SCTAB nTabRangeEnd = nEndTab;
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
{
- DelBroadcastAreasInRange( ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nEndTab ) ) );
- UpdateBroadcastAreas( URM_INSDEL, ScRange(
- ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nStartTab ),
- ScAddress( MAXCOL, nEndRow, nEndTab )), -static_cast<SCsCOL>(nSize), 0, 0 );
+ if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
+ {
+ DelBroadcastAreasInRange( ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize-1), nEndRow, nTabRangeEnd ) ) );
+ UpdateBroadcastAreas( URM_INSDEL, ScRange(
+ ScAddress( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart ),
+ ScAddress( MAXCOL, nEndRow, nTabRangeEnd )), -static_cast<SCsCOL>(nSize), 0, 0 );
+ }
+ else
+ DelBroadcastAreasInRange( ScRange(
+ ScAddress( nStartCol, nStartRow, nTabRangeStart ),
+ ScAddress( MAXCOL, nEndRow, nTabRangeEnd ) ) );
}
- else
- DelBroadcastAreasInRange( ScRange(
- ScAddress( nStartCol, nStartRow, nStartTab ),
- ScAddress( MAXCOL, nEndRow, nEndTab ) ) );
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
{
- UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nStartTab,
- MAXCOL, nEndRow, nEndTab,
- -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc );
+ lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark );
+ do
+ {
+ UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart,
+ MAXCOL, nEndRow, nTabRangeEnd,
+ -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc );
+ }
+ while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) );
}
if (pUndoOutline)
*pUndoOutline = FALSE;
for ( i = nStartTab; i <= nEndTab; i++)
- if (pTab[i])
+ if (pTab[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
pTab[i]->DeleteCol( nStartCol, nStartRow, nEndRow, nSize, pUndoOutline );
if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
@@ -1781,9 +1914,17 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX );
nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY ); // ClipArea, plus ExtendMerge value
- // Inhalte entweder komplett oder gar nicht loeschen:
+ /* Decide which contents to delete before copying. Delete all
+ contents if nInsFlag contains any real content flag.
+ #i102056# Notes are pasted from clipboard in a second pass,
+ together with the special flag IDF_ADDNOTES that states to not
+ overwrite/delete existing cells but to insert the notes into
+ these cells. In this case, just delete old notes from the
+ destination area. */
USHORT nDelFlag = IDF_NONE;
- if ( nInsFlag & IDF_CONTENTS )
+ if ( (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES) )
+ nDelFlag |= IDF_NOTE;
+ else if ( nInsFlag & IDF_CONTENTS )
nDelFlag |= IDF_CONTENTS;
// With bSkipAttrForEmpty, don't remove attributes, copy
// on top of existing attributes instead.
@@ -2343,7 +2484,7 @@ void ScDocument::GetCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
ScBaseCell* ScDocument::GetCell( const ScAddress& rPos ) const
{
SCTAB nTab = rPos.Tab();
- if ( pTab[nTab] )
+ if (ValidTab(nTab) && pTab[nTab])
return pTab[nTab]->GetCell( rPos );
DBG_ERROR("GetCell ohne Tabelle");
@@ -2443,6 +2584,18 @@ void ScDocument::DeleteNote( const ScAddress& rPos )
}
+void ScDocument::InitializeNoteCaptions( SCTAB nTab, bool bForced )
+{
+ if( ValidTab( nTab ) && pTab[ nTab ] )
+ pTab[ nTab ]->InitializeNoteCaptions( bForced );
+}
+
+void ScDocument::InitializeAllNoteCaptions( bool bForced )
+{
+ for( SCTAB nTab = 0; nTab < GetTableCount(); ++nTab )
+ InitializeNoteCaptions( nTab, bForced );
+}
+
void ScDocument::SetDirty()
{
BOOL bOldAutoCalc = GetAutoCalc();
@@ -2808,14 +2961,20 @@ BOOL ScDocument::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, U
void ScDocument::UpdateAllRowHeights( OutputDevice* pDev, double nPPTX, double nPPTY,
- const Fraction& rZoomX, const Fraction& rZoomY )
+ const Fraction& rZoomX, const Fraction& rZoomY, const ScMarkData* pTabMark )
{
- // one progress across all sheets
- ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), GetWeightedCount() );
+ // one progress across all (selected) sheets
+
+ ULONG nCellCount = 0;
+ for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
+ if ( pTab[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
+ nCellCount += pTab[nTab]->GetWeightedCount();
+
+ ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount );
ULONG nProgressStart = 0;
for ( SCTAB nTab=0; nTab<=MAXTAB; nTab++ )
- if ( pTab[nTab] )
+ if ( pTab[nTab] && ( !pTabMark || pTabMark->GetTableSelect(nTab) ) )
{
pTab[nTab]->SetOptimalHeight( 0, MAXROW, 0,
pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE, &aProgress, nProgressStart );
@@ -3980,24 +4139,6 @@ BOOL ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
}
-//UNUSED2008-05 void ScDocument::SetAutoFilterFlags()
-//UNUSED2008-05 {
-//UNUSED2008-05 USHORT nCount = pDBCollection->GetCount();
-//UNUSED2008-05 for (USHORT i=0; i<nCount; i++)
-//UNUSED2008-05 {
-//UNUSED2008-05 ScDBData* pData = (*pDBCollection)[i];
-//UNUSED2008-05 SCTAB nDBTab;
-//UNUSED2008-05 SCCOL nDBStartCol;
-//UNUSED2008-05 SCROW nDBStartRow;
-//UNUSED2008-05 SCCOL nDBEndCol;
-//UNUSED2008-05 SCROW nDBEndRow;
-//UNUSED2008-05 pData->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
-//UNUSED2008-05 pData->SetAutoFilter( HasAttrib( nDBStartCol,nDBStartRow,nDBTab,
-//UNUSED2008-05 nDBEndCol,nDBStartRow,nDBTab, HASATTR_AUTOFILTER ) );
-//UNUSED2008-05 }
-//UNUSED2008-05 }
-
-
BOOL ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
{
const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
@@ -4030,16 +4171,21 @@ void ScDocument::ApplySelectionFrame( const ScMarkData& rMark,
const SvxBoxItem* pLineOuter,
const SvxBoxInfoItem* pLineInner )
{
- if (rMark.IsMarked())
+ ScRangeList aRangeList;
+ rMark.FillRangeListWithMarks( &aRangeList, FALSE );
+ ULONG nRangeCount = aRangeList.Count();
+ for (SCTAB i=0; i<=MAXTAB; i++)
{
- ScRange aRange;
- rMark.GetMarkArea(aRange);
- for (SCTAB i=0; i<=MAXTAB; i++)
- if (pTab[i])
- if (rMark.GetTableSelect(i))
- pTab[i]->ApplyBlockFrame( pLineOuter, pLineInner,
- aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aEnd.Col(), aRange.aEnd.Row() );
+ if (pTab[i] && rMark.GetTableSelect(i))
+ {
+ for (ULONG j=0; j<nRangeCount; j++)
+ {
+ ScRange aRange = *aRangeList.GetObject(j);
+ pTab[i]->ApplyBlockFrame( pLineOuter, pLineInner,
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() );
+ }
+ }
}
}
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 12af06a773ed..813a3381c901 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -466,7 +466,7 @@ ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
}
}
-void ScDPObject::Output()
+void ScDPObject::Output( const ScAddress& rPos )
{
// clear old output area
pDoc->DeleteAreaTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
@@ -478,6 +478,8 @@ void ScDPObject::Output()
CreateOutput(); // create xSource and pOutput if not already done
+ pOutput->SetPosition( rPos );
+
pOutput->Output();
// aOutRange is always the range that was last output to the document
@@ -2337,7 +2339,7 @@ ScDPCollection::ScDPCollection(const ScDPCollection& r) :
ScCollection(r),
pDoc(r.pDoc),
maSharedString(r.maSharedString),
- maCacheCellPool(r.maCacheCellPool)
+ maCacheCellPool() // #i101725# don't copy hash_set with pointers from the other collection
{
}
@@ -2499,8 +2501,9 @@ void ScDPCollection::clearCacheCellPool()
vector<ScDPCacheCell*> ps;
ps.reserve(maCacheCellPool.size());
copy(maCacheCellPool.begin(), maCacheCellPool.end(), back_inserter(ps));
- for_each(ps.begin(), ps.end(), DeleteCacheCells());
maCacheCellPool.clear();
+ // for correctness' sake, delete the elements after clearing the hash_set
+ for_each(ps.begin(), ps.end(), DeleteCacheCells());
}
//------------------------------------------------------------------------
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 6d1e1eb70674..a5c571026e96 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -493,7 +493,7 @@ void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SC
if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() )
pData->maStart.PutInOrder( pData->maEnd );
AddCalcUndo( new ScUndoObjData( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) );
- RecalcPos( pObj, *pData, aOldStt, aOldEnd, bNegativePage );
+ RecalcPos( pObj, *pData, bNegativePage );
}
}
}
@@ -522,27 +522,33 @@ void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize )
SdrObject* pObj = pPage->GetObj( i );
ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
if( pData )
- RecalcPos( pObj, *pData, pData->maStart, pData->maEnd, bNegativePage );
+ RecalcPos( pObj, *pData, bNegativePage );
}
}
}
-void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData,
- const ScAddress& rOldStart, const ScAddress& /*rOldEnd*/, bool bNegativePage )
+void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage )
{
DBG_ASSERT( pDoc, "ScDrawLayer::RecalcPos - missing document" );
if( !pDoc )
return;
+ /* TODO CleanUp: Updating note position works just by chance currently...
+ When inserting rows/columns, this function is called after the
+ insertion, and the note is located at the new position contained in the
+ passed ScDrawObjData already. But when deleting rows/columns, this
+ function is called *before* the deletion, so the note is still at the
+ old cell position, and ScDocument::GetNote() will fail to get the note
+ or will get another note. But after the rows/columns are deleted, a
+ call to ScDrawLayer::SetPageSize() will call this function again, and
+ now the note is at the expected position in the document. */
if( rData.mbNote )
{
- /* #i63671# while inserting/deleting cells/rows/columns: note has
- not been moved yet in document, get it from old position. */
- DBG_ASSERT( rOldStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
+ DBG_ASSERT( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
/* When inside an undo action, there may be pending note captions
where cell note is already deleted. The caption will be deleted
later with drawing undo. */
- if( ScPostIt* pNote = pDoc->GetNote( rOldStart ) )
+ if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) )
pNote->UpdateCaptionPos( rData.maStart );
return;
}
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index 7129198c204f..29618da6630b 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -108,6 +108,7 @@ SLOFILES = \
$(SLO)$/table4.obj \
$(SLO)$/table5.obj \
$(SLO)$/table6.obj \
+ $(SLO)$/tabprotection.obj \
$(SLO)$/userdat.obj \
$(SLO)$/validat.obj \
$(SLO)$/postit.obj
@@ -127,7 +128,9 @@ EXCEPTIONSFILES= \
$(SLO)$/dptabdat.obj \
$(SLO)$/global2.obj \
$(SLO)$/table1.obj \
+ $(SLO)$/table2.obj \
$(SLO)$/table3.obj \
+ $(SLO)$/tabprotection.obj \
$(SLO)$/postit.obj \
$(SLO)$/documen3.obj \
$(SLO)$/documen5.obj \
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index 068ec3ade5e5..c53694b7674c 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -33,6 +33,7 @@
#include "postit.hxx"
+#include <rtl/ustrbuf.hxx>
#include <svtools/useroptions.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdocapt.hxx>
@@ -57,6 +58,9 @@
#include "userdat.hxx"
#include "detfunc.hxx"
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
// ============================================================================
namespace {
@@ -69,8 +73,107 @@ const long SC_NOTECAPTION_OFFSET_Y = -1500; /// Default Y offset of
const long SC_NOTECAPTION_OFFSET_X = 1500; /// Default X offset of note captions to left border of anchor cell.
const long SC_NOTECAPTION_BORDERDIST_TEMP = 100; /// Distance of temporary note captions to visible sheet area.
+// ============================================================================
+
+/** Static helper functions for caption objects. */
+class ScCaptionUtil
+{
+public:
+ /** Moves the caption object to the correct layer according to passed visibility. */
+ static void SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown );
+ /** Sets basic caption settings required for note caption objects. */
+ static void SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown );
+ /** Stores the cell position of the note in the user data area of the caption. */
+ static void SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos );
+ /** Sets all default formatting attributes to the caption object. */
+ static void SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc );
+ /** Updates caption item set according to the passed item set while removing shadow items. */
+ static void SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet );
+};
+
// ----------------------------------------------------------------------------
+void ScCaptionUtil::SetCaptionLayer( SdrCaptionObj& rCaption, bool bShown )
+{
+ SdrLayerID nLayer = bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
+ if( nLayer != rCaption.GetLayer() )
+ rCaption.SetLayer( nLayer );
+}
+
+void ScCaptionUtil::SetBasicCaptionSettings( SdrCaptionObj& rCaption, bool bShown )
+{
+ ScDrawLayer::SetAnchor( &rCaption, SCA_PAGE );
+ SetCaptionLayer( rCaption, bShown );
+ rCaption.SetFixedTail();
+ rCaption.SetSpecialTextBoxShadow();
+}
+
+void ScCaptionUtil::SetCaptionUserData( SdrCaptionObj& rCaption, const ScAddress& rPos )
+{
+ // pass true to ScDrawLayer::GetObjData() to create the object data entry
+ ScDrawObjData* pObjData = ScDrawLayer::GetObjData( &rCaption, true );
+ OSL_ENSURE( pObjData, "ScCaptionUtil::SetCaptionUserData - missing drawing object user data" );
+ pObjData->maStart = rPos;
+ pObjData->mbNote = true;
+}
+
+void ScCaptionUtil::SetDefaultItems( SdrCaptionObj& rCaption, ScDocument& rDoc )
+{
+ SfxItemSet aItemSet = rCaption.GetMergedItemSet();
+
+ // caption tail arrow
+ ::basegfx::B2DPolygon aTriangle;
+ aTriangle.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
+ aTriangle.append( ::basegfx::B2DPoint( 0.0, 30.0 ) );
+ aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
+ aTriangle.setClosed( true );
+ /* #99319# Line ends are now created with an empty name. The
+ checkForUniqueItem() method then finds a unique name for the item's
+ value. */
+ aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
+ aItemSet.Put( XLineStartWidthItem( 200 ) );
+ aItemSet.Put( XLineStartCenterItem( FALSE ) );
+ aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
+ aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
+ aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
+
+ // shadow
+ /* SdrShadowItem has FALSE, instead the shadow is set for the
+ rectangle only with SetSpecialTextBoxShadow() when the object is
+ created (item must be set to adjust objects from older files). */
+ aItemSet.Put( SdrShadowItem( FALSE ) );
+ aItemSet.Put( SdrShadowXDistItem( 100 ) );
+ aItemSet.Put( SdrShadowYDistItem( 100 ) );
+
+ // text attributes
+ aItemSet.Put( SdrTextLeftDistItem( 100 ) );
+ aItemSet.Put( SdrTextRightDistItem( 100 ) );
+ aItemSet.Put( SdrTextUpperDistItem( 100 ) );
+ aItemSet.Put( SdrTextLowerDistItem( 100 ) );
+ aItemSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ aItemSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
+ // #78943# use the default cell style to be able to modify the caption font
+ const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( rDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
+ rDefPattern.FillEditItemSet( &aItemSet );
+
+ rCaption.SetMergedItemSet( aItemSet );
+}
+
+void ScCaptionUtil::SetCaptionItems( SdrCaptionObj& rCaption, const SfxItemSet& rItemSet )
+{
+ // copy all items
+ rCaption.SetMergedItemSet( rItemSet );
+ // reset shadow items
+ rCaption.SetMergedItem( SdrShadowItem( FALSE ) );
+ rCaption.SetMergedItem( SdrShadowXDistItem( 100 ) );
+ rCaption.SetMergedItem( SdrShadowYDistItem( 100 ) );
+ rCaption.SetSpecialTextBoxShadow();
+}
+
+// ============================================================================
+
+/** Helper for creation and manipulation of caption drawing objects independent
+ from cell annotations. */
class ScCaptionCreator
{
public:
@@ -79,27 +182,32 @@ public:
/** Manipulate an existing caption. */
explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption );
+ /** Returns the drawing layer page of the sheet contained in maPos. */
+ SdrPage* GetDrawPage();
/** Returns the caption drawing obejct. */
inline SdrCaptionObj* GetCaption() { return mpCaption; }
/** Moves the caption inside the passed rectangle. Uses page area if 0 is passed. */
void FitCaptionToRect( const Rectangle* pVisRect = 0 );
- /** Places the passed caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
+ /** Places the caption inside the passed rectangle, tries to keep the cell rectangle uncovered. Uses page area if 0 is passed. */
void AutoPlaceCaption( const Rectangle* pVisRect = 0 );
/** Updates caption tail and textbox according to current cell position. Uses page area if 0 is passed. */
void UpdateCaptionPos( const Rectangle* pVisRect = 0 );
- /** Sets all default formatting attributes to the caption object. */
- void SetDefaultItems();
- /** Updates caption itemset according to the passed item set while removing shadow items. */
- void SetCaptionItems( const SfxItemSet& rItemSet );
+
+protected:
+ /** Helper constructor for derived classes. */
+ explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos );
+
+ /** Calculates the caption tail position according to current cell position. */
+ Point CalcTailPos( bool bTailFront );
+ /** Implements creation of the caption object. The caption will not be inserted into the document. */
+ void CreateCaption( bool bShown, bool bTailFront );
private:
/** Initializes all members. */
void Initialize();
/** Returns the passed rectangle if existing, page rectangle otherwise. */
inline const Rectangle& GetVisRect( const Rectangle* pVisRect ) const { return pVisRect ? *pVisRect : maPageRect; }
- /** Calculates the caption tail position according to current cell position. */
- Point CalcTailPos( bool bTailFront );
private:
ScDocument& mrDoc;
@@ -118,17 +226,7 @@ ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, boo
mpCaption( 0 )
{
Initialize();
-
- // create the caption drawing object
- Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
- Point aTailPos = CalcTailPos( bTailFront );
- mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
-
- // basic settings
- ScDrawLayer::SetAnchor( mpCaption, SCA_PAGE );
- mpCaption->SetLayer( bShown ? SC_LAYER_INTERN : SC_LAYER_HIDDEN );
- mpCaption->SetFixedTail();
- mpCaption->SetSpecialTextBoxShadow();
+ CreateCaption( bShown, bTailFront );
}
ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption ) :
@@ -139,6 +237,20 @@ ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, Sdr
Initialize();
}
+ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos ) :
+ mrDoc( rDoc ),
+ maPos( rPos ),
+ mpCaption( 0 )
+{
+ Initialize();
+}
+
+SdrPage* ScCaptionCreator::GetDrawPage()
+{
+ ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
+ return pDrawLayer ? pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) : 0;
+}
+
void ScCaptionCreator::FitCaptionToRect( const Rectangle* pVisRect )
{
const Rectangle& rVisRect = GetVisRect( pVisRect );
@@ -269,98 +381,131 @@ void ScCaptionCreator::UpdateCaptionPos( const Rectangle* pVisRect )
}
}
-void ScCaptionCreator::SetDefaultItems()
+Point ScCaptionCreator::CalcTailPos( bool bTailFront )
{
- SfxItemSet aItemSet = mpCaption->GetMergedItemSet();
-
- // caption tail arrow
- ::basegfx::B2DPolygon aTriangle;
- aTriangle.append( ::basegfx::B2DPoint( 10.0, 0.0 ) );
- aTriangle.append( ::basegfx::B2DPoint( 0.0, 30.0 ) );
- aTriangle.append( ::basegfx::B2DPoint( 20.0, 30.0 ) );
- aTriangle.setClosed( true );
- /* #99319# Line ends are now created with an empty name. The
- checkForUniqueItem() method then finds a unique name for the item's
- value. */
- aItemSet.Put( XLineStartItem( String::EmptyString(), ::basegfx::B2DPolyPolygon( aTriangle ) ) );
- aItemSet.Put( XLineStartWidthItem( 200 ) );
- aItemSet.Put( XLineStartCenterItem( FALSE ) );
- aItemSet.Put( XFillStyleItem( XFILL_SOLID ) );
- aItemSet.Put( XFillColorItem( String::EmptyString(), ScDetectiveFunc::GetCommentColor() ) );
- aItemSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT ) );
-
- // shadow
- /* SdrShadowItem has FALSE, instead the shadow is set for the
- rectangle only with SetSpecialTextBoxShadow when the object is
- created (item must be set to adjust objects from older files). */
- aItemSet.Put( SdrShadowItem( FALSE ) );
- aItemSet.Put( SdrShadowXDistItem( 100 ) );
- aItemSet.Put( SdrShadowYDistItem( 100 ) );
-
- // text attributes
- aItemSet.Put( SdrTextLeftDistItem( 100 ) );
- aItemSet.Put( SdrTextRightDistItem( 100 ) );
- aItemSet.Put( SdrTextUpperDistItem( 100 ) );
- aItemSet.Put( SdrTextLowerDistItem( 100 ) );
- aItemSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
- aItemSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
- // #78943# use the default cell style to be able to modify the caption font
- const ScPatternAttr& rDefPattern = static_cast< const ScPatternAttr& >( mrDoc.GetPool()->GetDefaultItem( ATTR_PATTERN ) );
- rDefPattern.FillEditItemSet( &aItemSet );
-
- mpCaption->SetMergedItemSet( aItemSet );
+ // tail position
+ bool bTailLeft = bTailFront != mbNegPage;
+ Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
+ // move caption point 1/10 mm inside cell
+ if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
+ aTailPos.Y() += 10;
+ return aTailPos;
}
-void ScCaptionCreator::SetCaptionItems( const SfxItemSet& rItemSet )
+void ScCaptionCreator::CreateCaption( bool bShown, bool bTailFront )
{
- // copy all items
- mpCaption->SetMergedItemSet( rItemSet );
- // reset shadow items
- mpCaption->SetMergedItem( SdrShadowItem( FALSE ) );
- mpCaption->SetMergedItem( SdrShadowXDistItem( 100 ) );
- mpCaption->SetMergedItem( SdrShadowYDistItem( 100 ) );
- mpCaption->SetSpecialTextBoxShadow();
+ // create the caption drawing object
+ Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) );
+ Point aTailPos = CalcTailPos( bTailFront );
+ mpCaption = new SdrCaptionObj( aTextRect, aTailPos );
+ // basic caption settings
+ ScCaptionUtil::SetBasicCaptionSettings( *mpCaption, bShown );
}
void ScCaptionCreator::Initialize()
{
maCellRect = ScDrawLayer::GetCellRect( mrDoc, maPos, true );
mbNegPage = mrDoc.IsNegativePage( maPos.Tab() );
+ if( SdrPage* pDrawPage = GetDrawPage() )
+ {
+ maPageRect = Rectangle( Point( 0, 0 ), pDrawPage->GetSize() );
+ /* #i98141# SdrPage::GetSize() returns negative width in RTL mode.
+ The call to Rectangle::Adjust() orders left/right coordinate
+ accordingly. */
+ maPageRect.Justify();
+ }
+}
+
+// ============================================================================
- if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
+/** Helper for creation of permanent caption drawing objects for cell notes. */
+class ScNoteCaptionCreator : public ScCaptionCreator
+{
+public:
+ /** Create a new caption object and inserts it into the document. */
+ explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData );
+ /** Manipulate an existing caption. */
+ explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown );
+};
+
+// ----------------------------------------------------------------------------
+
+ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ) :
+ ScCaptionCreator( rDoc, rPos ) // use helper c'tor that does not create the caption yet
+{
+ SdrPage* pDrawPage = GetDrawPage();
+ OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
+ if( pDrawPage )
{
- if( SdrPage* pPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( maPos.Tab() ) ) )
+ // create the caption drawing object
+ CreateCaption( rNoteData.mbShown, false );
+ rNoteData.mpCaption = GetCaption();
+ OSL_ENSURE( rNoteData.mpCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" );
+ if( rNoteData.mpCaption )
{
- maPageRect = Rectangle( Point( 0, 0 ), pPage->GetSize() );
- /* #i98141# SdrPage::GetSize() returns negative width in RTL mode.
- The call to Rectangle::Adjust() orders left/right coordinate
- accordingly. */
- maPageRect.Justify();
+ // store note position in user data of caption object
+ ScCaptionUtil::SetCaptionUserData( *rNoteData.mpCaption, rPos );
+ // insert object into draw page
+ pDrawPage->InsertObject( rNoteData.mpCaption );
}
}
}
-Point ScCaptionCreator::CalcTailPos( bool bTailFront )
+ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown ) :
+ ScCaptionCreator( rDoc, rPos, rCaption )
{
- // tail position
- bool bTailLeft = bTailFront != mbNegPage;
- Point aTailPos = bTailLeft ? maCellRect.TopLeft() : maCellRect.TopRight();
- // move caption point 1/10 mm inside cell
- if( bTailLeft ) aTailPos.X() += 10; else aTailPos.X() -= 10;
- aTailPos.Y() += 10;
- return aTailPos;
+ SdrPage* pDrawPage = GetDrawPage();
+ OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" );
+ OSL_ENSURE( rCaption.GetPage() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" );
+ if( pDrawPage && (rCaption.GetPage() == pDrawPage) )
+ {
+ // store note position in user data of caption object
+ ScCaptionUtil::SetCaptionUserData( rCaption, rPos );
+ // basic caption settings
+ ScCaptionUtil::SetBasicCaptionSettings( rCaption, bShown );
+ // set correct tail position
+ rCaption.SetTailPos( CalcTailPos( false ) );
+ }
}
} // namespace
// ============================================================================
+struct ScCaptionInitData
+{
+ typedef ::std::auto_ptr< SfxItemSet > SfxItemSetPtr;
+ typedef ::std::auto_ptr< OutlinerParaObject > OutlinerParaObjPtr;
+
+ SfxItemSetPtr mxItemSet; /// Caption object formatting.
+ OutlinerParaObjPtr mxOutlinerObj; /// Text object with all text portion formatting.
+ ::rtl::OUString maSimpleText; /// Simple text without formatting.
+ Point maCaptionOffset; /// Caption position relative to cell corner.
+ Size maCaptionSize; /// Size of the caption object.
+ bool mbDefaultPosSize; /// True = use default position and size for caption.
+
+ explicit ScCaptionInitData();
+};
+
+// ----------------------------------------------------------------------------
+
+ScCaptionInitData::ScCaptionInitData() :
+ mbDefaultPosSize( true )
+{
+}
+
+// ============================================================================
+
ScNoteData::ScNoteData( bool bShown ) :
mpCaption( 0 ),
mbShown( bShown )
{
}
+ScNoteData::~ScNoteData()
+{
+}
+
// ============================================================================
ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, bool bShown ) :
@@ -379,10 +524,12 @@ ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNo
CreateCaption( rPos, rNote.maNoteData.mpCaption );
}
-ScPostIt::ScPostIt( ScDocument& rDoc, const ScNoteData& rNoteData ) :
+ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption ) :
mrDoc( rDoc ),
maNoteData( rNoteData )
{
+ if( bAlwaysCreateCaption || maNoteData.mbShown )
+ CreateCaptionFromInitData( rPos );
}
ScPostIt::~ScPostIt()
@@ -390,164 +537,229 @@ ScPostIt::~ScPostIt()
RemoveCaption();
}
+ScPostIt* ScPostIt::Clone( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, bool bCloneCaption ) const
+{
+ CreateCaptionFromInitData( rOwnPos );
+ return bCloneCaption ? new ScPostIt( rDestDoc, rDestPos, *this ) : new ScPostIt( rDestDoc, rDestPos, maNoteData, false );
+}
+
void ScPostIt::AutoStamp()
{
maNoteData.maDate = ScGlobal::pLocaleData->getDate( Date() );
maNoteData.maAuthor = SvtUserOptions().GetID();
}
-const EditTextObject* ScPostIt::GetEditTextObject() const
+const OutlinerParaObject* ScPostIt::GetOutlinerObject() const
{
if( maNoteData.mpCaption )
- if( const OutlinerParaObject* pOPO = maNoteData.mpCaption->GetOutlinerParaObject() )
- return &pOPO->GetTextObject();
+ return maNoteData.mpCaption->GetOutlinerParaObject();
+ if( maNoteData.mxInitData.get() )
+ return maNoteData.mxInitData->mxOutlinerObj.get();
return 0;
}
-String ScPostIt::GetText() const
+const EditTextObject* ScPostIt::GetEditTextObject() const
+{
+ const OutlinerParaObject* pOPO = GetOutlinerObject();
+ return pOPO ? &pOPO->GetTextObject() : 0;
+}
+
+OUString ScPostIt::GetText() const
{
- String aText;
if( const EditTextObject* pEditObj = GetEditTextObject() )
{
+ OUStringBuffer aBuffer;
for( USHORT nPara = 0, nParaCount = pEditObj->GetParagraphCount(); nPara < nParaCount; ++nPara )
{
if( nPara > 0 )
- aText.Append( '\n' );
- aText.Append( pEditObj->GetText( nPara ) );
+ aBuffer.append( sal_Unicode( '\n' ) );
+ aBuffer.append( pEditObj->GetText( nPara ) );
}
+ return aBuffer.makeStringAndClear();
}
- return aText;
+ if( maNoteData.mxInitData.get() )
+ return maNoteData.mxInitData->maSimpleText;
+ return OUString();
}
bool ScPostIt::HasMultiLineText() const
{
- const EditTextObject* pEditObj = GetEditTextObject();
- return pEditObj && (pEditObj->GetParagraphCount() > 1);
+ if( const EditTextObject* pEditObj = GetEditTextObject() )
+ return pEditObj->GetParagraphCount() > 1;
+ if( maNoteData.mxInitData.get() )
+ return maNoteData.mxInitData->maSimpleText.indexOf( '\n' ) >= 0;
+ return false;
}
-void ScPostIt::SetText( const String& rText )
+void ScPostIt::SetText( const ScAddress& rPos, const OUString& rText )
{
+ CreateCaptionFromInitData( rPos );
if( maNoteData.mpCaption )
maNoteData.mpCaption->SetText( rText );
}
-void ScPostIt::ShowCaption( bool bShow )
+SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
{
- maNoteData.mbShown = bShow;
- UpdateCaptionLayer( maNoteData.mbShown );
+ CreateCaptionFromInitData( rPos );
+ return maNoteData.mpCaption;
}
-void ScPostIt::ShowCaptionTemp( bool bShow )
+void ScPostIt::ForgetCaption()
{
- UpdateCaptionLayer( maNoteData.mbShown || bShow );
+ /* This function is used in undo actions to give up the responsibility for
+ the caption object which is handled by separate drawing undo actions. */
+ maNoteData.mpCaption = 0;
+ maNoteData.mxInitData.reset();
}
-void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
+void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow )
{
+ CreateCaptionFromInitData( rPos );
+ // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
+ maNoteData.mbShown = bShow;
if( maNoteData.mpCaption )
- {
- ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
- aCreator.UpdateCaptionPos();
- }
+ ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, bShow );
}
-void ScPostIt::SetCaptionDefaultItems()
+void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow )
{
+ CreateCaptionFromInitData( rPos );
if( maNoteData.mpCaption )
- {
- ScCaptionCreator aCreator( mrDoc, ScAddress(), *maNoteData.mpCaption );
- aCreator.SetDefaultItems();
- }
+ ScCaptionUtil::SetCaptionLayer( *maNoteData.mpCaption, maNoteData.mbShown || bShow );
}
-void ScPostIt::SetCaptionItems( const SfxItemSet& rItemSet )
+void ScPostIt::UpdateCaptionPos( const ScAddress& rPos )
{
+ CreateCaptionFromInitData( rPos );
if( maNoteData.mpCaption )
{
- ScCaptionCreator aCreator( mrDoc, ScAddress(), *maNoteData.mpCaption );
- aCreator.SetCaptionItems( rItemSet );
+ ScCaptionCreator aCreator( mrDoc, rPos, *maNoteData.mpCaption );
+ aCreator.UpdateCaptionPos();
}
}
// private --------------------------------------------------------------------
+void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
+{
+ OSL_ENSURE( maNoteData.mpCaption || maNoteData.mxInitData.get(), "ScPostIt::CreateCaptionFromInitData - need caption object or initial caption data" );
+ if( maNoteData.mxInitData.get() )
+ {
+ /* This function is called from ScPostIt::Clone() when copying cells
+ to the clipboard/undo document, and when copying cells from the
+ clipboard/undo document. The former should always be called first,
+ so if called in an clipboard/undo document, the caption should have
+ been created already. */
+ OSL_ENSURE( !mrDoc.IsUndo() && !mrDoc.IsClipboard(), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
+
+ if( !maNoteData.mpCaption )
+ {
+ // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
+ ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
+ if( maNoteData.mpCaption )
+ {
+ ScCaptionInitData& rInitData = *maNoteData.mxInitData;
+
+ // transfer ownership of outliner object to caption, or set simple text
+ OSL_ENSURE( rInitData.mxOutlinerObj.get() || (rInitData.maSimpleText.getLength() > 0),
+ "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" );
+ if( rInitData.mxOutlinerObj.get() )
+ maNoteData.mpCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() );
+ else
+ maNoteData.mpCaption->SetText( rInitData.maSimpleText );
+
+ // copy all items or set default items; reset shadow items
+ ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
+ if( rInitData.mxItemSet.get() )
+ ScCaptionUtil::SetCaptionItems( *maNoteData.mpCaption, *rInitData.mxItemSet );
+
+ // set position and size of the caption object
+ if( rInitData.mbDefaultPosSize )
+ {
+ // set other items and fit caption size to text
+ maNoteData.mpCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
+ maNoteData.mpCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
+ maNoteData.mpCaption->AdjustTextFrameWidthAndHeight();
+ aCreator.AutoPlaceCaption();
+ }
+ else
+ {
+ Rectangle aCellRect = ScDrawLayer::GetCellRect( mrDoc, rPos, true );
+ bool bNegPage = mrDoc.IsNegativePage( rPos.Tab() );
+ long nPosX = bNegPage ? (aCellRect.Left() - rInitData.maCaptionOffset.X()) : (aCellRect.Right() + rInitData.maCaptionOffset.X());
+ long nPosY = aCellRect.Top() + rInitData.maCaptionOffset.Y();
+ Rectangle aCaptRect( Point( nPosX, nPosY ), rInitData.maCaptionSize );
+ maNoteData.mpCaption->SetLogicRect( aCaptRect );
+ aCreator.FitCaptionToRect();
+ }
+ }
+ }
+ // forget the initial caption data struct
+ maNoteData.mxInitData.reset();
+ }
+}
+
void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption )
{
- DBG_ASSERT( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
+ OSL_ENSURE( !maNoteData.mpCaption, "ScPostIt::CreateCaption - unexpected caption object found" );
maNoteData.mpCaption = 0;
// drawing layer may be missing, if a note is copied into a clipboard document
- DBG_ASSERT( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
+ OSL_ENSURE( !mrDoc.IsUndo(), "ScPostIt::CreateCaption - note caption should not be created in undo documents" );
if( mrDoc.IsClipboard() )
mrDoc.InitDrawLayer();
- if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
+ // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
+ ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
+ if( maNoteData.mpCaption )
{
- SdrPage* pDrawPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( rPos.Tab() ) );
- DBG_ASSERT( pDrawPage, "ScPostIt::CreateCaption - no drawing page" );
- if( pDrawPage )
+ // clone settings of passed caption
+ if( pCaption )
{
- // create the caption drawing object
- ScCaptionCreator aCreator( mrDoc, rPos, maNoteData.mbShown, false );
- maNoteData.mpCaption = aCreator.GetCaption();
-
- // additional user data (pass true to create the object data entry)
- ScDrawObjData* pData = ScDrawLayer::GetObjData( maNoteData.mpCaption, true );
- pData->maStart = rPos;
- pData->mbNote = true;
-
- // insert object into draw page
- pDrawPage->InsertObject( maNoteData.mpCaption );
-
- // clone settings of passed caption
- if( pCaption )
- {
- // copy edit text object (object must be inserted into page already)
- if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
- maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
- // copy formatting items (after text has been copied to apply font formatting)
- maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
- // move textbox position relative to new cell, copy textbox size
- Rectangle aCaptRect = pCaption->GetLogicRect();
- Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
- aCaptRect.Move( aDist.X(), aDist.Y() );
- maNoteData.mpCaption->SetLogicRect( aCaptRect );
- aCreator.FitCaptionToRect();
- }
- else
- {
- // set default formatting and default position
- aCreator.SetDefaultItems();
- aCreator.AutoPlaceCaption();
- }
+ // copy edit text object (object must be inserted into page already)
+ if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
+ maNoteData.mpCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) );
+ // copy formatting items (after text has been copied to apply font formatting)
+ maNoteData.mpCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() );
+ // move textbox position relative to new cell, copy textbox size
+ Rectangle aCaptRect = pCaption->GetLogicRect();
+ Point aDist = maNoteData.mpCaption->GetTailPos() - pCaption->GetTailPos();
+ aCaptRect.Move( aDist.X(), aDist.Y() );
+ maNoteData.mpCaption->SetLogicRect( aCaptRect );
+ aCreator.FitCaptionToRect();
+ }
+ else
+ {
+ // set default formatting and default position
+ ScCaptionUtil::SetDefaultItems( *maNoteData.mpCaption, mrDoc );
+ aCreator.AutoPlaceCaption();
+ }
- // create undo action
+ // create undo action
+ if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() )
if( pDrawLayer->IsRecording() )
pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoNewObject( *maNoteData.mpCaption ) );
- }
}
}
void ScPostIt::RemoveCaption()
{
+
/* Remove caption object only, if this note is its owner (e.g. notes in
undo documents refer to captions in original document, do not remove
them from drawing layer here). */
- if( maNoteData.mpCaption && (mrDoc.GetDrawLayer() == maNoteData.mpCaption->GetModel()) )
+ ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer();
+ if( maNoteData.mpCaption && (pDrawLayer == maNoteData.mpCaption->GetModel()) )
{
+ OSL_ENSURE( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
SdrPage* pDrawPage = maNoteData.mpCaption->GetPage();
- DBG_ASSERT( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
+ OSL_ENSURE( pDrawPage, "ScPostIt::RemoveCaption - object without drawing page" );
if( pDrawPage )
{
- pDrawPage->RecalcObjOrdNums();
-
- ScDrawLayer* pDrawLayer = static_cast< ScDrawLayer* >( maNoteData.mpCaption->GetModel() );
- DBG_ASSERT( pDrawLayer, "ScPostIt::RemoveCaption - object without drawing layer" );
-
+ pDrawPage->RecalcObjOrdNums();
// create drawing undo action (before removing the object to have valid draw page in undo action)
if( pDrawLayer && pDrawLayer->IsRecording() )
pDrawLayer->AddCalcUndo( pDrawLayer->GetSdrUndoFactory().CreateUndoDeleteObject( *maNoteData.mpCaption ) );
-
// remove the object from the drawing page, delete if undo is disabled
pDrawPage->RemoveObject( maNoteData.mpCaption->GetOrdNum() );
}
@@ -555,21 +767,8 @@ void ScPostIt::RemoveCaption()
maNoteData.mpCaption = 0;
}
-void ScPostIt::UpdateCaptionLayer( bool bShow )
-{
- // no separate drawing undo needed, handled completely inside ScUndoShowHideNote
- SdrLayerID nLayer = bShow ? SC_LAYER_INTERN : SC_LAYER_HIDDEN;
- if( maNoteData.mpCaption && (nLayer != maNoteData.mpCaption->GetLayer()) )
- maNoteData.mpCaption->SetLayer( nLayer );
-}
-
// ============================================================================
-ScPostIt* ScNoteUtil::CloneNote( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote, bool bCloneCaption )
-{
- return bCloneCaption ? new ScPostIt( rDoc, rPos, rNote ) : new ScPostIt( rDoc, rNote.GetNoteData() );
-}
-
void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange )
{
// do not use ScCellIterator, it skips filtered and subtotal cells
@@ -580,25 +779,26 @@ void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange
pNote->UpdateCaptionPos( aPos );
}
-SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos,
- SdrPage& rPage, const String& rUserText, const Rectangle& rVisRect, bool bTailFront )
+SdrCaptionObj* ScNoteUtil::CreateTempCaption(
+ ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage,
+ const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront )
{
- String aFinalText = rUserText;
+ OUStringBuffer aBuffer( rUserText );
// add plain text of invisible (!) cell note (no formatting etc.)
SdrCaptionObj* pNoteCaption = 0;
- if( ScPostIt* pNote = rDoc.GetNote( rPos ) )
+ if( const ScPostIt* pNote = rDoc.GetNote( rPos ) )
{
if( !pNote->IsCaptionShown() )
{
- if( aFinalText.Len() > 0 )
- aFinalText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) );
- aFinalText.Append( pNote->GetText() );
- pNoteCaption = pNote->GetCaption();
+ if( aBuffer.getLength() > 0 )
+ aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\n--------\n" ) );
+ aBuffer.append( pNote->GetText() );
+ pNoteCaption = pNote->GetOrCreateCaption( rPos );
}
}
// create a caption if any text exists
- if( aFinalText.Len() == 0 )
+ if( aBuffer.getLength() == 0 )
return 0;
// prepare visible rectangle (add default distance to all borders)
@@ -612,12 +812,12 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
ScCaptionCreator aCreator( rDoc, rPos, true, bTailFront );
SdrCaptionObj* pCaption = aCreator.GetCaption();
// insert caption into page (needed to set caption text)
- rPage.InsertObject( pCaption );
+ rDrawPage.InsertObject( pCaption );
// set the text to the object
- pCaption->SetText( aFinalText );
+ pCaption->SetText( aBuffer.makeStringAndClear() );
// set formatting (must be done after setting text) and resize the box to fit the text
- if( pNoteCaption && (rUserText.Len() == 0) )
+ if( pNoteCaption && (rUserText.getLength() == 0) )
{
pCaption->SetMergedItemSetAndBroadcast( pNoteCaption->GetMergedItemSet() );
Rectangle aCaptRect( pCaption->GetLogicRect().TopLeft(), pNoteCaption->GetLogicRect().GetSize() );
@@ -625,7 +825,7 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
}
else
{
- aCreator.SetDefaultItems();
+ ScCaptionUtil::SetDefaultItems( *pCaption, rDoc );
// adjust caption size to text size
long nMaxWidth = ::std::min< long >( aVisRect.GetWidth() * 2 / 3, SC_NOTECAPTION_MAXWIDTH_TEMP );
pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( TRUE ) );
@@ -640,19 +840,74 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress&
return pCaption;
}
-ScPostIt* ScNoteUtil::CreateNoteFromString( ScDocument& rDoc, const ScAddress& rPos, const String& rNoteText, bool bShown )
+ScPostIt* ScNoteUtil::CreateNoteFromCaption(
+ ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj& rCaption, bool bShown )
{
- if( rNoteText.Len() == 0 )
- return 0;
- ScPostIt* pNote = new ScPostIt( rDoc, rPos, bShown );
+ ScNoteData aNoteData( bShown );
+ aNoteData.mpCaption = &rCaption;
+ ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
+ pNote->AutoStamp();
rDoc.TakeNote( rPos, pNote );
- if( SdrCaptionObj* pCaption = pNote->GetCaption() )
+ // if pNote still points to the note after TakeNote(), insertion was successful
+ if( pNote )
{
- pCaption->SetText( rNoteText );
- pNote->SetCaptionDefaultItems(); // reformat text with default font
- pCaption->SetMergedItem( SdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) );
- pCaption->SetMergedItem( SdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) );
- pCaption->AdjustTextFrameWidthAndHeight();
+ // ScNoteCaptionCreator c'tor updates the caption object to be part of a note
+ ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown );
+ }
+ return pNote;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
+ ScDocument& rDoc, const ScAddress& rPos, SfxItemSet* pItemSet,
+ OutlinerParaObject* pOutlinerObj, const Rectangle& rCaptionRect,
+ bool bShown, bool bAlwaysCreateCaption )
+{
+ OSL_ENSURE( pItemSet && pOutlinerObj, "ScNoteUtil::CreateNoteFromObjectData - item set and outliner object expected" );
+ ScNoteData aNoteData( bShown );
+ aNoteData.mxInitData.reset( new ScCaptionInitData );
+ ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+ rInitData.mxItemSet.reset( pItemSet );
+ rInitData.mxOutlinerObj.reset( pOutlinerObj );
+
+ // convert absolute caption position to relative position
+ rInitData.mbDefaultPosSize = rCaptionRect.IsEmpty();
+ if( !rInitData.mbDefaultPosSize )
+ {
+ Rectangle aCellRect = ScDrawLayer::GetCellRect( rDoc, rPos, true );
+ bool bNegPage = rDoc.IsNegativePage( rPos.Tab() );
+ rInitData.maCaptionOffset.X() = bNegPage ? (aCellRect.Left() - rCaptionRect.Right()) : (rCaptionRect.Left() - aCellRect.Right());
+ rInitData.maCaptionOffset.Y() = rCaptionRect.Top() - aCellRect.Top();
+ rInitData.maCaptionSize = rCaptionRect.GetSize();
+ }
+
+ /* Create the note and insert it into the document. If the note is
+ visible, the caption object will be created automatically. */
+ ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
+ pNote->AutoStamp();
+ rDoc.TakeNote( rPos, pNote );
+ // if pNote still points to the note after TakeNote(), insertion was successful
+ return pNote;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromString(
+ ScDocument& rDoc, const ScAddress& rPos, const OUString& rNoteText,
+ bool bShown, bool bAlwaysCreateCaption )
+{
+ ScPostIt* pNote = 0;
+ if( rNoteText.getLength() > 0 )
+ {
+ ScNoteData aNoteData( bShown );
+ aNoteData.mxInitData.reset( new ScCaptionInitData );
+ ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+ rInitData.maSimpleText = rNoteText;
+ rInitData.mbDefaultPosSize = true;
+
+ /* Create the note and insert it into the document. If the note is
+ visible, the caption object will be created automatically. */
+ pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
+ pNote->AutoStamp();
+ rDoc.TakeNote( rPos, pNote );
+ // if pNote still points to the note after TakeNote(), insertion was successful
}
return pNote;
}
diff --git a/sc/source/core/data/stlsheet.cxx b/sc/source/core/data/stlsheet.cxx
index 37dce231cbaf..bad2c664cc4d 100644
--- a/sc/source/core/data/stlsheet.cxx
+++ b/sc/source/core/data/stlsheet.cxx
@@ -176,14 +176,8 @@ SfxItemSet& __EXPORT ScStyleSheet::GetItemSet()
if ( pDoc && pDoc->IsLoadingDone() )
{
// Setzen von sinnvollen Default-Werten:
- // SfxPrinter* pPrinter = pDoc->GetPrinter();
SvxPageItem aPageItem( ATTR_PAGE );
- // #50536# PaperBin auf Default lassen,
- // nicht auf aktuelle Drucker-Einstellung umsetzen
- // SvxSizeItem aPaperSizeItem(ATTR_PAGE_SIZE,SvxPaperInfo::GetPaperSize(pPrinter) );
-
- SvxPaper aDefaultPaper = SvxPaperInfo::GetDefaultSvxPaper( Application::GetSettings().GetLanguage() );
- SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(aDefaultPaper) );
+ SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetDefaultPaperSize() );
SvxSetItem aHFSetItem(
(const SvxSetItem&)
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 03b9fc9d90be..38aabaa51a55 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -114,6 +114,7 @@
#include "progress.hxx"
#include "hints.hxx" // fuer Paint-Broadcast
#include "prnsave.hxx"
+#include "tabprotection.hxx"
// STATIC DATA -----------------------------------------------------------
@@ -132,7 +133,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
bPageSizeValid( FALSE ),
nRepeatStartX( SCCOL_REPEAT_NONE ),
nRepeatStartY( SCROW_REPEAT_NONE ),
- bProtected( FALSE ),
+ pTabProtection( NULL ),
pColWidth( NULL ),
pRowHeight( NULL ),
pColFlags( NULL ),
@@ -140,6 +141,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
pOutlineTable( NULL ),
bTableAreaValid( FALSE ),
bVisible( TRUE ),
+ bPendingRowHeights( FALSE ),
nTab( nNewTab ),
nRecalcLvl( 0 ),
pDocument( pDoc ),
@@ -249,6 +251,11 @@ void ScTable::SetVisible( BOOL bVis )
bVisible = bVis;
}
+void ScTable::SetPendingRowHeights( BOOL bSet )
+{
+ bPendingRowHeights = bSet;
+}
+
void ScTable::SetLayoutRTL( BOOL bSet )
{
bLayoutRTL = bSet;
@@ -863,6 +870,10 @@ BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
if (!ValidCol(nCol) || !ValidRow(nRow))
return FALSE;
+ if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
+ // Skip an overlapped cell.
+ return false;
+
if (bMarked && !rMark.IsCellMarked(nCol,nRow))
return FALSE;
@@ -905,7 +916,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
{
BOOL bUp = ( nMovY < 0 );
nRow = rMark.GetNextMarked( nCol, nRow, bUp );
- while ( VALIDROW(nRow) && pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN) )
+ while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
+ pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
{
// #53697# ausgeblendete ueberspringen (s.o.)
nRow += nMovY;
@@ -934,7 +946,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
else if (nRow > MAXROW)
nRow = 0;
nRow = rMark.GetNextMarked( nCol, nRow, bUp );
- while ( VALIDROW(nRow) && pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN) )
+ while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
+ pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
{
// #53697# ausgeblendete ueberspringen (s.o.)
nRow += nMovY;
@@ -1095,6 +1108,7 @@ void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nR
{
if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
{
+ InitializeNoteCaptions();
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if ( eUpdateRefMode != URM_COPY && pDrawLayer )
{
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 5b726467c3ba..59858796078c 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -117,6 +117,7 @@ BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize )
void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
if (nStartCol==0 && nEndCol==MAXCOL)
{
if (pRowHeight && pRowFlags)
@@ -143,6 +144,7 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
BOOL* pUndoOutline )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
if (nStartCol==0 && nEndCol==MAXCOL)
{
if (pRowHeight && pRowFlags)
@@ -186,6 +188,7 @@ BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
if (nStartRow==0 && nEndRow==MAXROW)
{
if (pColWidth && pColFlags)
@@ -236,6 +239,7 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
BOOL* pUndoOutline )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
if (nStartRow==0 && nEndRow==MAXROW)
{
if (pColWidth && pColFlags)
@@ -292,7 +296,7 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USH
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nDelFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
{
ScPatternAttr aPattern(pDocument->GetPool());
aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
@@ -318,7 +322,7 @@ void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nDelFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
{
ScDocumentPool* pPool = pDocument->GetPool();
SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
@@ -361,7 +365,7 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// ggf. Formeln durch Werte ersetzen
- if (bProtected)
+ if ( IsProtected() )
for (i = nCol1; i <= nCol2; i++)
pTable->aCol[i].RemoveProtected(nRow1, nRow2);
}
@@ -406,7 +410,7 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nInsFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
{
ScPatternAttr aPattern(pDocument->GetPool());
aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
@@ -484,9 +488,10 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
}
else // kopieren
{
+ ScAddress aOwnPos( nCol, nRow, nTab );
if (pCell->GetCellType() == CELLTYPE_FORMULA)
{
- pNew = pCell->CloneWithNote( *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
+ pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
// Referenzen drehen
// bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
@@ -495,7 +500,9 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
((ScFormulaCell*)pNew)->TransposeReference();
}
else
- pNew = pCell->CloneWithNote( *pDestDoc, aDestPos );
+ {
+ pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
+ }
}
pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
}
@@ -900,7 +907,15 @@ ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
{
if( ValidColRow( nCol, nRow ) )
+ {
aCol[ nCol ].TakeNote( nRow, rpNote );
+ if( rpNote && rpNote->GetNoteData().mxInitData.get() )
+ {
+ if( !mxUninitNotes.get() )
+ mxUninitNotes.reset( new ScAddress2DVec );
+ mxUninitNotes->push_back( ScAddress2D( nCol, nRow ) );
+ }
+ }
else
DELETEZ( rpNote );
}
@@ -919,6 +934,17 @@ void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
}
+void ScTable::InitializeNoteCaptions( bool bForced )
+{
+ if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) )
+ {
+ for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt )
+ if( ScPostIt* pNote = GetNote( aIt->first, aIt->second ) )
+ pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) );
+ mxUninitNotes.reset();
+ }
+}
+
CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
{
if (ValidColRow( nCol, nRow ))
@@ -1457,7 +1483,7 @@ BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
BOOL bIsEditable = TRUE;
if ( nLockCount )
bIsEditable = FALSE;
- else if ( bProtected && !pDocument->IsScenario(nTab) )
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
{
if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
{
@@ -1524,7 +1550,7 @@ BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
BOOL bIsEditable = TRUE;
if ( nLockCount )
bIsEditable = FALSE;
- else if ( bProtected && !pDocument->IsScenario(nTab))
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
{
if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
{
@@ -1918,6 +1944,7 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
if ( nNewWidth != pColWidth[nCol] )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
@@ -1947,6 +1974,7 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
if ( nNewHeight != nOldHeight )
{
nRecalcLvl++;
+ InitializeNoteCaptions();
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
@@ -1969,6 +1997,7 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
{
nRecalcLvl++;
+ InitializeNoteCaptions();
if (!nNewHeight)
{
DBG_ERROR("Zeilenhoehe 0 in SetRowHeight");
@@ -2235,6 +2264,7 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
if (bWasVis != bShow)
{
nRecalcLvl++;
+ InitializeNoteCaptions();
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
{
@@ -2272,6 +2302,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
if (bWasVis != bShow)
{
nRecalcLvl++;
+ InitializeNoteCaptions();
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
{
@@ -2307,6 +2338,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
BYTE nFlags = pRowFlags->GetValue(nRow);
BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
nRecalcLvl++;
+ InitializeNoteCaptions();
if (bWasVis != bShow)
{
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
@@ -2348,6 +2380,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
{
SCROW nStartRow = nRow1;
nRecalcLvl++;
+ InitializeNoteCaptions();
while (nStartRow <= nRow2)
{
BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
@@ -2400,6 +2433,7 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
{
SCROW nStartRow = nRow1;
nRecalcLvl++;
+ InitializeNoteCaptions();
while (nStartRow <= nRow2)
{
BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
@@ -2667,7 +2701,7 @@ void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SC
pCell = aCol[nCol].GetCell( nRow );
if (pCell)
if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
+ if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
DiffSign( aRef.aStart.Row(), nRow ) ==
@@ -2698,7 +2732,7 @@ void ScTable::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SC
while ( aIter.Next( nRow, pCell ) && !bFound )
{
if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
+ if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
if ( aRef.aStart.Row() == nRow && aRef.aEnd.Row() == nRow &&
aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
DiffSign( aRef.aStart.Col(), nCol ) ==
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 74f2a97e9c2e..ae299fdf5fca 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1022,12 +1022,19 @@ BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
}
}
else if ( (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL) ||
+ (rEntry.eOp == SC_CONTAINS || rEntry.eOp == SC_DOES_NOT_CONTAIN ||
+ rEntry.eOp == SC_BEGINS_WITH || rEntry.eOp == SC_ENDS_WITH ||
+ rEntry.eOp == SC_DOES_NOT_BEGIN_WITH || rEntry.eOp == SC_DOES_NOT_END_WITH) ||
(rEntry.bQueryByString && (pCell ? pCell->HasStringData() :
HasStringData(
static_cast<SCCOL>(rEntry.nField),
nRow))))
{ // by String
String aCellStr;
+ if( rEntry.eOp == SC_CONTAINS || rEntry.eOp == SC_DOES_NOT_CONTAIN
+ || rEntry.eOp == SC_BEGINS_WITH || rEntry.eOp == SC_ENDS_WITH
+ || rEntry.eOp == SC_DOES_NOT_BEGIN_WITH || rEntry.eOp == SC_DOES_NOT_END_WITH )
+ bMatchWholeCell = FALSE;
if ( pCell )
{
if (pCell->GetCellType() != CELLTYPE_NOTE)
@@ -1040,7 +1047,10 @@ BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
GetInputString( static_cast<SCCOL>(rEntry.nField), nRow, aCellStr );
BOOL bRealRegExp = (rParam.bRegExp && ((rEntry.eOp == SC_EQUAL)
- || (rEntry.eOp == SC_NOT_EQUAL)));
+ || (rEntry.eOp == SC_NOT_EQUAL) || (rEntry.eOp == SC_CONTAINS)
+ || (rEntry.eOp == SC_DOES_NOT_CONTAIN) || (rEntry.eOp == SC_BEGINS_WITH)
+ || (rEntry.eOp == SC_ENDS_WITH) || (rEntry.eOp == SC_DOES_NOT_BEGIN_WITH)
+ || (rEntry.eOp == SC_DOES_NOT_END_WITH)));
BOOL bTestRegExp = (pbTestEqualCondition && rParam.bRegExp
&& ((rEntry.eOp == SC_LESS_EQUAL)
|| (rEntry.eOp == SC_GREATER_EQUAL)));
@@ -1048,20 +1058,61 @@ BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
{
xub_StrLen nStart = 0;
xub_StrLen nEnd = aCellStr.Len();
- BOOL bMatch = (BOOL) rEntry.GetSearchTextPtr( rParam.bCaseSens )
- ->SearchFrwrd( aCellStr, &nStart, &nEnd );
+
// from 614 on, nEnd is behind the found text
+ BOOL bMatch = FALSE;
+ if ( rEntry.eOp == SC_ENDS_WITH || rEntry.eOp == SC_DOES_NOT_END_WITH )
+ {
+ nEnd = 0;
+ nStart = aCellStr.Len();
+ bMatch = (BOOL) rEntry.GetSearchTextPtr( rParam.bCaseSens )
+ ->SearchBkwrd( aCellStr, &nStart, &nEnd );
+ }
+ else
+ {
+ bMatch = (BOOL) rEntry.GetSearchTextPtr( rParam.bCaseSens )
+ ->SearchFrwrd( aCellStr, &nStart, &nEnd );
+ }
if ( bMatch && bMatchWholeCell
&& (nStart != 0 || nEnd != aCellStr.Len()) )
bMatch = FALSE; // RegExp must match entire cell string
if ( bRealRegExp )
- bOk = ((rEntry.eOp == SC_NOT_EQUAL) ? !bMatch : bMatch);
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ case SC_CONTAINS:
+ bOk = bMatch;
+ break;
+ case SC_NOT_EQUAL:
+ case SC_DOES_NOT_CONTAIN:
+ bOk = !bMatch;
+ break;
+ case SC_BEGINS_WITH:
+ bOk = ( bMatch && (nStart == 0) );
+ break;
+ case SC_DOES_NOT_BEGIN_WITH:
+ bOk = !( bMatch && (nStart == 0) );
+ break;
+ case SC_ENDS_WITH:
+ bOk = ( bMatch && (nEnd == aCellStr.Len()) );
+ break;
+ case SC_DOES_NOT_END_WITH:
+ bOk = !( bMatch && (nEnd == aCellStr.Len()) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
else
bTestEqual = bMatch;
}
if ( !bRealRegExp )
{
- if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL )
+ if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL
+ || rEntry.eOp == SC_CONTAINS || rEntry.eOp == SC_DOES_NOT_CONTAIN
+ || rEntry.eOp == SC_BEGINS_WITH || rEntry.eOp == SC_ENDS_WITH
+ || rEntry.eOp == SC_DOES_NOT_BEGIN_WITH || rEntry.eOp == SC_DOES_NOT_END_WITH )
{
if ( !rEntry.bQueryByString && rEntry.pStr->Len() == 0 )
{
@@ -1069,22 +1120,54 @@ BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
// the query value is assigned directly, and the string is empty. In that case,
// don't find any string (isEqual would find empty string results in formula cells).
bOk = FALSE;
+ if ( rEntry.eOp == SC_NOT_EQUAL )
+ bOk = !bOk;
}
else if ( bMatchWholeCell )
+ {
bOk = pTransliteration->isEqual( aCellStr, *rEntry.pStr );
+ if ( rEntry.eOp == SC_NOT_EQUAL )
+ bOk = !bOk;
+ }
else
{
- ::com::sun::star::uno::Sequence< sal_Int32 > xOff;
String aCell( pTransliteration->transliterate(
aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(),
- &xOff ) );
+ NULL ) );
String aQuer( pTransliteration->transliterate(
*rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(),
- &xOff ) );
- bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND);
+ NULL ) );
+ xub_StrLen nIndex = (rEntry.eOp == SC_ENDS_WITH
+ || rEntry.eOp == SC_DOES_NOT_END_WITH)? (aCell.Len()-aQuer.Len()):0;
+ xub_StrLen nStrPos = aCell.Search( aQuer, nIndex );
+ switch (rEntry.eOp)
+ {
+ case SC_EQUAL:
+ case SC_CONTAINS:
+ bOk = ( nStrPos != STRING_NOTFOUND );
+ break;
+ case SC_NOT_EQUAL:
+ case SC_DOES_NOT_CONTAIN:
+ bOk = ( nStrPos == STRING_NOTFOUND );
+ break;
+ case SC_BEGINS_WITH:
+ bOk = ( nStrPos == 0 );
+ break;
+ case SC_DOES_NOT_BEGIN_WITH:
+ bOk = ( nStrPos != 0 );
+ break;
+ case SC_ENDS_WITH:
+ bOk = ( nStrPos + aQuer.Len() == aCell.Len() );
+ break;
+ case SC_DOES_NOT_END_WITH:
+ bOk = ( nStrPos + aQuer.Len() != aCell.Len() );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
}
- if ( rEntry.eOp == SC_NOT_EQUAL )
- bOk = !bOk;
}
else
{ // use collator here because data was probably sorted
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index a6ef174e326c..021385678160 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -51,8 +51,11 @@
#include "stlpool.hxx"
#include "stlsheet.hxx"
#include "brdcst.hxx"
+#include "tabprotection.hxx"
#include "globstr.hrc"
+using ::com::sun::star::uno::Sequence;
+
// STATIC DATA -----------------------------------------------------------
#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
@@ -273,6 +276,24 @@ void ScTable::SetPageSize( const Size& rSize )
bPageSizeValid = FALSE;
}
+BOOL ScTable::IsProtected() const
+{
+ return pTabProtection.get() && pTabProtection->isProtected();
+}
+
+void ScTable::SetProtection(const ScTableProtection* pProtect)
+{
+ if (pProtect)
+ pTabProtection.reset(new ScTableProtection(*pProtect));
+ else
+ pTabProtection.reset(NULL);
+}
+
+ScTableProtection* ScTable::GetProtection()
+{
+ return pTabProtection.get();
+}
+
Size ScTable::GetPageSize() const
{
if ( bPageSizeValid )
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 443d0f23e3d0..9ca7b29b745e 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -219,7 +219,7 @@ BOOL ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
// NB: rich text format is lost.
// This is also true of Cells.
if( ScPostIt* pNote = pCell->GetNote() )
- pNote->SetText( aString );
+ pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
}
else if ( cMatrixFlag != MM_NONE )
{ // #60558# Matrix nicht zerreissen
diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx
new file mode 100644
index 000000000000..1620c5194e92
--- /dev/null
+++ b/sc/source/core/data/tabprotection.cxx
@@ -0,0 +1,465 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tabprotection.cxx,v $
+ * $Revision: 1.1.4.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "tabprotection.hxx"
+#include "tools/debug.hxx"
+#include "svtools/PasswordHelper.hxx"
+#include "document.hxx"
+
+#define DEBUG_TAB_PROTECTION 0
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+// ============================================================================
+
+bool ScPassHashHelper::needsPassHashRegen(const ScDocument& rDoc, ScPasswordHash eHash)
+{
+ if (rDoc.IsDocProtected())
+ {
+ const ScDocProtection* p = rDoc.GetDocProtection();
+ if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash))
+ return true;
+ }
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ const ScTableProtection* p = rDoc.GetTabProtection(i);
+ if (!p || !p->isProtected())
+ // Sheet not protected. Skip it.
+ continue;
+
+ if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash))
+ return true;
+ }
+
+ return false;
+}
+
+// ============================================================================
+
+ScPassHashProtectable::~ScPassHashProtectable()
+{
+}
+
+// ============================================================================
+
+static sal_uInt16 lcl_getXLHashFromChar(const sal_Char* szPassword)
+{
+ sal_uInt16 cchPassword = static_cast< sal_uInt16 >( strlen(szPassword) );
+ sal_uInt16 wPasswordHash = 0;
+ if (!cchPassword)
+ return wPasswordHash;
+
+ const char* pch = &szPassword[cchPassword];
+ while (pch-- != szPassword)
+ {
+ wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
+ ((wPasswordHash << 1) & 0x7fff);
+ wPasswordHash ^= *pch;
+ }
+
+ wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
+ ((wPasswordHash << 1) & 0x7fff);
+
+ wPasswordHash ^= (0x8000 | ('N' << 8) | 'K');
+ wPasswordHash ^= cchPassword;
+
+ return wPasswordHash;
+}
+
+static Sequence<sal_Int8> lcl_getXLHash(const String& aPassText)
+{
+ const sal_Char* szBuf = OUStringToOString(OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr();
+ sal_uInt16 nHash = lcl_getXLHashFromChar(szBuf);
+ Sequence<sal_Int8> aHash(2);
+ aHash[0] = (nHash >> 8) & 0xFF;
+ aHash[1] = nHash & 0xFF;
+ return aHash;
+}
+
+class ScTableProtectionImpl
+{
+public:
+ static ::com::sun::star::uno::Sequence<sal_Int8> hashPassword(const String& aPassText, ScPasswordHash eHash = PASSHASH_OOO);
+
+ explicit ScTableProtectionImpl(SCSIZE nOptSize);
+ explicit ScTableProtectionImpl(const ScTableProtectionImpl& r);
+
+ bool isProtected() const;
+ bool isProtectedWithPass() const;
+ void setProtected(bool bProtected);
+
+ bool isPasswordEmpty() const;
+ bool hasPasswordHash(ScPasswordHash eHash) const;
+ void setPassword(const String& aPassText);
+ ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash = PASSHASH_OOO);
+ bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(SCSIZE nOptId) const;
+ void setOption(SCSIZE nOptId, bool bEnabled);
+
+private:
+ String maPassText;
+ ::com::sun::star::uno::Sequence<sal_Int8> maPassHash;
+ ::std::vector<bool> maOptions;
+ bool mbEmptyPass;
+ bool mbProtected;
+ ScPasswordHash meHash;
+};
+
+Sequence<sal_Int8> ScTableProtectionImpl::hashPassword(const String& aPassText, ScPasswordHash eHash)
+{
+ Sequence<sal_Int8> aHash;
+ switch (eHash)
+ {
+ case PASSHASH_XL:
+ aHash = lcl_getXLHash(aPassText);
+ break;
+ case PASSHASH_OOO:
+ default:
+ SvPasswordHelper::GetHashPassword(aHash, aPassText);
+ break;
+ }
+ return aHash;
+}
+
+ScTableProtectionImpl::ScTableProtectionImpl(SCSIZE nOptSize) :
+ maOptions(nOptSize),
+ mbEmptyPass(true),
+ mbProtected(false),
+ meHash(PASSHASH_OOO)
+{
+}
+
+ScTableProtectionImpl::ScTableProtectionImpl(const ScTableProtectionImpl& r) :
+ maPassText(r.maPassText),
+ maPassHash(r.maPassHash),
+ maOptions(r.maOptions),
+ mbEmptyPass(r.mbEmptyPass),
+ mbProtected(r.mbProtected),
+ meHash(r.meHash)
+{
+}
+
+bool ScTableProtectionImpl::isProtected() const
+{
+ return mbProtected;
+}
+
+bool ScTableProtectionImpl::isProtectedWithPass() const
+{
+ if (!mbProtected)
+ return false;
+
+ return maPassText.Len() || maPassHash.getLength();
+}
+
+void ScTableProtectionImpl::setProtected(bool bProtected)
+{
+ mbProtected = bProtected;
+ // We need to keep the old password even when the protection is off. So,
+ // don't erase the password data here.
+}
+
+void ScTableProtectionImpl::setPassword(const String& aPassText)
+{
+ // We can't hash it here because we don't know whether this document will
+ // get saved to Excel or ODF, depending on which we will need to use a
+ // different hashing algorithm. One alternative is to hash it using all
+ // hash algorithms that we support, and store them all.
+
+ maPassText = aPassText;
+ mbEmptyPass = aPassText.Len() == 0;
+ if (mbEmptyPass)
+ {
+ maPassHash = Sequence<sal_Int8>();
+ }
+}
+
+bool ScTableProtectionImpl::isPasswordEmpty() const
+{
+ return mbEmptyPass;
+}
+
+bool ScTableProtectionImpl::hasPasswordHash(ScPasswordHash eHash) const
+{
+ if (mbEmptyPass)
+ return true;
+
+ if (maPassText.Len())
+ return true;
+
+ if (meHash == eHash)
+ return true;
+
+ return false;
+}
+
+Sequence<sal_Int8> ScTableProtectionImpl::getPasswordHash(ScPasswordHash eHash) const
+{
+ if (mbEmptyPass)
+ // Flaged as empty.
+ return Sequence<sal_Int8>();
+
+ if (maPassText.Len())
+ // Cleartext password exists. Hash it.
+ return hashPassword(maPassText, eHash);
+
+ if (meHash == eHash)
+ // Stored hash exists.
+ return maPassHash;
+
+ // Failed to find a matching hash.
+ return Sequence<sal_Int8>();
+}
+
+void ScTableProtectionImpl::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ sal_Int32 nLen = aPassword.getLength();
+ mbEmptyPass = nLen <= 0 ? true : false;
+ meHash = eHash;
+ maPassHash = aPassword;
+
+#if DEBUG_TAB_PROTECTION
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ printf("%2.2X ", static_cast<sal_uInt8>(aPassword[i]));
+ printf("\n");
+#endif
+}
+
+bool ScTableProtectionImpl::verifyPassword(const String& aPassText) const
+{
+#if DEBUG_TAB_PROTECTION
+ fprintf(stdout, "ScTableProtectionImpl::verifyPassword: input = '%s'\n",
+ OUStringToOString(rtl::OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr());
+#endif
+
+ if (mbEmptyPass)
+ return aPassText.Len() == 0;
+
+ if (maPassText.Len())
+ // Clear text password exists, and this one takes precedence.
+ return aPassText.Equals(maPassText);
+
+ Sequence<sal_Int8> aHash = hashPassword(aPassText, meHash);
+
+#if DEBUG_TAB_PROTECTION
+ fprintf(stdout, "ScTableProtectionImpl::verifyPassword: hash = ");
+ for (sal_Int32 i = 0; i < aHash.getLength(); ++i)
+ printf("%2.2X ", static_cast<sal_uInt8>(aHash[i]));
+ printf("\n");
+#endif
+
+ return aHash == maPassHash;
+}
+
+bool ScTableProtectionImpl::isOptionEnabled(SCSIZE nOptId) const
+{
+ if ( maOptions.size() <= static_cast<size_t>(nOptId) )
+ {
+ DBG_ERROR("ScTableProtectionImpl::isOptionEnabled: wrong size");
+ return false;
+ }
+
+ return maOptions[nOptId];
+}
+
+void ScTableProtectionImpl::setOption(SCSIZE nOptId, bool bEnabled)
+{
+ if ( maOptions.size() <= static_cast<size_t>(nOptId) )
+ {
+ DBG_ERROR("ScTableProtectionImpl::setOption: wrong size");
+ return;
+ }
+
+ maOptions[nOptId] = bEnabled;
+}
+
+// ============================================================================
+
+ScDocProtection::ScDocProtection() :
+ mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScDocProtection::NONE)))
+{
+}
+
+ScDocProtection::ScDocProtection(const ScDocProtection& r) :
+ ScPassHashProtectable(),
+ mpImpl(new ScTableProtectionImpl(*r.mpImpl))
+{
+}
+
+ScDocProtection::~ScDocProtection()
+{
+}
+
+bool ScDocProtection::isProtected() const
+{
+ return mpImpl->isProtected();
+}
+
+bool ScDocProtection::isProtectedWithPass() const
+{
+ return mpImpl->isProtectedWithPass();
+}
+
+void ScDocProtection::setProtected(bool bProtected)
+{
+ mpImpl->setProtected(bProtected);
+
+ // Currently Calc doesn't support document protection options. So, let's
+ // assume that when the document is protected, its structure is protected.
+ // We need to do this for Excel export.
+ mpImpl->setOption(ScDocProtection::STRUCTURE, bProtected);
+}
+
+bool ScDocProtection::isPasswordEmpty() const
+{
+ return mpImpl->isPasswordEmpty();
+}
+
+bool ScDocProtection::hasPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->hasPasswordHash(eHash);
+}
+
+void ScDocProtection::setPassword(const String& aPassText)
+{
+ mpImpl->setPassword(aPassText);
+}
+
+uno::Sequence<sal_Int8> ScDocProtection::getPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->getPasswordHash(eHash);
+}
+
+void ScDocProtection::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ mpImpl->setPasswordHash(aPassword, eHash);
+}
+
+bool ScDocProtection::verifyPassword(const String& aPassText) const
+{
+ return mpImpl->verifyPassword(aPassText);
+}
+
+bool ScDocProtection::isOptionEnabled(Option eOption) const
+{
+ return mpImpl->isOptionEnabled(eOption);
+}
+
+void ScDocProtection::setOption(Option eOption, bool bEnabled)
+{
+ mpImpl->setOption(eOption, bEnabled);
+}
+
+// ============================================================================
+
+ScTableProtection::ScTableProtection() :
+ mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScTableProtection::NONE)))
+{
+ // Set default values for the options.
+ mpImpl->setOption(SELECT_LOCKED_CELLS, true);
+ mpImpl->setOption(SELECT_UNLOCKED_CELLS, true);
+}
+
+ScTableProtection::ScTableProtection(const ScTableProtection& r) :
+ ScPassHashProtectable(),
+ mpImpl(new ScTableProtectionImpl(*r.mpImpl))
+{
+}
+
+ScTableProtection::~ScTableProtection()
+{
+}
+
+bool ScTableProtection::isProtected() const
+{
+ return mpImpl->isProtected();
+}
+
+bool ScTableProtection::isProtectedWithPass() const
+{
+ return mpImpl->isProtectedWithPass();
+}
+
+void ScTableProtection::setProtected(bool bProtected)
+{
+ mpImpl->setProtected(bProtected);
+}
+
+bool ScTableProtection::isPasswordEmpty() const
+{
+ return mpImpl->isPasswordEmpty();
+}
+
+bool ScTableProtection::hasPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->hasPasswordHash(eHash);
+}
+
+void ScTableProtection::setPassword(const String& aPassText)
+{
+ mpImpl->setPassword(aPassText);
+}
+
+Sequence<sal_Int8> ScTableProtection::getPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->getPasswordHash(eHash);
+}
+
+void ScTableProtection::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ mpImpl->setPasswordHash(aPassword, eHash);
+}
+
+bool ScTableProtection::verifyPassword(const String& aPassText) const
+{
+ return mpImpl->verifyPassword(aPassText);
+}
+
+bool ScTableProtection::isOptionEnabled(Option eOption) const
+{
+ return mpImpl->isOptionEnabled(eOption);
+}
+
+void ScTableProtection::setOption(Option eOption, bool bEnabled)
+{
+ mpImpl->setOption(eOption, bEnabled);
+}
+
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 09c1db07c464..9bb8bff1081f 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -76,8 +76,9 @@ SV_IMPL_OP_PTRARR_SORT( ScValidationEntries_Impl, ScValidationDataPtr );
ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
const String& rExpr1, const String& rExpr2,
ScDocument* pDocument, const ScAddress& rPos,
- const formula::FormulaGrammar::Grammar eGrammar ) :
- ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, eGrammar ),
+ const String& rExprNmsp1, const String& rExprNmsp2,
+ FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
+ ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
nKey( 0 ),
eDataMode( eMode ),
eErrorStyle( SC_VALERR_STOP ),
@@ -695,6 +696,40 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings,
SCSIZE nCol, nRow, nCols, nRows, n = 0;
pValues->GetDimensions( nCols, nRows );
+ BOOL bRef = FALSE;
+ ScRange aRange;
+
+ ScTokenArray* pArr = (ScTokenArray*) &rTokArr;
+ pArr->Reset();
+ ScToken* t = NULL;
+ if (pArr->GetLen() == 1 && (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL)
+ {
+ if (t->GetOpCode() == ocDBArea)
+ {
+ if( ScDBData* pDBData = pDocument->GetDBCollection()->FindIndex( t->GetIndex() ) )
+ {
+ pDBData->GetArea(aRange);
+ bRef = TRUE;
+ }
+ }
+ else if (t->GetOpCode() == ocName)
+ {
+ ScRangeData* pName = pDocument->GetRangeName()->FindIndex( t->GetIndex() );
+ if (pName && pName->IsReference(aRange))
+ {
+ bRef = TRUE;
+ }
+ }
+ else if (t->GetType() != svIndex)
+ {
+ t->CalcAbsIfRel(rPos);
+ if (pArr->IsValidReference(aRange))
+ {
+ bRef = TRUE;
+ }
+ }
+ }
+
/* XL artificially limits things to a single col or row in the UI but does
* not list the constraint in MOOXml. If a defined name or INDIRECT
* resulting in 1D is entered in the UI and the definition later modified
@@ -735,7 +770,15 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings,
{
// FIXME FIXME FIXME
// Feature regression. Date formats are lost passing through the matrix
- pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr );
+ //pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr );
+ //For external reference and a formula that results in an area or array, date formats are still lost.
+ if ( bRef )
+ {
+ pDocument->GetInputString((SCCOL)(nCol+aRange.aStart.Col()),
+ (SCROW)(nRow+aRange.aStart.Row()), aRange.aStart.Tab() , aValStr);
+ }
+ else
+ pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr );
}
if( pCell && rMatch < 0 )
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 3d783e74c03d..9fcf743c1e85 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -70,6 +70,21 @@ struct ScCompare
}
};
+struct ScCompareOptions
+{
+ ScQueryEntry aQueryEntry;
+ bool bRegEx;
+ bool bMatchWholeCell;
+ bool bIgnoreCase;
+
+ ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
+private:
+ // Not implemented, prevent usage.
+ ScCompareOptions();
+ ScCompareOptions( const ScCompareOptions & );
+ ScCompareOptions& operator=( const ScCompareOptions & );
+};
+
class ScToken;
#define MAXSTACK (4096 / sizeof(formula::FormulaToken*))
@@ -356,9 +371,16 @@ void ScChoseJump();
// Returns true if last jump was executed and result matrix pushed.
bool JumpMatrix( short nStackLevel );
-double CompareFunc( const ScCompare& rComp );
+/** @param pOptions
+ NULL means case sensitivity document option is to be used!
+ */
+double CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions = NULL );
double Compare();
-ScMatrixRef CompareMat();
+/** @param pOptions
+ NULL means case sensitivity document option is to be used!
+ */
+ScMatrixRef CompareMat( ScCompareOptions* pOptions = NULL );
+ScMatrixRef QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions );
void ScEqual();
void ScNotEqual();
void ScLess();
diff --git a/sc/source/core/inc/refupdat.hxx b/sc/source/core/inc/refupdat.hxx
index 0461578db0a6..2a8b17335fbf 100644
--- a/sc/source/core/inc/refupdat.hxx
+++ b/sc/source/core/inc/refupdat.hxx
@@ -82,7 +82,7 @@ public:
ScComplexRefData& rRef, BOOL bWrap, BOOL bAbsolute );
static void MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
- ScComplexRefData& rRef );
+ SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef );
/// Before calling, the absolute references must be up-to-date!
static ScRefUpdateRes UpdateTranspose( ScDocument* pDoc,
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 8b13374fe501..b38d5b52e4f5 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -1126,39 +1126,48 @@ lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
SCTAB nDefTab, ScRefAddress& rRefAddress,
- const ScAddress::Details& rDetails )
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo /* = NULL */ )
{
- ScAddress aAddr( 0, 0, nDefTab );
- USHORT nRes = lcl_ScAddress_Parse( rRefString.GetBuffer(), pDoc, aAddr, rDetails, NULL );
- if( nRes & SCA_VALID )
+ bool bRet = false;
+ if (pExtInfo || (ScGlobal::FindUnquoted( rRefString, SC_COMPILER_FILE_TAB_SEP) == STRING_NOTFOUND))
{
- rRefAddress.Set( aAddr,
- ((nRes & SCA_COL_ABSOLUTE) == 0),
- ((nRes & SCA_ROW_ABSOLUTE) == 0),
- ((nRes & SCA_TAB_ABSOLUTE) == 0));
- return TRUE;
+ ScAddress aAddr( 0, 0, nDefTab );
+ USHORT nRes = aAddr.Parse( rRefString, pDoc, rDetails, pExtInfo);
+ if ( nRes & SCA_VALID )
+ {
+ rRefAddress.Set( aAddr,
+ ((nRes & SCA_COL_ABSOLUTE) == 0),
+ ((nRes & SCA_ROW_ABSOLUTE) == 0),
+ ((nRes & SCA_TAB_ABSOLUTE) == 0));
+ bRet = true;
+ }
}
- else
- return FALSE;
+ return bRet;
}
bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab,
ScRefAddress& rStartRefAddress, ScRefAddress& rEndRefAddress,
- const ScAddress::Details& rDetails )
+ const ScAddress::Details& rDetails,
+ ScAddress::ExternalInfo* pExtInfo /* = NULL */ )
{
- BOOL bRet = FALSE;
- // FIXME : This will break for Lotus
- xub_StrLen nPos = rRefString.Search(':');
- if (nPos != STRING_NOTFOUND)
+ bool bRet = false;
+ if (pExtInfo || (ScGlobal::FindUnquoted( rRefString, SC_COMPILER_FILE_TAB_SEP) == STRING_NOTFOUND))
{
- String aTmp( rRefString );
- sal_Unicode* p = aTmp.GetBufferAccess();
- p[ nPos ] = 0;
- if( ConvertSingleRef( pDoc, p, nDefTab, rStartRefAddress, rDetails ) )
+ ScRange aRange( ScAddress( 0, 0, nDefTab));
+ USHORT nRes = aRange.Parse( rRefString, pDoc, rDetails, pExtInfo);
+ if ( nRes & SCA_VALID )
{
- nDefTab = rStartRefAddress.Tab();
- bRet = ConvertSingleRef( pDoc, p + nPos + 1, nDefTab, rEndRefAddress, rDetails );
+ rStartRefAddress.Set( aRange.aStart,
+ ((nRes & SCA_COL_ABSOLUTE) == 0),
+ ((nRes & SCA_ROW_ABSOLUTE) == 0),
+ ((nRes & SCA_TAB_ABSOLUTE) == 0));
+ rEndRefAddress.Set( aRange.aEnd,
+ ((nRes & SCA_COL2_ABSOLUTE) == 0),
+ ((nRes & SCA_ROW2_ABSOLUTE) == 0),
+ ((nRes & SCA_TAB2_ABSOLUTE) == 0));
+ bRet = true;
}
}
return bRet;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index e148f3ab8516..bc2266cbd3c8 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -68,11 +68,14 @@
#include "cell.hxx"
#include "dociter.hxx"
#include "docoptio.hxx"
-#include "formula/errorcodes.hxx"
+#include <formula/errorcodes.hxx>
#include "parclass.hxx"
#include "autonamecache.hxx"
#include "externalrefmgr.hxx"
#include "rangeutl.hxx"
+#include "convuno.hxx"
+#include "tokenuno.hxx"
+#include "formulaparserpool.hxx"
using namespace formula;
using namespace ::com::sun::star;
@@ -408,28 +411,36 @@ void ScCompiler::InitCharClassEnglish()
void ScCompiler::SetGrammar( const FormulaGrammar::Grammar eGrammar )
{
- DBG_ASSERT( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "ScCompiler::SetGrammar: don't passFormulaGrammar::GRAM_UNSPECIFIED");
+ DBG_ASSERT( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "ScCompiler::SetGrammar: don't pass FormulaGrammar::GRAM_UNSPECIFIED");
if (eGrammar == GetGrammar())
return; // nothing to be done
- FormulaGrammar::Grammar eMyGrammar = eGrammar;
- const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( eMyGrammar);
- OpCodeMapPtr xMap( GetOpCodeMap( nFormulaLanguage));
- DBG_ASSERT( xMap, "ScCompiler::SetGrammar: unknown formula language");
- if (!xMap)
+ if( eGrammar == FormulaGrammar::GRAM_EXTERNAL )
{
- xMap = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
- eMyGrammar = xMap->getGrammar();
+ meGrammar = eGrammar;
+ mxSymbols = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
}
+ else
+ {
+ FormulaGrammar::Grammar eMyGrammar = eGrammar;
+ const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( eMyGrammar);
+ OpCodeMapPtr xMap = GetOpCodeMap( nFormulaLanguage);
+ DBG_ASSERT( xMap, "ScCompiler::SetGrammar: unknown formula language");
+ if (!xMap)
+ {
+ xMap = GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
+ eMyGrammar = xMap->getGrammar();
+ }
- // Save old grammar for call to SetGrammarAndRefConvention().
- FormulaGrammar::Grammar eOldGrammar = GetGrammar();
- // This also sets the grammar associated with the map!
- SetFormulaLanguage( xMap);
+ // Save old grammar for call to SetGrammarAndRefConvention().
+ FormulaGrammar::Grammar eOldGrammar = GetGrammar();
+ // This also sets the grammar associated with the map!
+ SetFormulaLanguage( xMap);
- // Override if necessary.
- if (eMyGrammar != GetGrammar())
- SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+ // Override if necessary.
+ if (eMyGrammar != GetGrammar())
+ SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+ }
}
@@ -1811,9 +1822,11 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra
aPos( rPos ),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
+ mnRangeOpPosInSymbol(-1),
pConv( pConvOOO_A1 ),
mbCloseBrackets( true ),
- mbExtendedErrorDetection( false )
+ mbExtendedErrorDetection( false ),
+ mbRewind( false )
{
nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
}
@@ -1824,9 +1837,11 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
aPos( rPos ),
pCharClass( ScGlobal::pCharClass ),
mnPredetectedReference(0),
+ mnRangeOpPosInSymbol(-1),
pConv( pConvOOO_A1 ),
mbCloseBrackets( true ),
- mbExtendedErrorDetection( false )
+ mbExtendedErrorDetection( false ),
+ mbRewind( false )
{
nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
}
@@ -1962,7 +1977,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
sal_Unicode c = *pSrc;
sal_Unicode cLast = 0;
bool bQuote = false;
- bool bRangeOp = false;
+ mnRangeOpPosInSymbol = -1;
ScanState eState = ssGetChar;
xub_StrLen nSpaces = 0;
sal_Unicode cSep = mxSymbols->getSymbol( ocSep).GetChar(0);
@@ -2110,11 +2125,11 @@ Label_MaskStateMachine:
else
*pSym++ = c;
}
- else if (c == ':' && !bRangeOp)
+ else if (c == ':' && mnRangeOpPosInSymbol < 0)
{
// One range operator may form Sheet1.A:A, which we need to
// pass as one entity to IsReference().
- bRangeOp = true;
+ mnRangeOpPosInSymbol = pSym - &cSymbol[0];
if( pSym == &cSymbol[ MAXSTRLEN-1 ] )
{
SetError(errStringOverflow);
@@ -2409,7 +2424,7 @@ Label_MaskStateMachine:
{
nSrcPos = sal::static_int_cast<xub_StrLen>( nSrcPos + nSpaces );
String aSymbol;
- bRangeOp = false;
+ mnRangeOpPosInSymbol = -1;
USHORT nErr = 0;
do
{
@@ -2438,9 +2453,9 @@ Label_MaskStateMachine:
bi18n = (c == cSheetSep || c == SC_COMPILER_FILE_TAB_SEP);
}
// One range operator restarts parsing for second reference.
- if (c == ':' && !bRangeOp)
+ if (c == ':' && mnRangeOpPosInSymbol < 0)
{
- bRangeOp = true;
+ mnRangeOpPosInSymbol = aSymbol.Len();
bi18n = true;
}
if ( bi18n )
@@ -2460,6 +2475,14 @@ Label_MaskStateMachine:
nSrcPos = sal::static_int_cast<xub_StrLen>( pSrc - pStart );
*pSym = 0;
}
+ if (mnRangeOpPosInSymbol >= 0 && mnRangeOpPosInSymbol == (pSym-1) - &cSymbol[0])
+ {
+ // This is a trailing range operator, which is nonsense. Will be caught
+ // in next round.
+ mnRangeOpPosInSymbol = -1;
+ *--pSym = 0;
+ --nSrcPos;
+ }
if ( bAutoCorrect )
aCorrectedSymbol = cSymbol;
if (bAutoIntersection && nSpaces > 1)
@@ -2835,8 +2858,21 @@ BOOL ScCompiler::IsReference( const String& rName )
// Though the range operator is handled explicitly, when encountering
// something like Sheet1.A:A we will have to treat it as one entity if it
// doesn't pass as single cell reference.
- if (ScGlobal::FindUnquoted( rName, ':') != STRING_NOTFOUND)
- return IsDoubleReference( rName);
+ if (mnRangeOpPosInSymbol > 0) // ":foo" would be nonsense
+ {
+ if (IsDoubleReference( rName))
+ return true;
+ // Now try with a symbol up to the range operator, rewind source
+ // position.
+ sal_Int32 nLen = mnRangeOpPosInSymbol;
+ while (cSymbol[++nLen])
+ ;
+ cSymbol[mnRangeOpPosInSymbol] = 0;
+ nSrcPos -= static_cast<xub_StrLen>(nLen - mnRangeOpPosInSymbol);
+ mnRangeOpPosInSymbol = -1;
+ mbRewind = true;
+ return true; // end all checks
+ }
return false;
}
@@ -3551,54 +3587,65 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
// #42016# Italian ARCTAN.2 resulted in #REF! => IsOpcode() before
// IsReference().
- const String aOrg( cSymbol );
-
- if (bAsciiNonAlnum && IsOpCode( aOrg, bInArray ))
- return true;
-
String aUpper;
- bool bAsciiUpper = false;
- if (bMayBeFuncName)
+
+ do
{
- bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
- if (IsOpCode( aUpper, bInArray ))
+ mbRewind = false;
+ const String aOrg( cSymbol );
+
+ if (bAsciiNonAlnum && IsOpCode( aOrg, bInArray ))
return true;
- }
- // Column 'DM' ("Deutsche Mark", German currency) couldn't be
- // referred => IsReference() before IsValue().
- // Preserve case of file names in external references.
- if (IsReference( aOrg ))
- return true;
+ aUpper.Erase();
+ bool bAsciiUpper = false;
+ if (bMayBeFuncName)
+ {
+ bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
+ if (IsOpCode( aUpper, bInArray ))
+ return true;
+ }
- if (!aUpper.Len())
- bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
+ // Column 'DM' ("Deutsche Mark", German currency) couldn't be
+ // referred => IsReference() before IsValue().
+ // Preserve case of file names in external references.
+ if (IsReference( aOrg ))
+ {
+ if (mbRewind) // Range operator, but no direct reference.
+ continue; // do; up to range operator.
+ return true;
+ }
- // IsBoolean() before IsValue() to catch inline bools without the kludge
- // for inline arrays.
- if (bAllowBooleans && IsBoolean( aUpper ))
- return true;
+ if (!aUpper.Len())
+ bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
- if (IsValue( aUpper ))
- return true;
+ // IsBoolean() before IsValue() to catch inline bools without the kludge
+ // for inline arrays.
+ if (bAllowBooleans && IsBoolean( aUpper ))
+ return true;
- // User defined names and such do need i18n upper also in ODF.
- if (bAsciiUpper)
- aUpper = ScGlobal::pCharClass->upper( aOrg );
+ if (IsValue( aUpper ))
+ return true;
- if (IsNamedRange( aUpper ))
- return true;
- // Preserve case of file names in external references.
- if (IsExternalNamedRange( aOrg ))
- return true;
- if (IsDBRange( aUpper ))
- return true;
- if (IsColRowName( aUpper ))
- return true;
- if (bMayBeFuncName && IsMacro( aUpper ))
- return true;
- if (bMayBeFuncName && IsOpCode2( aUpper ))
- return true;
+ // User defined names and such do need i18n upper also in ODF.
+ if (bAsciiUpper)
+ aUpper = ScGlobal::pCharClass->upper( aOrg );
+
+ if (IsNamedRange( aUpper ))
+ return true;
+ // Preserve case of file names in external references.
+ if (IsExternalNamedRange( aOrg ))
+ return true;
+ if (IsDBRange( aUpper ))
+ return true;
+ if (IsColRowName( aUpper ))
+ return true;
+ if (bMayBeFuncName && IsMacro( aUpper ))
+ return true;
+ if (bMayBeFuncName && IsOpCode2( aUpper ))
+ return true;
+
+ } while (mbRewind);
if ( mbExtendedErrorDetection )
{
@@ -3620,6 +3667,21 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
return true;
}
+void ScCompiler::CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp )
+{
+ bool bExternal = GetGrammar() == FormulaGrammar::GRAM_EXTERNAL;
+ USHORT nExpectedCount = bExternal ? 2 : 1;
+ DBG_ASSERT( pArr->GetLen() == nExpectedCount, "ScCompiler::CreateStringFromXMLTokenArray - wrong number of tokens" );
+ if( pArr->GetLen() == nExpectedCount )
+ {
+ FormulaToken** ppTokens = pArr->GetArray();
+ // string tokens expected, GetString() will assert if token type is wrong
+ rFormula = ppTokens[ 0 ]->GetString();
+ if( bExternal )
+ rFormulaNmsp = ppTokens[ 1 ]->GetString();
+ }
+}
+
ScTokenArray* ScCompiler::CompileString( const String& rFormula )
{
#if 0
@@ -3627,6 +3689,10 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
rtl::OUStringToOString( rFormula, RTL_TEXTENCODING_UTF8 ).getStr() );
#endif
+ OSL_ENSURE( meGrammar != FormulaGrammar::GRAM_EXTERNAL, "ScCompiler::CompileString - unexpected grammar GRAM_EXTERNAL" );
+ if( meGrammar == FormulaGrammar::GRAM_EXTERNAL )
+ SetGrammar( FormulaGrammar::GRAM_PODF );
+
ScTokenArray aArr;
pArr = &aArr;
aFormula = rFormula;
@@ -3829,6 +3895,34 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
}
+ScTokenArray* ScCompiler::CompileString( const String& rFormula, const String& rFormulaNmsp )
+{
+ DBG_ASSERT( (GetGrammar() == FormulaGrammar::GRAM_EXTERNAL) || (rFormulaNmsp.Len() == 0),
+ "ScCompiler::CompileString - unexpected formula namespace for internal grammar" );
+ if( GetGrammar() == FormulaGrammar::GRAM_EXTERNAL ) try
+ {
+ ScFormulaParserPool& rParserPool = pDoc->GetFormulaParserPool();
+ uno::Reference< sheet::XFormulaParser > xParser( rParserPool.getFormulaParser( rFormulaNmsp ), uno::UNO_SET_THROW );
+ table::CellAddress aReferencePos;
+ ScUnoConversion::FillApiAddress( aReferencePos, aPos );
+ uno::Sequence< sheet::FormulaToken > aTokenSeq = xParser->parseFormula( rFormula, aReferencePos );
+ ScTokenArray aTokenArray;
+ if( ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, aTokenSeq ) )
+ {
+ // remember pArr, in case a subsequent CompileTokenArray() is executed.
+ ScTokenArray* pNew = new ScTokenArray( aTokenArray );
+ pArr = pNew;
+ return pNew;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ // no success - fallback to some internal grammar and hope the best
+ return CompileString( rFormula );
+}
+
+
BOOL ScCompiler::HandleRange()
{
ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
@@ -3865,7 +3959,7 @@ BOOL ScCompiler::HandleRange()
if( pRangeData->HasReferences() )
{
SetRelNameReference();
- MoveRelWrap();
+ MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
}
pNew->Reset();
if ( bAddPair )
@@ -3917,7 +4011,7 @@ BOOL ScCompiler::HandleExternalReference(const FormulaToken& _aToken)
if (pNew->GetNextReference() != NULL)
{
SetRelNameReference();
- MoveRelWrap();
+ MoveRelWrap(MAXCOL, MAXROW);
}
pNew->Reset();
return GetToken();
@@ -4012,33 +4106,33 @@ void ScCompiler::SetRelNameReference()
// Wrap-adjust relative references of a RangeName to current position,
// don't call for other token arrays!
-void ScCompiler::MoveRelWrap()
+void ScCompiler::MoveRelWrap( SCCOL nMaxCol, SCROW nMaxRow )
{
pArr->Reset();
for( ScToken* t = static_cast<ScToken*>(pArr->GetNextReference()); t;
t = static_cast<ScToken*>(pArr->GetNextReference()) )
{
if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
- ScRefUpdate::MoveRelWrap( pDoc, aPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, nMaxCol, nMaxRow, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
else
- ScRefUpdate::MoveRelWrap( pDoc, aPos, t->GetDoubleRef() );
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, nMaxCol, nMaxRow, t->GetDoubleRef() );
}
}
// static
// Wrap-adjust relative references of a RangeName to current position,
// don't call for other token arrays!
-void ScCompiler::MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc,
- const ScAddress& rPos )
+void ScCompiler::MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc, const ScAddress& rPos,
+ SCCOL nMaxCol, SCROW nMaxRow )
{
rArr.Reset();
for( ScToken* t = static_cast<ScToken*>(rArr.GetNextReference()); t;
t = static_cast<ScToken*>(rArr.GetNextReference()) )
{
if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
- ScRefUpdate::MoveRelWrap( pDoc, rPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ ScRefUpdate::MoveRelWrap( pDoc, rPos, nMaxCol, nMaxRow, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
else
- ScRefUpdate::MoveRelWrap( pDoc, rPos, t->GetDoubleRef() );
+ ScRefUpdate::MoveRelWrap( pDoc, rPos, nMaxCol, nMaxRow, t->GetDoubleRef() );
}
}
@@ -4213,7 +4307,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
SingleDoubleRefModifier aMod( rRef );
if ( rRef.IsRelName() )
{
- ScRefUpdate::MoveRelWrap( pDoc, aPos, aMod.Ref() );
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
rChanged = TRUE;
}
else
@@ -4243,7 +4337,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
{
- ScRefUpdate::MoveRelWrap( pDoc, aPos, rRef );
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
rChanged = TRUE;
}
else
@@ -5060,6 +5154,11 @@ BOOL ScCompiler::EnQuote( String& rStr )
return TRUE;
}
+sal_Unicode ScCompiler::GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const
+{
+ return pConv->getSpecialSymbol(eType);
+}
+
void ScCompiler::fillAddInToken(::std::vector< ::com::sun::star::sheet::FormulaOpCodeMapEntry >& _rVec,bool _bIsEnglish) const
{
// All known AddIn functions.
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 20c534a0a556..2d337eab2eb3 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -1420,6 +1420,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab )
{
+ rDoc.InitializeNoteCaptions( nObjTab );
SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
DBG_ASSERT( pPage, "Page ?" );
if( pPage )
@@ -1430,6 +1431,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
if ( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, nObjTab ) )
{
ScPostIt* pNote = rDoc.GetNote( pData->maStart );
+ // caption should exist, we iterate over drawing objects...
DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" );
if( pNote )
{
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
index d08f593aaf21..5519c679f84e 100644
--- a/sc/source/core/tool/editutil.cxx
+++ b/sc/source/core/tool/editutil.cxx
@@ -64,12 +64,13 @@
#include "patattr.hxx"
#include "scmod.hxx"
#include "inputopt.hxx"
+#include "compiler.hxx"
// STATIC DATA -----------------------------------------------------------
// Delimiters zusaetzlich zu EditEngine-Default:
-const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=();+-*/^&<>";
+const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=()+-*/^&<>";
//------------------------------------------------------------------------
@@ -79,6 +80,7 @@ String ScEditUtil::ModifyDelimiters( const String& rOld )
String aRet = rOld;
aRet.EraseAllChars( '_' ); // underscore is used in function argument names
aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( pCalcDelimiters ) );
+ aRet.Append(ScCompiler::GetNativeSymbol(ocSep)); // argument separator is localized.
return aRet;
}
diff --git a/sc/source/core/tool/formulaparserpool.cxx b/sc/source/core/tool/formulaparserpool.cxx
new file mode 100644
index 000000000000..94259a56d6e2
--- /dev/null
+++ b/sc/source/core/tool/formulaparserpool.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulaparserpool.cxx,v $
+ * $Revision: 1.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "formulaparserpool.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XFilterFormulaParser.hpp>
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/objsh.hxx>
+#include "document.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+// ============================================================================
+
+namespace {
+
+class ScParserFactoryMap
+{
+public:
+ explicit ScParserFactoryMap();
+
+ Reference< XFormulaParser > createFormulaParser(
+ const Reference< XComponent >& rxComponent,
+ const OUString& rNamespace );
+
+private:
+ typedef ::std::hash_map<
+ OUString,
+ Reference< XSingleComponentFactory >,
+ OUStringHash,
+ ::std::equal_to< OUString > > FactoryMap;
+
+ Reference< XComponentContext > mxContext; /// Default context of global process factory.
+ FactoryMap maFactories; /// All parser factories, mapped by formula namespace.
+};
+
+ScParserFactoryMap::ScParserFactoryMap()
+{
+ try
+ {
+ // get process factory and default component context
+ Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
+ Reference< XPropertySet > xPropSet( xFactory, UNO_QUERY_THROW );
+ mxContext.set( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), UNO_QUERY_THROW );
+
+ // enumerate all implementations of the FormulaParser service
+ Reference< XContentEnumerationAccess > xFactoryEA( xFactory, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnum( xFactoryEA->createContentEnumeration( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FilterFormulaParser" ) ) ), UNO_SET_THROW );
+ while( xEnum->hasMoreElements() ) try // single try/catch for every element
+ {
+ // create an instance of the formula parser implementation
+ Reference< XSingleComponentFactory > xCompFactory( xEnum->nextElement(), UNO_QUERY_THROW );
+ Reference< XFilterFormulaParser > xParser( xCompFactory->createInstanceWithContext( mxContext ), UNO_QUERY_THROW );
+
+ // store factory in the map
+ OUString aNamespace = xParser->getSupportedNamespace();
+ if( aNamespace.getLength() > 0 )
+ maFactories[ aNamespace ] = xCompFactory;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+Reference< XFormulaParser > ScParserFactoryMap::createFormulaParser(
+ const Reference< XComponent >& rxComponent, const OUString& rNamespace )
+{
+ Reference< XFormulaParser > xParser;
+ FactoryMap::const_iterator aIt = maFactories.find( rNamespace );
+ if( aIt != maFactories.end() ) try
+ {
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= rxComponent;
+ xParser.set( aIt->second->createInstanceWithArgumentsAndContext( aArgs, mxContext ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ return xParser;
+}
+
+struct ScParserFactorySingleton : public ::rtl::Static< ScParserFactoryMap, ScParserFactorySingleton > {};
+
+} // namespace
+
+// ============================================================================
+
+ScFormulaParserPool::ScFormulaParserPool( const ScDocument& rDoc ) :
+ mrDoc( rDoc )
+{
+}
+
+ScFormulaParserPool::~ScFormulaParserPool()
+{
+}
+
+bool ScFormulaParserPool::hasFormulaParser( const OUString& rNamespace )
+{
+ return getFormulaParser( rNamespace ).is();
+}
+
+Reference< XFormulaParser > ScFormulaParserPool::getFormulaParser( const OUString& rNamespace )
+{
+ // try to find an existing parser entry
+ ParserMap::iterator aIt = maParsers.find( rNamespace );
+ if( aIt != maParsers.end() )
+ return aIt->second;
+
+ // always create a new entry in the map (even if the following initialization fails)
+ Reference< XFormulaParser >& rxParser = maParsers[ rNamespace ];
+
+ // try to create a new parser object
+ if( SfxObjectShell* pDocShell = mrDoc.GetDocumentShell() ) try
+ {
+ Reference< XComponent > xComponent( pDocShell->GetModel(), UNO_QUERY_THROW );
+ ScParserFactoryMap& rFactoryMap = ScParserFactorySingleton::get();
+ rxParser = rFactoryMap.createFormulaParser( xComponent, rNamespace );
+ }
+ catch( Exception& )
+ {
+ }
+ return rxParser;
+}
+
+// ============================================================================
+
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index ec4c4c293839..195366271f0d 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -71,6 +71,7 @@
#include "lookupcache.hxx"
#include "rangenam.hxx"
#include "compiler.hxx"
+#include "externalrefmgr.hxx"
#define SC_DOUBLE_MAXVALUE 1.7e307
@@ -626,7 +627,20 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
}
-double ScInterpreter::CompareFunc( const ScCompare& rComp )
+ScCompareOptions::ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
+ aQueryEntry(rEntry),
+ bRegEx(bReg),
+ bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell()),
+ bIgnoreCase(true)
+{
+ bRegEx = (bRegEx && (aQueryEntry.eOp == SC_EQUAL || aQueryEntry.eOp == SC_NOT_EQUAL));
+ // Interpreter functions usually are case insensitive, except the simple
+ // comparison operators, for which these options aren't used. Override in
+ // struct if needed.
+}
+
+
+double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions )
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CompareFunc" );
// Keep DoubleError if encountered
@@ -698,7 +712,53 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp )
fRes = 1; // number is less than string
else
{
- if (pDok->GetDocOptions().IsIgnoreCase())
+ // Both strings.
+ if (pOptions)
+ {
+ // All similar to Sctable::ValidQuery(), *rComp.pVal[1] actually
+ // is/must be identical to *rEntry.pStr, which is essential for
+ // regex to work through GetSearchTextPtr().
+ ScQueryEntry& rEntry = pOptions->aQueryEntry;
+ DBG_ASSERT( *rComp.pVal[1] == *rEntry.pStr, "ScInterpreter::CompareFunc: broken options");
+ if (pOptions->bRegEx)
+ {
+ xub_StrLen nStart = 0;
+ xub_StrLen nStop = rComp.pVal[0]->Len();
+ bool bMatch = rEntry.GetSearchTextPtr(
+ !pOptions->bIgnoreCase)->SearchFrwrd( *rComp.pVal[0],
+ &nStart, &nStop);
+ if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rComp.pVal[0]->Len()))
+ bMatch = false; // RegEx must match entire string.
+ fRes = (bMatch ? 0 : 1);
+ }
+ else if (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
+ {
+ ::utl::TransliterationWrapper* pTransliteration =
+ (pOptions->bIgnoreCase ? ScGlobal::pTransliteration :
+ ScGlobal::pCaseTransliteration);
+ bool bMatch;
+ if (pOptions->bMatchWholeCell)
+ bMatch = pTransliteration->isEqual( *rComp.pVal[0], *rComp.pVal[1]);
+ else
+ {
+ String aCell( pTransliteration->transliterate(
+ *rComp.pVal[0], ScGlobal::eLnge, 0,
+ rComp.pVal[0]->Len(), NULL));
+ String aQuer( pTransliteration->transliterate(
+ *rComp.pVal[1], ScGlobal::eLnge, 0,
+ rComp.pVal[1]->Len(), NULL));
+ bMatch = (aCell.Search( aQuer ) != STRING_NOTFOUND);
+ }
+ fRes = (bMatch ? 0 : 1);
+ }
+ else if (pOptions->bIgnoreCase)
+ fRes = (double) ScGlobal::pCollator->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ else
+ fRes = (double) ScGlobal::pCaseCollator->compareString(
+ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+ }
+ else if (pDok->GetDocOptions().IsIgnoreCase())
fRes = (double) ScGlobal::pCollator->compareString(
*rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
else
@@ -763,7 +823,7 @@ double ScInterpreter::Compare()
}
-ScMatrixRef ScInterpreter::CompareMat()
+ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions )
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CompareMat" );
String aVal1, aVal2;
@@ -855,7 +915,7 @@ ScMatrixRef ScInterpreter::CompareMat()
aComp.bEmpty[i] = FALSE;
}
}
- pResMat->PutDouble( CompareFunc( aComp ), j,k );
+ pResMat->PutDouble( CompareFunc( aComp, pOptions ), j,k );
}
else
pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k );
@@ -885,7 +945,7 @@ ScMatrixRef ScInterpreter::CompareMat()
*aComp.pVal[i] = pMat[i]->GetString(j);
aComp.bEmpty[i] = pMat[i]->IsEmpty(j);
}
- pResMat->PutDouble( CompareFunc( aComp ), j );
+ pResMat->PutDouble( CompareFunc( aComp, pOptions ), j );
}
}
}
@@ -894,6 +954,52 @@ ScMatrixRef ScInterpreter::CompareMat()
}
+ScMatrixRef ScInterpreter::QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions )
+{
+ short nSaveCurFmtType = nCurFmtType;
+ short nSaveFuncFmtType = nFuncFmtType;
+ PushMatrix( pMat);
+ if (rOptions.aQueryEntry.bQueryByString)
+ PushString( *rOptions.aQueryEntry.pStr);
+ else
+ PushDouble( rOptions.aQueryEntry.nVal);
+ ScMatrixRef pResultMatrix = CompareMat( &rOptions);
+ nCurFmtType = nSaveCurFmtType;
+ nFuncFmtType = nSaveFuncFmtType;
+ if (nGlobalError || !pResultMatrix)
+ {
+ SetError( errIllegalParameter);
+ return pResultMatrix;
+ }
+
+ switch (rOptions.aQueryEntry.eOp)
+ {
+ case SC_EQUAL:
+ pResultMatrix->CompareEqual();
+ break;
+ case SC_LESS:
+ pResultMatrix->CompareLess();
+ break;
+ case SC_GREATER:
+ pResultMatrix->CompareGreater();
+ break;
+ case SC_LESS_EQUAL:
+ pResultMatrix->CompareLessEqual();
+ break;
+ case SC_GREATER_EQUAL:
+ pResultMatrix->CompareGreaterEqual();
+ break;
+ case SC_NOT_EQUAL:
+ pResultMatrix->CompareNotEqual();
+ break;
+ default:
+ SetError( errIllegalArgument);
+ DBG_ERROR1( "ScInterpreter::QueryMat: unhandled comparison operator: %d", (int)rOptions.aQueryEntry.eOp);
+ }
+ return pResultMatrix;
+}
+
+
void ScInterpreter::ScEqual()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEqual" );
@@ -4310,6 +4416,7 @@ void ScInterpreter::ScCountIf()
SCCOL nCol2;
SCROW nRow2;
SCTAB nTab2;
+ ScMatrixRef pQueryMatrix;
switch ( GetStackType() )
{
case svDoubleRef :
@@ -4326,6 +4433,24 @@ void ScInterpreter::ScCountIf()
nRow2 = nRow1;
nTab2 = nTab1;
break;
+ case svMatrix:
+ {
+ pQueryMatrix = PopMatrix();
+ if (!pQueryMatrix)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ nCol1 = 0;
+ nRow1 = 0;
+ nTab1 = 0;
+ SCSIZE nC, nR;
+ pQueryMatrix->GetDimensions( nC, nR);
+ nCol2 = static_cast<SCCOL>(nC - 1);
+ nRow2 = static_cast<SCROW>(nR - 1);
+ nTab2 = 0;
+ }
+ break;
default:
PushIllegalParameter();
return ;
@@ -4367,15 +4492,37 @@ void ScInterpreter::ScCountIf()
rParam.nCol1 = nCol1;
rParam.nCol2 = nCol2;
rEntry.nField = nCol1;
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
- // Entry.nField im Iterator bei Spaltenwechsel weiterschalten
- aCellIter.SetAdvanceQueryParamEntryField( TRUE );
- if ( aCellIter.GetFirst() )
+ if (pQueryMatrix)
{
- do
+ // Never case-sensitive.
+ ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+ ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+ if (nGlobalError || !pResultMatrix)
{
- fSum++;
- } while ( aCellIter.GetNext() );
+ PushIllegalParameter();
+ return;
+ }
+
+ SCSIZE nSize = pResultMatrix->GetElementCount();
+ for (SCSIZE nIndex = 0; nIndex < nSize; ++nIndex)
+ {
+ if (pResultMatrix->IsValue( nIndex) &&
+ pResultMatrix->GetDouble( nIndex))
+ ++fSum;
+ }
+ }
+ else
+ {
+ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
+ // Entry.nField im Iterator bei Spaltenwechsel weiterschalten
+ aCellIter.SetAdvanceQueryParamEntryField( TRUE );
+ if ( aCellIter.GetFirst() )
+ {
+ do
+ {
+ fSum++;
+ } while ( aCellIter.GetNext() );
+ }
}
}
else
@@ -4399,6 +4546,7 @@ void ScInterpreter::ScSumIf()
SCROW nRow3 = 0;
SCTAB nTab3 = 0;
+ ScMatrixRef pSumExtraMatrix;
bool bSumExtraRange = (nParamCount == 3);
if (bSumExtraRange)
{
@@ -4423,6 +4571,10 @@ void ScInterpreter::ScSumIf()
case svSingleRef :
PopSingleRef( nCol3, nRow3, nTab3 );
break;
+ case svMatrix:
+ pSumExtraMatrix = PopMatrix();
+ //! nCol3, nRow3, nTab3 remain 0
+ break;
default:
PushIllegalParameter();
return ;
@@ -4498,6 +4650,7 @@ void ScInterpreter::ScSumIf()
SCCOL nCol2;
SCROW nRow2;
SCTAB nTab2;
+ ScMatrixRef pQueryMatrix;
switch ( GetStackType() )
{
case svRefList :
@@ -4522,13 +4675,31 @@ void ScInterpreter::ScSumIf()
nRow2 = nRow1;
nTab2 = nTab1;
break;
+ case svMatrix:
+ {
+ pQueryMatrix = PopMatrix();
+ if (!pQueryMatrix)
+ {
+ PushIllegalParameter();
+ return;
+ }
+ nCol1 = 0;
+ nRow1 = 0;
+ nTab1 = 0;
+ SCSIZE nC, nR;
+ pQueryMatrix->GetDimensions( nC, nR);
+ nCol2 = static_cast<SCCOL>(nC - 1);
+ nRow2 = static_cast<SCROW>(nR - 1);
+ nTab2 = 0;
+ }
+ break;
default:
PushIllegalParameter();
return ;
}
if ( nTab1 != nTab2 )
{
- PushIllegalParameter();
+ PushIllegalArgument();
return;
}
@@ -4544,15 +4715,29 @@ void ScInterpreter::ScSumIf()
// instead of the result range.
SCCOL nColDelta = nCol2 - nCol1;
SCROW nRowDelta = nRow2 - nRow1;
- if (nCol3 + nColDelta > MAXCOL)
+ SCCOL nMaxCol;
+ SCROW nMaxRow;
+ if (pSumExtraMatrix)
{
- SCCOL nNewDelta = MAXCOL - nCol3;
+ SCSIZE nC, nR;
+ pSumExtraMatrix->GetDimensions( nC, nR);
+ nMaxCol = static_cast<SCCOL>(nC - 1);
+ nMaxRow = static_cast<SCROW>(nR - 1);
+ }
+ else
+ {
+ nMaxCol = MAXCOL;
+ nMaxRow = MAXROW;
+ }
+ if (nCol3 + nColDelta > nMaxCol)
+ {
+ SCCOL nNewDelta = nMaxCol - nCol3;
nCol2 = nCol1 + nNewDelta;
}
- if (nRow3 + nRowDelta > MAXROW)
+ if (nRow3 + nRowDelta > nMaxRow)
{
- SCROW nNewDelta = MAXROW - nRow3;
+ SCROW nNewDelta = nMaxRow - nRow3;
nRow2 = nRow1 + nNewDelta;
}
}
@@ -4592,30 +4777,119 @@ void ScInterpreter::ScSumIf()
rParam.nCol1 = nCol1;
rParam.nCol2 = nCol2;
rEntry.nField = nCol1;
- SCCOL nColDiff = nCol3 - nCol1;
- SCROW nRowDiff = nRow3 - nRow1;
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
- // Increment Entry.nField in iterator when switching to next column.
- aCellIter.SetAdvanceQueryParamEntryField( TRUE );
- if ( aCellIter.GetFirst() )
+ SCsCOL nColDiff = nCol3 - nCol1;
+ SCsROW nRowDiff = nRow3 - nRow1;
+ if (pQueryMatrix)
{
- do
+ // Never case-sensitive.
+ ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+ ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+ if (nGlobalError || !pResultMatrix)
{
- aAdr.SetCol( aCellIter.GetCol() + nColDiff);
- aAdr.SetRow( aCellIter.GetRow() + nRowDiff);
- ScBaseCell* pCell = GetCell( aAdr );
- if ( HasCellValueData(pCell) )
+ PushIllegalParameter();
+ return;
+ }
+
+ if (pSumExtraMatrix)
+ {
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
{
- fVal = GetCellValue( aAdr, pCell );
- if ( bNull && fVal != 0.0 )
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{
- bNull = FALSE;
- fMem = fVal;
+ if (pResultMatrix->IsValue( nCol, nRow) &&
+ pResultMatrix->GetDouble( nCol, nRow))
+ {
+ SCSIZE nC = nCol + nColDiff;
+ SCSIZE nR = nRow + nRowDiff;
+ if (pSumExtraMatrix->IsValue( nC, nR))
+ {
+ fVal = pSumExtraMatrix->GetDouble( nC, nR);
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fSum += fVal;
+ }
+ }
}
- else
- fSum += fVal;
}
- } while ( aCellIter.GetNext() );
+ }
+ else
+ {
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ {
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ {
+ if (pResultMatrix->GetDouble( nCol, nRow))
+ {
+ aAdr.SetCol( nCol + nColDiff);
+ aAdr.SetRow( nRow + nRowDiff);
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( HasCellValueData(pCell) )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fSum += fVal;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
+ // Increment Entry.nField in iterator when switching to next column.
+ aCellIter.SetAdvanceQueryParamEntryField( TRUE );
+ if ( aCellIter.GetFirst() )
+ {
+ if (pSumExtraMatrix)
+ {
+ do
+ {
+ SCSIZE nC = aCellIter.GetCol() + nColDiff;
+ SCSIZE nR = aCellIter.GetRow() + nRowDiff;
+ if (pSumExtraMatrix->IsValue( nC, nR))
+ {
+ fVal = pSumExtraMatrix->GetDouble( nC, nR);
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fSum += fVal;
+ }
+ } while ( aCellIter.GetNext() );
+ }
+ else
+ {
+ do
+ {
+ aAdr.SetCol( aCellIter.GetCol() + nColDiff);
+ aAdr.SetRow( aCellIter.GetRow() + nRowDiff);
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( HasCellValueData(pCell) )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = FALSE;
+ fMem = fVal;
+ }
+ else
+ fSum += fVal;
+ }
+ } while ( aCellIter.GetNext() );
+ }
+ }
}
}
else
@@ -5762,6 +6036,52 @@ void ScInterpreter::ScDBVarP()
}
+ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument* pDoc,
+ const ScAddress::ExternalInfo& rExtInfo, const ScRefAddress& rRefAd1,
+ const ScRefAddress* pRefAd2 )
+{
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ size_t nSheets = 1;
+ const String* pRealTab = pRefMgr->getRealTableName( rExtInfo.mnFileId, rExtInfo.maTabName);
+ ScTokenArray* pTokenArray = new ScTokenArray;
+ if (pRefAd2)
+ {
+ ScComplexRefData aRef;
+ aRef.InitRangeRel( ScRange( rRefAd1.GetAddress(), pRefAd2->GetAddress()), rPos);
+ aRef.Ref1.SetColRel( rRefAd1.IsRelCol());
+ aRef.Ref1.SetRowRel( rRefAd1.IsRelRow());
+ aRef.Ref1.SetTabRel( rRefAd1.IsRelTab());
+ aRef.Ref1.SetFlag3D( true);
+ aRef.Ref2.SetColRel( pRefAd2->IsRelCol());
+ aRef.Ref2.SetRowRel( pRefAd2->IsRelRow());
+ aRef.Ref2.SetTabRel( pRefAd2->IsRelTab());
+ nSheets = aRef.Ref2.nTab - aRef.Ref1.nTab + 1;
+ aRef.Ref2.SetFlag3D( nSheets > 1 );
+ pTokenArray->AddExternalDoubleReference( rExtInfo.mnFileId,
+ (pRealTab ? *pRealTab : rExtInfo.maTabName), aRef);
+ }
+ else
+ {
+ ScSingleRefData aRef;
+ aRef.InitAddressRel( rRefAd1.GetAddress(), rPos);
+ aRef.SetColRel( rRefAd1.IsRelCol());
+ aRef.SetRowRel( rRefAd1.IsRelRow());
+ aRef.SetTabRel( rRefAd1.IsRelTab());
+ aRef.SetFlag3D( true);
+ pTokenArray->AddExternalSingleReference( rExtInfo.mnFileId,
+ (pRealTab ? *pRealTab : rExtInfo.maTabName), aRef);
+ }
+ // The indirect usage of the external table can't be detected during the
+ // store-to-file cycle, mark it as permanently referenced so it gets stored
+ // even if not directly referenced anywhere.
+ pRefMgr->setCacheTableReferencedPermanently( rExtInfo.mnFileId,
+ rExtInfo.maTabName, nSheets);
+ ScCompiler aComp( pDoc, rPos, *pTokenArray);
+ aComp.CompileTokenArray();
+ return pTokenArray;
+}
+
+
void ScInterpreter::ScIndirect()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIndirect" );
@@ -5780,15 +6100,46 @@ void ScInterpreter::ScIndirect()
SCTAB nTab = aPos.Tab();
String sRefStr( GetString() );
ScRefAddress aRefAd, aRefAd2;
- if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails) ||
+ ScAddress::ExternalInfo aExtInfo;
+ if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo) ||
(bTryXlA1 && ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd,
- aRefAd2, aDetailsXlA1)))
- PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
- aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
- else if ( ConvertSingleRef ( pDok, sRefStr, nTab, aRefAd, aDetails) ||
+ aRefAd2, aDetailsXlA1, &aExtInfo)))
+ {
+ if (aExtInfo.mbExternal)
+ {
+ /* TODO: future versions should implement a proper subroutine
+ * token. This procedure here is a minimally invasive fix for
+ * #i101645# in OOo3.1.1 */
+ // Push a subroutine on the instruction code stack that
+ // resolves the external reference as the next instruction.
+ aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok,
+ aExtInfo, aRefAd, &aRefAd2));
+ // Signal subroutine call to interpreter.
+ PushTempToken( new FormulaUnknownToken( ocCall));
+ }
+ else
+ PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
+ aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
+ }
+ else if ( ConvertSingleRef ( pDok, sRefStr, nTab, aRefAd, aDetails, &aExtInfo) ||
(bTryXlA1 && ConvertSingleRef ( pDok, sRefStr, nTab, aRefAd,
- aDetailsXlA1)))
- PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
+ aDetailsXlA1, &aExtInfo)))
+ {
+ if (aExtInfo.mbExternal)
+ {
+ /* TODO: future versions should implement a proper subroutine
+ * token. This procedure here is a minimally invasive fix for
+ * #i101645# in OOo3.1.1 */
+ // Push a subroutine on the instruction code stack that
+ // resolves the external reference as the next instruction.
+ aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok,
+ aExtInfo, aRefAd, NULL));
+ // Signal subroutine call to interpreter.
+ PushTempToken( new FormulaUnknownToken( ocCall));
+ }
+ else
+ PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
+ }
else
{
do
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 2722925fc56d..a73fe62998a6 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3812,6 +3812,15 @@ StackVar ScInterpreter::Interpret()
default : PushError( errUnknownOpCode); break;
}
+ // If the function signalled that it pushed a subroutine on the
+ // instruction code stack instead of a result, continue with
+ // execution of the subroutine.
+ if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall)
+ {
+ Pop();
+ continue; // while( ( pCur = aCode.Next() ) != NULL ...
+ }
+
// Remember result matrix in case it could be reused.
if (pTokenMatrixMap && sp && GetStackType() == svMatrix)
pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur,
diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk
index 8a4b1b44fd12..ac0aa23fc044 100644
--- a/sc/source/core/tool/makefile.mk
+++ b/sc/source/core/tool/makefile.mk
@@ -1,7 +1,7 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
+#
# Copyright 2008 by Sun Microsystems, Inc.
#
# OpenOffice.org - a multi-platform office productivity suite
@@ -78,6 +78,7 @@ SLOFILES = \
$(SLO)$/docoptio.obj \
$(SLO)$/editutil.obj \
$(SLO)$/filtopt.obj \
+ $(SLO)$/formulaparserpool.obj \
$(SLO)$/hints.obj \
$(SLO)$/indexmap.obj \
$(SLO)$/inputopt.obj \
@@ -122,6 +123,7 @@ EXCEPTIONSFILES= \
$(SLO)$/chartlock.obj \
$(SLO)$/chgtrack.obj \
$(SLO)$/compiler.obj \
+ $(SLO)$/formulaparserpool.obj \
$(SLO)$/interpr1.obj \
$(SLO)$/interpr2.obj \
$(SLO)$/interpr3.obj \
diff --git a/sc/source/core/tool/progress.cxx b/sc/source/core/tool/progress.cxx
index fc7a7088d2a9..450736997c2d 100644
--- a/sc/source/core/tool/progress.cxx
+++ b/sc/source/core/tool/progress.cxx
@@ -162,7 +162,7 @@ void ScProgress::CreateInterpretProgress( ScDocument* pDoc, BOOL bWait )
if ( !pGlobalProgress )
pInterpretProgress = new ScProgress( pDoc->GetDocumentShell(),
ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ),
- pDoc->GetFormulaCodeInTree(), FALSE, bWait );
+ pDoc->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE, FALSE, bWait );
pInterpretDoc = pDoc;
}
}
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 704c3255486e..4a4683935e99 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -60,7 +60,7 @@ using namespace formula;
// Interner ctor fuer das Suchen nach einem Index
ScRangeData::ScRangeData( USHORT n )
- : pCode( NULL ), nIndex( n ), bModified( FALSE )
+ : pCode( NULL ), nIndex( n ), bModified( FALSE ), mnMaxRow(-1), mnMaxCol(-1)
{}
ScRangeData::ScRangeData( ScDocument* pDok,
@@ -76,7 +76,9 @@ ScRangeData::ScRangeData( ScDocument* pDok,
eType ( nType ),
pDoc ( pDok ),
nIndex ( 0 ),
- bModified ( FALSE )
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
{
if (rSymbol.Len() > 0)
{
@@ -122,7 +124,9 @@ ScRangeData::ScRangeData( ScDocument* pDok,
eType ( nType ),
pDoc ( pDok ),
nIndex ( 0 ),
- bModified ( FALSE )
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
{
if( !pCode->GetCodeError() )
{
@@ -157,7 +161,9 @@ ScRangeData::ScRangeData( ScDocument* pDok,
eType ( RT_NAME ),
pDoc ( pDok ),
nIndex ( 0 ),
- bModified ( FALSE )
+ bModified ( FALSE ),
+ mnMaxRow (-1),
+ mnMaxCol (-1)
{
ScSingleRefData aRefData;
aRefData.InitAddress( rTarget );
@@ -179,7 +185,9 @@ ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
eType (rScRangeData.eType),
pDoc (rScRangeData.pDoc),
nIndex (rScRangeData.nIndex),
- bModified (rScRangeData.bModified)
+ bModified (rScRangeData.bModified),
+ mnMaxRow (rScRangeData.mnMaxRow),
+ mnMaxCol (rScRangeData.mnMaxCol)
{}
ScRangeData::~ScRangeData()
@@ -247,7 +255,7 @@ void ScRangeData::UpdateSymbol( rtl::OUStringBuffer& rBuffer, const ScAddress& r
::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
ScCompiler aComp( pDoc, rPos, *pTemp.get());
aComp.SetGrammar(eGrammar);
- aComp.MoveRelWrap();
+ aComp.MoveRelWrap(GetMaxCol(), GetMaxRow());
aComp.CreateStringFromTokenArray( rBuffer );
}
@@ -393,7 +401,7 @@ BOOL ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
ScCompiler aComp( pDoc, rPos, *pTemp);
aComp.SetGrammar(pDoc->GetGrammar());
- aComp.MoveRelWrap();
+ aComp.MoveRelWrap(MAXCOL, MAXROW);
return pTemp->IsReference( rRange );
}
@@ -520,6 +528,26 @@ BOOL ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
return TRUE;
}
+void ScRangeData::SetMaxRow(SCROW nRow)
+{
+ mnMaxRow = nRow;
+}
+
+SCROW ScRangeData::GetMaxRow() const
+{
+ return mnMaxRow >= 0 ? mnMaxRow : MAXROW;
+}
+
+void ScRangeData::SetMaxCol(SCCOL nCol)
+{
+ mnMaxCol = nCol;
+}
+
+SCCOL ScRangeData::GetMaxCol() const
+{
+ return mnMaxCol >= 0 ? mnMaxCol : MAXCOL;
+}
+
USHORT ScRangeData::GetErrCode()
{
diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx
index 42cf295390d6..e129abdcf97f 100644
--- a/sc/source/core/tool/reftokenhelper.cxx
+++ b/sc/source/core/tool/reftokenhelper.cxx
@@ -49,13 +49,14 @@ using ::std::auto_ptr;
using ::rtl::OUString;
void ScRefTokenHelper::compileRangeRepresentation(
- vector<ScSharedTokenRef>& rRefTokens, const OUString& rRangeStr, ScDocument* pDoc)
+ vector<ScSharedTokenRef>& rRefTokens, const OUString& rRangeStr, ScDocument* pDoc, FormulaGrammar::Grammar eGrammar)
{
const sal_Unicode cSep = ';';
const sal_Unicode cQuote = '\'';
+ bool bFailure = false;
sal_Int32 nOffset = 0;
- while (nOffset >= 0)
+ while (nOffset >= 0 && !bFailure)
{
OUString aToken;
ScRangeStringConverter::GetTokenByOffset(aToken, rRangeStr, nOffset, cSep, cQuote);
@@ -63,17 +64,52 @@ void ScRefTokenHelper::compileRangeRepresentation(
break;
ScCompiler aCompiler(pDoc, ScAddress(0,0,0));
- aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH);
+ aCompiler.SetGrammar(eGrammar);
auto_ptr<ScTokenArray> pArray(aCompiler.CompileString(aToken));
- // There should only be one reference per range token.
- pArray->Reset();
- FormulaToken* p = pArray->GetNextReference();
- if (!p)
- continue;
+ // There MUST be exactly one reference per range token and nothing
+ // else, and it MUST be a valid reference, not some #REF!
+ USHORT nLen = pArray->GetLen();
+ if (!nLen)
+ continue; // Should a missing range really be allowed?
+ if (nLen != 1)
+ bFailure = true;
+ else
+ {
+ pArray->Reset();
+ const FormulaToken* p = pArray->GetNextReference();
+ if (!p)
+ bFailure = true;
+ else
+ {
+ const ScToken* pT = static_cast<const ScToken*>(p);
+ switch (pT->GetType())
+ {
+ case svSingleRef:
+ if (!pT->GetSingleRef().Valid())
+ bFailure = true;
+ break;
+ case svDoubleRef:
+ if (!pT->GetDoubleRef().Valid())
+ bFailure = true;
+ break;
+ case svExternalSingleRef:
+ if (!pT->GetSingleRef().ValidExternal())
+ bFailure = true;
+ break;
+ case svExternalDoubleRef:
+ if (!pT->GetDoubleRef().ValidExternal())
+ bFailure = true;
+ break;
+ default:
+ ;
+ }
+ if (!bFailure)
+ rRefTokens.push_back(
+ ScSharedTokenRef(static_cast<ScToken*>(p->Clone())));
+ }
+ }
- rRefTokens.push_back(
- ScSharedTokenRef(static_cast<ScToken*>(p->Clone())));
#if 0
switch (p->GetType())
{
@@ -93,7 +129,10 @@ void ScRefTokenHelper::compileRangeRepresentation(
;
}
#endif
+
}
+ if (bFailure)
+ rRefTokens.clear();
}
bool ScRefTokenHelper::getRangeFromToken(ScRange& rRange, const ScSharedTokenRef& pToken, bool bExternal)
diff --git a/sc/source/core/tool/refupdat.cxx b/sc/source/core/tool/refupdat.cxx
index d019a6082583..ddb5f3dc0a5c 100644
--- a/sc/source/core/tool/refupdat.cxx
+++ b/sc/source/core/tool/refupdat.cxx
@@ -821,27 +821,27 @@ ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos,
}
void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos,
- ScComplexRefData& rRef )
+ SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef )
{
if( rRef.Ref1.IsColRel() )
{
rRef.Ref1.nCol = rRef.Ref1.nRelCol + rPos.Col();
- lcl_MoveItWrap( rRef.Ref1.nCol, static_cast<SCsCOL>(0), MAXCOL );
+ lcl_MoveItWrap( rRef.Ref1.nCol, static_cast<SCsCOL>(0), nMaxCol );
}
if( rRef.Ref2.IsColRel() )
{
rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col();
- lcl_MoveItWrap( rRef.Ref2.nCol, static_cast<SCsCOL>(0), MAXCOL );
+ lcl_MoveItWrap( rRef.Ref2.nCol, static_cast<SCsCOL>(0), nMaxCol );
}
if( rRef.Ref1.IsRowRel() )
{
rRef.Ref1.nRow = rRef.Ref1.nRelRow + rPos.Row();
- lcl_MoveItWrap( rRef.Ref1.nRow, static_cast<SCsROW>(0), MAXROW );
+ lcl_MoveItWrap( rRef.Ref1.nRow, static_cast<SCsROW>(0), nMaxRow );
}
if( rRef.Ref2.IsRowRel() )
{
rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row();
- lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), MAXROW );
+ lcl_MoveItWrap( rRef.Ref2.nRow, static_cast<SCsROW>(0), nMaxRow );
}
SCsTAB nMaxTab = (SCsTAB) pDoc->GetTableCount() - 1;
if( rRef.Ref1.IsTabRel() )
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index e8a1dd90a403..0f03d31d3fc8 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1821,8 +1821,11 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
case svSingleRef :
{
ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
+ if ( rRef1.IsFlag3D() )
+ {
rRef1.CalcAbsIfRel( rOldPos );
rRef1.CalcRelFromAbs( rNewPos );
+ }
}
break;
default:
diff --git a/sc/source/filter/excel/biffdump.cxx b/sc/source/filter/excel/biffdump.cxx
new file mode 100644
index 000000000000..c3478cf8cb50
--- /dev/null
+++ b/sc/source/filter/excel/biffdump.cxx
@@ -0,0 +1,9864 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffdump.cxx,v $
+ * $Revision: 1.91 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "biffdump.hxx"
+
+#if EXC_INCL_DUMPER
+#include <tools/stream.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sot/storinfo.hxx>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtl/math.hxx>
+#include "document.hxx"
+#include "global.hxx"
+#include "fprogressbar.hxx"
+#include "xlpivot.hxx"
+#include "xicontent.hxx"
+#include "imp_op.hxx"
+
+#define GETSTR(s) ByteString( s, RTL_TEXTENCODING_MS_1252 )
+
+static const sal_Char* __pHexPrefix = "0x";
+static const sal_Char* __pBinPrefix = "0b";
+static const sal_Char* pU = "UNKNOWN ";
+
+const sal_Char* Biff8RecDumper::pLevelPreString = " ";
+const sal_Char* Biff8RecDumper::pLevelPreStringNT = pLevelPreString + strlen( pLevelPreString );
+UINT32 Biff8RecDumper::nInstances = 0;
+sal_Char* Biff8RecDumper::pBlankLine = NULL;
+const UINT16 Biff8RecDumper::nLenBlankLine = 255;
+const UINT16 Biff8RecDumper::nRecCnt = 0x2020;
+UINT8* Biff8RecDumper::pCharType = NULL;
+UINT8* Biff8RecDumper::pCharVal = NULL;
+
+static const UINT16 nLevelInc = 1;
+
+static UINT16 nXFCount = 0;
+
+static UINT16 nSXLISize[2] = {0, 0}; // array size for SXLI records [rows/cols]
+static UINT16 nSXLIIndex = 0; // current index for SXLI records
+
+// ============================================================================
+
+namespace {
+
+// decimal --------------------------------------------------------------------
+
+inline void lclAppendDec( ByteString& rStr, sal_uInt8 nData )
+{
+ rStr.Append( ByteString::CreateFromInt32( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, sal_Int8 nData )
+{
+ rStr.Append( ByteString::CreateFromInt32( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, sal_uInt16 nData )
+{
+ rStr.Append( ByteString::CreateFromInt32( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, sal_Int16 nData )
+{
+ rStr.Append( ByteString::CreateFromInt32( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, sal_uInt32 nData )
+{
+ rStr.Append( ByteString::CreateFromInt64( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, sal_Int32 nData )
+{
+ rStr.Append( ByteString::CreateFromInt32( nData ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, float fData )
+{
+ rStr.Append( ByteString( ::rtl::math::doubleToString( fData, rtl_math_StringFormat_G, 15, '.', true ) ) );
+}
+
+inline void lclAppendDec( ByteString& rStr, double fData )
+{
+ rStr.Append( ByteString( ::rtl::math::doubleToString( fData, rtl_math_StringFormat_G, 15, '.', true ) ) );
+}
+
+// hexadecimal ----------------------------------------------------------------
+
+void lclAppendHex( ByteString& rStr, sal_uInt8 nData, bool bPrefix = true )
+{
+ static const sal_Char spcHexDigits[] = "0123456789ABCDEF";
+ static const ByteString saPrefix( "0x" );
+
+ if( bPrefix )
+ rStr.Append( saPrefix );
+ rStr.Append( spcHexDigits[ (nData >> 4) & 0x0F ] ).Append( spcHexDigits[ nData & 0x0F ] );
+}
+
+inline void lclAppendHex( ByteString& rStr, sal_Int8 nData, bool bPrefix = true )
+{
+ lclAppendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void lclAppendHex( ByteString& rStr, sal_uInt16 nData, bool bPrefix = true )
+{
+ lclAppendHex( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bPrefix );
+ lclAppendHex( rStr, static_cast< sal_uInt8 >( nData ), false );
+}
+
+inline void lclAppendHex( ByteString& rStr, sal_Int16 nData, bool bPrefix = true )
+{
+ lclAppendHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void lclAppendHex( ByteString& rStr, sal_uInt32 nData, bool bPrefix = true )
+{
+ lclAppendHex( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bPrefix );
+ lclAppendHex( rStr, static_cast< sal_uInt16 >( nData ), false );
+}
+
+inline void lclAppendHex( ByteString& rStr, sal_Int32 nData, bool bPrefix = true )
+{
+ lclAppendHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+inline void lclAppendHex( ByteString& rStr, double fData, bool bPrefix = true )
+{
+ const sal_uInt32* pnData = reinterpret_cast< const sal_uInt32* >( &fData );
+ lclAppendHex( rStr, pnData[ 0 ], bPrefix );
+ lclAppendHex( rStr, pnData[ 1 ], false );
+}
+
+// others ---------------------------------------------------------------------
+
+void lclAppendGuid( ByteString& rStr, const XclGuid& rGuid )
+{
+ lclAppendHex( rStr, SVBT32ToUInt32( rGuid.mpnData ), false );
+ rStr.Append( '-' );
+ lclAppendHex( rStr, SVBT16ToShort( rGuid.mpnData + 4 ), false );
+ rStr.Append( '-' );
+ lclAppendHex( rStr, SVBT16ToShort( rGuid.mpnData + 6 ), false );
+ rStr.Append( '-' );
+ lclAppendHex( rStr, rGuid.mpnData[ 8 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 9 ], false );
+ rStr.Append( '-' );
+ lclAppendHex( rStr, rGuid.mpnData[ 10 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 11 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 12 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 13 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 14 ], false );
+ lclAppendHex( rStr, rGuid.mpnData[ 15 ], false );
+}
+
+} // namespace
+
+// ============================================================================
+
+static void __AddHexNibble( ByteString& r, UINT8 nVal )
+{
+ const sal_Char pH[] = "0123456789ABCDEF";
+
+ nVal &= 0x0F;
+
+ r += pH[ nVal ];
+}
+
+
+static void __AddPureHex( ByteString& r, UINT8 nVal )
+{
+ __AddHexNibble( r, nVal >> 4 );
+ __AddHexNibble( r, nVal );
+}
+
+
+static void __AddHex( ByteString& r, UINT8 nVal )
+{
+ r += __pHexPrefix;
+ __AddHexNibble( r, nVal >> 4 );
+ __AddHexNibble( r, nVal );
+}
+
+
+static void __AddPureHex( ByteString& r, UINT16 nVal )
+{
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 12 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 8 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 4 ) );
+ __AddHexNibble( r, ( UINT8 ) nVal );
+}
+
+
+static void __AddHex( ByteString& r, UINT16 nVal )
+{
+ r += __pHexPrefix;
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 12 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 8 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 4 ) );
+ __AddHexNibble( r, ( UINT8 ) nVal );
+}
+
+
+static void __AddPureHex( ByteString& r, UINT32 nVal )
+{
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 28 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 24 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 20 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 16 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 12 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 8 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 4 ) );
+ __AddHexNibble( r, ( UINT8 ) nVal );
+}
+
+
+static void __AddHex( ByteString& r, UINT32 nVal )
+{
+ r += __pHexPrefix;
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 28 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 24 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 20 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 16 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 12 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 8 ) );
+ __AddHexNibble( r, ( UINT8 ) ( nVal >> 4 ) );
+ __AddHexNibble( r, ( UINT8 ) nVal );
+}
+
+
+static void __AddHex( ByteString& r, INT32 nVal )
+{
+ __AddHex( r, (UINT32) nVal );
+}
+
+
+static void __AddPureBinNibble( ByteString& r, UINT8 nVal )
+{
+ nVal <<= 4;
+ for( int n = 4 ; n ; n-- )
+ {
+ r += ( nVal & 0x80 )? "1" : "0";
+ nVal <<= 1;
+ }
+}
+
+
+static void __AddPureBin( ByteString& r, UINT8 nVal )
+{
+ __AddPureBinNibble( r, nVal >> 4 );
+ r += " ";
+ __AddPureBinNibble( r, nVal );
+}
+
+
+static void __AddPureBin( ByteString& r, UINT16 nVal )
+{
+ const sal_Char* pIn = " ";
+ __AddPureBin( r, ( UINT8 ) ( nVal >> 8 ) );
+ r += pIn;
+ __AddPureBin( r, ( UINT8 ) nVal );
+}
+
+
+static void __AddPureBin( ByteString& r, UINT32 nVal )
+{
+ const sal_Char* pIn = " ";
+ __AddPureBin( r, ( UINT8 ) ( nVal >> 24 ) );
+ r += pIn;
+ __AddPureBin( r, ( UINT8 ) ( nVal >> 16 ) );
+ r += pIn;
+ __AddPureBin( r, ( UINT8 ) ( nVal >> 8 ) );
+ r += pIn;
+ __AddPureBin( r, ( UINT8 ) nVal );
+}
+
+
+inline static void __AddDec( ByteString& r, UINT32 n )
+{
+ sal_Char p[ 32 ];
+ sprintf( p, "%u", n ); // #100211# - checked
+ r += p;
+}
+
+
+inline static void __AddDec( ByteString& r, UINT16 n )
+{
+ __AddDec( r, ( UINT32 ) n );
+}
+
+
+inline static void __AddDec( ByteString& r, UINT8 n )
+{
+ __AddDec( r, ( UINT32 ) n );
+}
+
+
+inline static void __AddDec( ByteString& r, INT32 n )
+{
+ sal_Char p[ 32 ];
+ sprintf( p, "%d", n ); // #100211# - checked
+ r += p;
+}
+
+
+inline static void __AddDec( ByteString& r, INT16 n )
+{
+ __AddDec( r, ( INT32 ) n );
+}
+
+inline static void __AddDec( ByteString& r, sal_Int8 n )
+{
+ __AddDec( r, ( INT32 ) n );
+}
+
+
+static void __AddDec( ByteString& r, UINT32 nVal, UINT16 nNumOfDig, sal_Char c = ' ' )
+{
+ ByteString t;
+ ByteString aVal;
+ __AddDec( aVal, nVal );
+ if( nNumOfDig > (UINT16) aVal.Len() )
+ t.Fill( nNumOfDig - (UINT16) aVal.Len(), c );
+ r += t;
+ r += aVal;
+}
+
+
+inline static void __AddDec1616( ByteString& r, UINT32 n )
+{
+ __AddDec( r, (UINT16)(n >> 16) );
+ r += '.';
+ __AddDec( r, (UINT16)(n & 0xFFFF) );
+}
+
+
+static void __AddDouble( ByteString& r, const double f )
+{
+ r += ByteString( ::rtl::math::doubleToString( f, rtl_math_StringFormat_G, 15, '.', TRUE ) );
+}
+
+
+static inline void __AddRK( ByteString& rString, sal_Int32 nRKValue )
+{
+ __AddDouble( rString, XclTools::GetDoubleFromRK( nRKValue ) );
+}
+
+
+inline static void __Add16p16( ByteString& r, UINT32 n )
+{
+ __AddDouble( r, double(n) / 65536.0 );
+}
+
+
+static void lcl_AddRef( ByteString& rStr, sal_uInt16 nCol, sal_uInt16 nRow )
+{
+ ScAddress aRef( static_cast< SCCOL >( nCol ), static_cast< SCROW >( nRow ), 0 );
+ rStr.Append( GETSTR( aRef.GetColRowString() ) );
+}
+
+
+static void lcl_AddRangeRef( ByteString& rStr, sal_uInt16 nCol1, sal_uInt16 nRow1, sal_uInt16 nCol2, sal_uInt16 nRow2 )
+{
+ lcl_AddRef( rStr, nCol1, nRow1 );
+ if( (nCol1 != nCol2) || (nRow1 != nRow2) )
+ {
+ rStr.Append( ':' );
+ lcl_AddRef( rStr, nCol2, nRow2 );
+ }
+}
+
+
+static void __AddCellHead( ByteString& r, const UINT16 nC, const UINT16 nR, const UINT16 nXF )
+{
+ lcl_AddRef( r, (UINT8) nC, nR );
+ r += " (XF=";
+ __AddDec( r, nXF );
+ r += ')';
+}
+
+
+inline static void lcl_AddFlag(
+ ByteString& rString, bool bFlag, const sal_Char* pcTrue = "true", const sal_Char* pcFalse = "false" )
+{
+ rString += (bFlag ? pcTrue : pcFalse);
+}
+
+inline static void lcl_AddOnOff( ByteString& rString, bool bFlag )
+{
+ lcl_AddFlag( rString, bFlag, "on", "off" );
+}
+
+
+static void lcl_AddEnum(
+ ByteString& rString, long nValue, const sal_Char* const ppcEnums[], long nSize,
+ const sal_Char* pcDefault = 0, long nOffset = 0 )
+{
+ nValue -= nOffset;
+ const sal_Char* pcText = "!unknown!";
+ if( (0 <= nValue) && (nValue < nSize) && ppcEnums[ nValue ] )
+ pcText = ppcEnums[ nValue ];
+ else if( pcDefault )
+ pcText = pcDefault;
+ if( *pcText ) // nonempty string
+ rString.Append( " (" ).Append( pcText ).Append( ')' );
+}
+
+
+namespace {
+
+void lclDumpString( SvStream& rOutStrm, const ByteString& rData )
+{
+ ByteString aOutStr;
+ xub_StrLen nIdx = 0;
+ for( ; (nIdx < rData.Len()) && (aOutStr.Len() < 80); ++nIdx )
+ {
+ sal_Char cChar = rData.GetChar( nIdx );
+ if( 32 <= cChar )
+ aOutStr.Append( cChar );
+ else
+ {
+ aOutStr.Append( '<' );
+ __AddHex( aOutStr, static_cast< sal_uInt8 >( cChar ) );
+ aOutStr.Append( '>' );
+ }
+ }
+ rOutStrm << aOutStr.GetBuffer();
+ if( nIdx < rData.Len() )
+ rOutStrm << "<...>";
+}
+
+void lclDumpStringValue( SvStream& rOutStrm, const ByteString& rName, const ByteString& rData )
+{
+ rOutStrm << rName.GetBuffer() << "='";
+ lclDumpString( rOutStrm, rData );
+ rOutStrm << '\'';
+}
+
+void lclDumpString( SvStream& rOutStrm, const String& rData )
+{
+ ByteString aOutStr;
+ xub_StrLen nIdx = 0;
+ for( ; (nIdx < rData.Len()) && (aOutStr.Len() < 80); ++nIdx )
+ {
+ sal_Unicode cChar = rData.GetChar( nIdx );
+ if( (32 <= cChar) && (cChar <= 255) )
+ aOutStr.Append( static_cast< sal_Char >( cChar ) );
+ else
+ {
+ aOutStr.Append( '<' );
+ if( cChar < 256 )
+ __AddHex( aOutStr, static_cast< sal_uInt8 >( cChar ) );
+ else
+ __AddHex( aOutStr, static_cast< sal_uInt16 >( cChar ) );
+ aOutStr.Append( '>' );
+ }
+ }
+ rOutStrm << aOutStr.GetBuffer();
+ if( nIdx < rData.Len() )
+ rOutStrm << "<...>";
+}
+
+void lclDumpStringValue( SvStream& rOutStrm, const ByteString& rName, const String& rData )
+{
+ rOutStrm << rName.GetBuffer() << "='";
+ lclDumpString( rOutStrm, rData );
+ rOutStrm << '\'';
+}
+
+} // namespace
+
+
+IdRangeList::~IdRangeList()
+{
+ Clear();
+}
+
+
+void IdRangeList::Clear( void )
+{
+ IdRange* p = ( IdRange* ) First();
+
+ while( p )
+ {
+ delete p;
+ p = ( IdRange* ) Next();
+ }
+
+ List::Clear();
+}
+
+// ============================================================================
+//
+// H E L P E R O B J E C T S
+//
+// ============================================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+class XclDumpStreamHeader
+{
+public:
+ explicit XclDumpStreamHeader( SvStream& rInStrm, SvStream& rOutStrm, const String& rStrmName, const String& rStrmPath );
+ ~XclDumpStreamHeader();
+ inline ULONG GetStreamLen() const { return mnStrmLen; }
+
+private:
+ SvStream& mrOutStrm;
+ String maStrmName;
+ String maStrmPath;
+ ByteString maSeparator;
+ ULONG mnStrmLen;
+};
+
+XclDumpStreamHeader::XclDumpStreamHeader( SvStream& rInStrm, SvStream& rOutStrm, const String& rStrmName, const String& rStrmPath ) :
+ mrOutStrm( rOutStrm ),
+ maStrmName( rStrmName ),
+ maStrmPath( rStrmPath ),
+ mnStrmLen( 0 )
+{
+ maSeparator.Assign( '+' ).Expand( 78, '-' );
+
+ rInStrm.Seek( STREAM_SEEK_TO_END );
+ mnStrmLen = rInStrm.Tell();
+ rInStrm.Seek( STREAM_SEEK_TO_BEGIN );
+
+ ByteString aLine;
+ lclAppendDec( aLine, mnStrmLen );
+
+ mrOutStrm << maSeparator.GetBuffer() << "\n";
+ mrOutStrm << "| STREAM-BEGIN\n";
+ mrOutStrm << "| ";
+ lclDumpStringValue( mrOutStrm, "stream-name", maStrmName );
+ mrOutStrm << "\n| ";
+ lclDumpStringValue( mrOutStrm, "stream-path", maStrmPath );
+ mrOutStrm << "\n| stream-len=" << aLine.GetBuffer() << "\n";
+ mrOutStrm << "|\n\n";
+}
+
+XclDumpStreamHeader::~XclDumpStreamHeader()
+{
+ mrOutStrm << "|\n";
+ mrOutStrm << "| ";
+ lclDumpStringValue( mrOutStrm, "stream-name", maStrmName );
+ mrOutStrm << "\n| ";
+ lclDumpStringValue( mrOutStrm, "stream-path", maStrmPath );
+ mrOutStrm << "\n";
+ mrOutStrm << "| STREAM-END\n";
+ mrOutStrm << maSeparator.GetBuffer() << "\n\n";
+}
+
+// ----------------------------------------------------------------------------
+
+class XclDumpStorageHeader
+{
+public:
+ explicit XclDumpStorageHeader( SotStorage& rInStrg, SvStream& rOutStrm, const String& rStrgPath );
+ ~XclDumpStorageHeader();
+
+private:
+ SvStream& mrOutStrm;
+ String maStrgName;
+ String maStrgPath;
+ ByteString maSeparator;
+};
+
+XclDumpStorageHeader::XclDumpStorageHeader( SotStorage& rInStrg, SvStream& rOutStrm, const String& rStrgPath ) :
+ mrOutStrm( rOutStrm ),
+ maStrgName( rInStrg.GetName() ),
+ maStrgPath( rStrgPath )
+{
+ maSeparator.Assign( "++" ).Expand( 78, '=' );
+
+ mrOutStrm << maSeparator.GetBuffer() << "\n";
+ mrOutStrm << "|| STORAGE-BEGIN\n";
+ mrOutStrm << "|| ";
+ lclDumpStringValue( mrOutStrm, "storage-name", maStrgName );
+ mrOutStrm << "\n|| ";
+ lclDumpStringValue( mrOutStrm, "storage-path", maStrgPath );
+ mrOutStrm << "\n";
+
+ SvStorageInfoList aInfoList;
+ rInStrg.FillInfoList( &aInfoList );
+ ByteString aLine;
+ lclAppendDec( aLine, aInfoList.Count() );
+ mrOutStrm << "|| directory-size=" << aLine.GetBuffer() << "\n";
+
+ for( ULONG nInfo = 0; nInfo < aInfoList.Count(); ++nInfo )
+ {
+ SvStorageInfo& rInfo = aInfoList.GetObject( nInfo );
+ mrOutStrm << "|| type=";
+ if( rInfo.IsStream() )
+ mrOutStrm << "stream ";
+ else if( rInfo.IsStorage() )
+ mrOutStrm << "storage ";
+ else
+ mrOutStrm << "unknown ";
+ lclDumpStringValue( mrOutStrm, "name", rInfo.GetName() );
+ mrOutStrm << "\n";
+ }
+
+ mrOutStrm << "||\n\n";
+}
+
+XclDumpStorageHeader::~XclDumpStorageHeader()
+{
+ mrOutStrm << "||\n";
+ mrOutStrm << "|| ";
+ lclDumpStringValue( mrOutStrm, "storage-name", maStrgName );
+ mrOutStrm << "\n|| ";
+ lclDumpStringValue( mrOutStrm, "storage-path", maStrgPath );
+ mrOutStrm << "\n";
+ mrOutStrm << "|| STORAGE-END\n";
+ mrOutStrm << maSeparator.GetBuffer() << "\n\n";
+}
+
+// ----------------------------------------------------------------------------
+
+}
+
+// ============================================================================
+//
+// ============================================================================
+
+void Biff8RecDumper::Print( const ByteString& r )
+{
+ DBG_ASSERT( pDumpStream, "-Biff8RecDumper::Print(): Stream is wech!" );
+ *pDumpStream << '\n' << pLevelPre;
+ pDumpStream->Write( r.GetBuffer(), r.Len() );
+}
+
+
+void Biff8RecDumper::Print( const sal_Char* p )
+{
+ DBG_ASSERT( pDumpStream, "-Biff8RecDumper::Print(): Stream is wech!" );
+ DBG_ASSERT( p, "-Biff8RecDumper::Print(): ByteString is wech!" );
+
+ *pDumpStream << '\n' << pLevelPre << p;
+}
+
+
+static const sal_Char* GetSeriesType( const UINT16 n )
+{
+ const sal_Char* p;
+
+ switch( n )
+ {
+ case 0: p = "(date) "; break;
+ case 1: p = "(numeric) "; break;
+ case 2: p = "(sequence)"; break;
+ case 3: p = "(text) "; break;
+ default: p = "(unknown) ";
+ }
+
+ return p;
+}
+
+
+static const sal_Char* GetLineType( const UINT16 n )
+{
+ const sal_Char* p;
+
+ switch( n )
+ {
+ case 0: p = "solid"; break;
+ case 1: p = "dash"; break;
+ case 2: p = "dot"; break;
+ case 3: p = "dash-dot"; break;
+ case 4: p = "dash-dot-dot"; break;
+ case 5: p = "none"; break;
+ case 6: p = "dark gray pattern"; break;
+ case 7: p = "medium gray pattern"; break;
+ case 8: p = "light gray pattern"; break;
+ default: p = pU;
+ }
+
+ return p;
+}
+
+
+static ByteString GetRGB( const UINT32 n )
+{
+ ByteString s;
+
+ s += "R";
+ __AddDec( s, ( UINT8 ) n );
+ s += " G";
+ __AddDec( s, ( UINT8 ) ( n >> 8 ) );
+ s += " B";
+ __AddDec( s, ( UINT8 ) ( n >> 16 ) );
+
+ return s;
+}
+
+
+static void AddRef( ByteString& t, UINT16 nRow, UINT16 nC, BOOL bName, UINT16 nTab = 0xFFFF )
+{
+ BOOL bColRel = ( nC & 0x4000 ) != 0;
+ BOOL bRowRel = ( nC & 0x8000 ) != 0;
+ UINT8 nCol = (UINT8) nC;
+ INT8 nRelCol = (INT8) nCol;
+ INT16 nRelRow = (INT16) nRow;
+
+ if( nTab < 0xFFFF )
+ {
+ t += "XTI(";
+ __AddDec( t, nTab );
+ t += ")!";
+ }
+
+ if( bName )
+ {
+ // dump relative: [Column|Row]
+ // [C-1,R-1] = one column left, one row up
+ // [C+1,R+1] = one column right, one row down
+ // [C,R] = same column/row
+ // [C=B,R=2] = absolute column B/row 2
+ t += "[C";
+ if( bColRel )
+ {
+ if( nRelCol > 0 )
+ t += '+';
+ if( nRelCol != 0 )
+ __AddDec( t, (INT16)nRelCol );
+ }
+ else
+ {
+ t += '=';
+ t += GETSTR( ::ScScColToAlpha( nCol ) );
+ }
+
+ t += ",R";
+ if( bRowRel )
+ {
+ if( nRelRow > 0 )
+ t += "+";
+ if( nRelRow != 0 )
+ __AddDec( t, nRelRow );
+ }
+ else
+ {
+ t += '=';
+ __AddDec( t, (INT32)nRow + 1 );
+ }
+ t += ']';
+ }
+ else
+ {
+ if( !bColRel )
+ t += '$';
+ t += GETSTR( ::ScColToAlpha( nCol ) );
+ if( !bRowRel )
+ t += '$';
+ __AddDec( t, (UINT16)(nRow + 1) );
+ }
+}
+
+static void AddRangeRef( ByteString& t, UINT16 nRow1, UINT16 nC1, UINT16 nRow2, UINT16 nC2, BOOL bName, UINT16 nTab = 0xFFFF )
+{
+ AddRef( t, nRow1, nC1, bName, nTab );
+ if( (nRow1 != nRow2) || (nC1 != nC2) )
+ {
+ t += ':';
+ AddRef( t, nRow2, nC2, bName );
+ }
+}
+
+
+
+static BOOL AddUNICODEString( ByteString& rStr, XclImpStream& rStrm, const BOOL b16BitLen = TRUE, UINT16 nLen = 0, ByteString* pRawName = 0 )
+{
+ BOOL bRet = TRUE;
+
+ if( !nLen )
+ nLen = b16BitLen ? rStrm.ReaduInt16() : rStrm.ReaduInt8();
+ UINT8 nGrbit = rStrm.ReaduInt8();
+
+ UINT32 nExtLen;
+ UINT16 nCrun;
+ bool b16Bit, bFarEast, bRichString;
+ rStrm.ReadUniStringExtHeader( b16Bit, bRichString, bFarEast, nCrun, nExtLen, nGrbit );
+
+ rStr += "(l=";
+ __AddDec( rStr, nLen );
+ rStr += " f=";
+ __AddHex( rStr, nGrbit );
+ rStr += " ";
+ rStr += b16Bit ? "16-Bit" : "8-Bit";
+
+ if( bRichString && bFarEast )
+ rStr += " rich far-east";
+ else if( bRichString && !bFarEast )
+ rStr += " rich";
+ else if ( !bRichString && bFarEast )
+ rStr += " far-east";
+ rStr += ") '";
+
+ ByteString aData( rStrm.ReadRawUniString( nLen, b16Bit ), RTL_TEXTENCODING_MS_1252 );
+ if( pRawName ) *pRawName = aData;
+
+ xub_StrLen nIndex = 0;
+ while( (nIndex < aData.Len()) && (nIndex < 255) )
+ {
+ UINT8 nChar = (UINT8)aData.GetChar( nIndex );
+ if( nChar < ' ' )
+ {
+ ByteString aIns( '<' );
+ __AddHex( aIns, nChar );
+ aIns += '>';
+ aData.Erase( nIndex, 1 ).Insert( aIns, nIndex );
+ nIndex += 5;
+ }
+ nIndex++;
+ }
+
+ rStr += aData.Copy( 0, 255 );
+ rStr += '\'';
+ if( aData.Len() > 255 )
+ rStr += "...";
+
+ if( nCrun )
+ {
+ rStr += " + ";
+ __AddDec( rStr, nCrun );
+ rStr += " format blocks (";
+ nCrun *= 4;
+ __AddDec( rStr, nCrun );
+ rStr += " bytes)";
+ rStrm.Ignore( nCrun );
+ }
+ if( nExtLen )
+ {
+ rStr += " + ";
+ __AddDec( rStr, nExtLen );
+ rStr += " byte extended:";
+ for( sal_uInt32 nIdx = 0; rStrm.IsValid() && (nIdx < nExtLen); ++nIdx )
+ {
+ rStr.Append( ' ' );
+ __AddPureHex( rStr, rStrm.ReaduInt8() );
+ }
+ }
+
+ return bRet;
+}
+
+
+DUMP_ERR::~DUMP_ERR()
+{
+ if( pHint )
+ delete pHint;
+}
+
+
+
+
+#define Read1(rIn) (rIn).ReaduInt8()
+#define Read2(rIn) (rIn).ReaduInt16()
+#define Read4(rIn) (rIn).ReaduInt32()
+#define Read8(rIn) (rIn).ReadDouble()
+#define LINESTART() {t.Erase();t+=pPre;}
+#define IGNORE(n) rIn.Ignore(n)
+#define ADDBIN(n) __AddBin( t, Read##n( rIn ) )
+#define ADDHEX(n) __AddHex( t, Read##n( rIn ) )
+#define ADDDEC(n) __AddDec( t, Read##n( rIn ) )
+#define ADDDOUBLE() __AddDouble( t, rIn.ReadDouble() )
+#define ADD16P16() __Add16p16( t, Read4( rIn ) )
+#define ADDTEXT(T) t += T
+#define PRINT() Print( t )
+#define PreDump(LEN) {rIn.PushPosition();ContDump(LEN);rIn.PopPosition();}
+#define ADDCELLHEAD() {UINT16 nR,nC,nX;rIn>>nR>>nC>>nX;__AddCellHead(t,nC,nR,nX);}
+#define STARTFLAG() {ADDTEXT( "flags=" ); __AddHex( t, __nFlags ); ADDTEXT( " " );}
+#define ADDFLAG(mask,text) {if( __nFlags & mask ) t.Append( ' ' ).Append( text );}
+#define ADDRESERVED(mask) ADDFLAG(mask,"!RESERVED!")
+
+
+UINT16 Biff8RecDumper::DumpXF( XclImpStream& rStrm, const sal_Char* pPre )
+{
+ ByteString t; // "t" needed by macros
+
+ sal_uInt32 nBorder1, nBorder2;
+ sal_uInt16 nFont, nNumFmt, nTypeProt, nAlign, nMiscAttrib, nArea, __nFlags, nTmp;
+ rStrm >> nFont >> nNumFmt >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
+ bool bCell = !::get_flag( nTypeProt, EXC_XF_STYLE );
+
+ // XF type/parent
+ LINESTART();
+ ::extract_value( nTmp, nTypeProt, 4, 12 );
+ ADDTEXT( "index=#" ); __AddDec( t, nXFCount++ );
+ ADDTEXT( " type=" ); lcl_AddFlag( t, bCell, "cell", "style" );
+ ADDTEXT( " parent-xf=#" ); __AddDec( t, nTmp );
+ PRINT();
+
+ // attribute used flags
+ LINESTART();
+ ::extract_value( __nFlags, nMiscAttrib, 10, 6 );
+ if( !bCell ) __nFlags ^= 0x3F; // in style XFs a 0 means used
+ ADDTEXT( "used " ); STARTFLAG();
+ ADDFLAG( EXC_XF_DIFF_VALFMT, "numfmt" );
+ ADDFLAG( EXC_XF_DIFF_FONT, "font" );
+ ADDFLAG( EXC_XF_DIFF_ALIGN, "align" );
+ ADDFLAG( EXC_XF_DIFF_BORDER, "border" );
+ ADDFLAG( EXC_XF_DIFF_AREA, "area" );
+ ADDFLAG( EXC_XF_DIFF_PROT, "prot" );
+ PRINT();
+
+ // cell protection/font/number format
+ LINESTART();
+ ADDTEXT( "cell-lock=" ); lcl_AddOnOff( t, ::get_flag( nTypeProt, EXC_XF_LOCKED ) );
+ ADDTEXT( " hidden=" ); lcl_AddOnOff( t, ::get_flag( nTypeProt, EXC_XF_HIDDEN ) );
+ ADDTEXT( " font=" ); __AddDec( t, nFont );
+ ADDTEXT( " num-fmt=" ); __AddDec( t, nNumFmt );
+ PRINT();
+
+ // alignment
+ LINESTART();
+ ::extract_value( nTmp, nAlign, 0, 3 );
+ ADDTEXT( "hor-align=" ); __AddDec( t, nTmp );
+ ADDTEXT( " (" );
+ switch( nTmp )
+ {
+ case EXC_XF_HOR_GENERAL: ADDTEXT( "general" ); break;
+ case EXC_XF_HOR_LEFT: ADDTEXT( "left" ); break;
+ case EXC_XF_HOR_CENTER: ADDTEXT( "center" ); break;
+ case EXC_XF_HOR_RIGHT: ADDTEXT( "right" ); break;
+ case EXC_XF_HOR_FILL: ADDTEXT( "fill" ); break;
+ case EXC_XF_HOR_JUSTIFY: ADDTEXT( "justify" ); break;
+ case EXC_XF_HOR_CENTER_AS: ADDTEXT( "center-as" ); break;
+ case EXC_XF_HOR_DISTRIB: ADDTEXT( "distrib" ); break;
+ default: ADDTEXT( "!unknown!" );
+ };
+ ::extract_value( nTmp, nAlign, 4, 3 );
+ ADDTEXT( ") ver-align=" ); __AddDec( t, nTmp );
+ ADDTEXT( " (" );
+ switch( nTmp )
+ {
+ case EXC_XF_VER_TOP: ADDTEXT( "top" ); break;
+ case EXC_XF_VER_CENTER: ADDTEXT( "center" ); break;
+ case EXC_XF_VER_BOTTOM: ADDTEXT( "bottom" ); break;
+ case EXC_XF_VER_JUSTIFY: ADDTEXT( "justify" ); break;
+ case EXC_XF_VER_DISTRIB: ADDTEXT( "distrib" ); break;
+ default: ADDTEXT( "!unknown!" );
+ };
+ ADDTEXT( ") text-wrap=" ); lcl_AddOnOff( t, ::get_flag( nAlign, EXC_XF_LINEBREAK ) );
+ PRINT();
+
+ LINESTART();
+ ::extract_value( nTmp, nAlign, 8, 8 );
+ ADDTEXT( "rotation=" ); __AddDec( t, nTmp );
+ ADDTEXT( " (" );
+ if( nTmp < 91 )
+ { __AddDec( t, nTmp ); ADDTEXT( "\xB0" ); }
+ else if( nTmp < 181 )
+ { __AddDec( t, static_cast< sal_Int32 >( 90 - nTmp ) ); ADDTEXT( "\xB0" ); }
+ else if( nTmp == EXC_ROT_STACKED )
+ { ADDTEXT( "stacked" ); }
+ else
+ { ADDTEXT( "!unknown!" ); }
+ ::extract_value( nTmp, nMiscAttrib, 0, 4 );
+ ADDTEXT( ") indent=" ); __AddDec( t, nTmp );
+ ADDTEXT( " shrink=" ); lcl_AddOnOff( t, ::get_flag( nMiscAttrib, EXC_XF8_SHRINK ) );
+ ::extract_value( nTmp, nMiscAttrib, 6, 2 );
+ ADDTEXT( " text-dir=" ); __AddDec( t, nTmp );
+ ADDTEXT( " (" );
+ switch( nTmp )
+ {
+ case EXC_XF_TEXTDIR_CONTEXT: ADDTEXT( "context" ); break;
+ case EXC_XF_TEXTDIR_LTR: ADDTEXT( "ltr" ); break;
+ case EXC_XF_TEXTDIR_RTL: ADDTEXT( "rtl" ); break;
+ default: ADDTEXT( "!unknown!" );
+ };
+ ADDTEXT( ")" );
+ PRINT();
+
+ // border/area
+ LINESTART();
+ ::extract_value( nTmp, nBorder1, 0, 4 );
+ ADDTEXT( "left-line=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder1, 16, 7 );
+ ADDTEXT( " color=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder1, 4, 4 );
+ ADDTEXT( " right-line =" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder1, 23, 7 );
+ ADDTEXT( " color=" ); __AddDec( t, nTmp );
+ PRINT();
+ LINESTART();
+ ::extract_value( nTmp, nBorder1, 8, 4 );
+ ADDTEXT( "top-line =" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder2, 0, 7 );
+ ADDTEXT( " color=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder1, 12, 4 );
+ ADDTEXT( " bottom-line=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder2, 7, 7 );
+ ADDTEXT( " color=" ); __AddDec( t, nTmp );
+ PRINT();
+ LINESTART();
+ ::extract_value( nTmp, nBorder2, 21, 4 );
+ ADDTEXT( "diag-line=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nBorder2, 14, 7 );
+ ADDTEXT( " color=" ); __AddDec( t, nTmp );
+ ADDTEXT( " diag-tl-to-br=" ); lcl_AddOnOff( t, ::get_flag( nBorder1, 0x40000000UL ) );
+ ADDTEXT( " diag-bl-to-tr=" ); lcl_AddOnOff( t, ::get_flag( nBorder1, 0x80000000UL ) );
+ PRINT();
+ LINESTART();
+ ::extract_value( nTmp, nBorder2, 26, 6 );
+ ADDTEXT( "area-pattern=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nArea, 0, 7 );
+ ADDTEXT( " fore-color=" ); __AddDec( t, nTmp );
+ ::extract_value( nTmp, nArea, 7, 7 );
+ ADDTEXT( " back-color=" ); __AddDec( t, nTmp );
+ PRINT();
+
+ return 0;
+}
+
+void Biff8RecDumper::DumpValidPassword( XclImpStream& rIn, const sal_Char* pPre )
+{
+ ByteString t;
+ UINT16 nHash;
+ rIn >> nHash;
+ LINESTART();
+ ADDTEXT( "hash=" );
+ __AddHex( t, nHash );
+ if( nHash )
+ {
+ ByteString sPasswd;
+ ByteString sDummy;
+ UINT16 nLen = 9;
+ UINT16 nDummy;
+ UINT16 nNewChar;
+
+ nHash ^= 0xCE4B;
+ nDummy = nHash;
+ ADDTEXT( " without-mask=" );
+ __AddHex( t, nHash );
+ while( !(nDummy & 0x8000) && nLen )
+ {
+ nLen--;
+ nDummy <<= 1;
+ }
+ if( !nLen ) nLen = 2;
+ if( (nLen ^ nHash) & 0x0001 ) nLen++;
+ if( nLen == 9 )
+ {
+ nLen = 10;
+ nHash ^= 0x8001;
+ }
+ nHash ^= nLen;
+ if( nLen < 9 ) nHash <<= (8 - nLen);
+ for( UINT16 iChar = nLen; iChar > 0; iChar-- )
+ {
+ switch( iChar )
+ {
+ case 10:
+ nNewChar = (nHash & 0xC000) | 0x0400;
+ nHash ^= nNewChar;
+ nNewChar >>= 2;
+ break;
+ case 9:
+ nNewChar = 0x4200;
+ nHash ^= nNewChar;
+ nNewChar >>= 1;
+ break;
+ case 1:
+ nNewChar = nHash & 0xFF00;
+ break;
+ default:
+ nNewChar = (nHash & 0xE000) ^ 0x2000;
+ if( !nNewChar ) nNewChar = (nHash & 0xF000) ^ 0x1800;
+ if( nNewChar == 0x6000 ) nNewChar = 0x6100;
+ nHash ^= nNewChar;
+ nHash <<= 1;
+ break;
+ }
+ nNewChar >>= 8;
+ nNewChar &= 0x00FF;
+ sDummy = sPasswd;
+ sPasswd = (sal_Char) nNewChar;
+ sPasswd += sDummy;
+ }
+ ADDTEXT( " valid-password='" );
+ t += sPasswd;
+ ADDTEXT( "'" );
+ }
+ PRINT();
+}
+
+
+void __AddGUID( ByteString& rStr, XclImpStream& rIn )
+{
+ UINT16 nIndex;
+ __AddPureHex( rStr, Read4( rIn ) );
+ rStr += "-";
+ __AddPureHex( rStr, Read2( rIn ) );
+ rStr += "-";
+ __AddPureHex( rStr, Read2( rIn ) );
+ rStr += "-";
+ // last 2 parts byte for byte
+ for( nIndex = 0; nIndex < 2; nIndex++ )
+ __AddPureHex( rStr, Read1( rIn ) );
+ rStr += "-";
+ for( nIndex = 0; nIndex < 6; nIndex++ )
+ __AddPureHex( rStr, Read1( rIn ) );
+}
+
+
+void Biff8RecDumper::PreDumpDecrypted( ULONG nL )
+{
+ if( !nL ) return;
+
+ ByteString t;
+ const sal_Char* pPre = (pLevelPre > pLevelPreString) ? pLevelPre - 1 : pLevelPre;
+
+ LINESTART();
+ ADDTEXT( "*** encrypted ***" );
+ PRINT();
+ pIn->DisableDecryption();
+ pIn->Seek( EXC_REC_SEEK_TO_BEGIN );
+ ContDump( nL );
+
+ if( pIn->HasValidDecrypter() )
+ {
+ LINESTART();
+ ADDTEXT( "*** decrypted ***" );
+ PRINT();
+ pIn->EnableDecryption();
+ pIn->Seek( EXC_REC_SEEK_TO_BEGIN );
+ ContDump( nL );
+ }
+}
+
+
+void Biff8RecDumper::RecDump( BOOL bSubStream )
+{
+ const sal_Char* p;
+ BOOL bDec = FALSE;
+ ByteString aTmp;
+ UINT16 __nFlags;
+ const UINT16 nR = pIn->GetRecId();
+ const ByteString* pName = GetName( nR );
+
+ // set CONTINUE handling mode
+ switch( nR )
+ {
+ case 0x000A: // EOF
+ case 0x003C: // CONT
+ case 0x005D: // OBJ
+ case 0x00EC: // MSODRAWING
+ case 0x01B6: // TXO
+ pIn->ResetRecord( false );
+ break;
+ case 0x1066: // CHGELFRAME
+ pIn->ResetRecord( bReadContRecs, 0x1066 );
+ break;
+ default:
+ pIn->ResetRecord( bReadContRecs );
+ }
+ const ULONG nL = pIn->GetRecSize();
+
+ switch( nR )
+ {
+ case 0x0009:
+ case 0x0209:
+ case 0x0409:
+ case 0x0809:
+ nLevelCnt = 0;
+ break;
+ case 0x1033:
+ if( pName )
+ aTmp = *pName;
+ else
+ aTmp = "BEGIN ";
+ bDec = ( pLevelPre + nLevelInc ) >= pLevelPreString;
+ nLevelCnt++;
+ aTmp.Append( ByteString::CreateFromInt32( nLevelCnt ) );
+ pName = &aTmp;
+ break;
+ case 0x1034:
+ if( pName )
+ aTmp = *pName;
+ else
+ aTmp = "END ";
+ if( ( pLevelPre + nLevelInc ) <= pLevelPreStringNT )
+ pLevelPre += nLevelInc;
+ if( nLevelCnt )
+ {
+ aTmp.Append( ByteString::CreateFromInt32( nLevelCnt ) );
+ nLevelCnt--;
+ }
+ else
+ aTmp += "#LEVEL ERROR#";
+ pName = &aTmp;
+ break;
+ }
+
+ ByteString aT;
+ ByteString& t = aT;
+ const sal_Char* pPre = (pLevelPre > pLevelPreString) ? pLevelPre - 1 : pLevelPre;
+
+ if( nR || nL ) // skip dummy-zero DIMENSIONS at eof
+ {
+ if( bBlankLine )
+ *pDumpStream << '\n';
+
+ aT += pLevelPre;
+ __AddHex( aT, nR );
+
+ if( pName )
+ {
+ aT += " (";
+ aT += *pName;
+ aT += ") [";
+ }
+ else
+ aT += " [";
+
+ if( bReadContRecs )
+ __AddHex( aT, nL );
+ else
+ __AddHex( aT, (UINT16)nL );
+ aT += "]";
+ if( !bSkipOffset )
+ {
+ aT += " :";
+ __AddHex( aT, UINT32(pIn->GetSvStreamPos() - 2 * sizeof(UINT16)) );
+ aT += ':';
+ }
+
+ Print( aT );
+ }
+
+ if( HasModeNameOnly( nR ) )
+ ;
+ else if( HasModeHex( nR ) || !bBIFF8 )
+ {
+ if( bEncrypted )
+ PreDumpDecrypted( nL );
+ else
+ ContDump( nL );
+ }
+ else if( nMaxBodyLines && nL )
+ {
+ XclImpStream& rIn = *pIn;
+
+ if( bEncrypted )
+ {
+ PreDumpDecrypted( nL );
+ LINESTART();
+ ADDTEXT( "*** contents ***" );
+ PRINT();
+ pIn->Seek( EXC_REC_SEEK_TO_BEGIN );
+ }
+
+ LINESTART();
+
+ switch( nR )
+ {
+ case 0x0000: // DIMENSIONS - used area
+ case 0x0200:
+ {
+ LINESTART();
+ UINT32 nR1, nR2;
+ UINT16 nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ ADDTEXT( "first row: " ); __AddHex( t, nR1 );
+ ADDTEXT( " last row+1: " ); __AddHex( t, nR2 );
+ ADDTEXT( " first col: " ); __AddHex( t, nC1 );
+ ADDTEXT( " last col+1: " ); __AddHex( t, nC2 );
+ ADDTEXT( " (" ); lcl_AddRangeRef( t, nC1, (UINT16)nR1, nC2-1, (UINT16)nR2-1 );
+ ADDTEXT( ")" );
+ PRINT();
+ }
+ break;
+ case 0x06:
+ {
+ ADDCELLHEAD();
+ PRINT();
+ LINESTART();
+ ADDTEXT( "val = " );
+ ADDDOUBLE();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ ADDTEXT( " " );
+ STARTFLAG();
+ ADDFLAG( 0x01, "fAlwaysCalc" );
+ ADDFLAG( 0x02, "fCalcOnLoad" );
+ ADDFLAG( 0x08, "fShrFmla" );
+ }
+ PRINT();
+ LINESTART();
+ UINT16 n;
+ ADDTEXT( "chn = " );
+ ADDHEX( 4 );
+ rIn >> n;
+ ADDTEXT( " cce = " );
+ __AddDec( t, n );
+ PRINT();
+ FormulaDump( n, FT_CellFormula );
+ if( rIn.GetRecLeft() > 0 )
+ {
+ LINESTART();
+ ADDTEXT( "additional formula data" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ }
+ break;
+ case 0x0013: // PASSWORD
+ DumpValidPassword( rIn, pPre );
+ break;
+ case 0x0014: // HEADER
+ case 0x0015: // FOOTER
+ if( rIn.GetRecLeft() )
+ AddUNICODEString( t, rIn );
+ PRINT();
+ break;
+ case 0x17:
+ {
+ if( mnSubstream == EXC_BOF_WORKSPACE )
+ {
+ ADDTEXT( "filename=" );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ else
+ {
+ UINT16 n;
+ rIn >> n;
+ ADDTEXT( "# of XTI: " );
+ __AddDec( t, n );
+ PRINT();
+ UINT16 nSB, nF, nL;
+ while( n && rIn.IsValid() )
+ {
+ LINESTART();
+ rIn >> nSB >> nF >> nL;
+ ADDTEXT( "Supbook = " );
+ __AddDec( t, nSB );
+ ADDTEXT( " Tab = " );
+ __AddDec( t, nF );
+ ADDTEXT( " ... " );
+ __AddDec( t, nL );
+ PRINT();
+ n--;
+ }
+ }
+ }
+ break;
+ case 0x0018:
+ case 0x0218: // NAME
+ {
+ sal_uInt8 nKey, nNameLen, nMenuLen, nDescrLen, nHelpLen, nStatusLen;
+ sal_uInt16 nFmlaSize, nRes, nTab;
+
+ rIn >> __nFlags >> nKey >> nNameLen >> nFmlaSize >> nRes >> nTab >> nMenuLen >> nDescrLen >> nHelpLen >> nStatusLen;
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fHidden" );
+ ADDFLAG( 0x0002, "fFunc" );
+ ADDFLAG( 0x0004, "fVBProc" );
+ ADDFLAG( 0x0008, "fProc" );
+ ADDFLAG( 0x0010, "fCalcExp" );
+ ADDFLAG( 0x0020, "fBuiltIn" );
+ ADDFLAG( 0x1000, "fBig" );
+ ADDRESERVED( 0xE000 );
+ ADDTEXT( " func-group-idx=" );
+ __AddDec( t, (UINT16)((__nFlags & 0x0FC0) >> 6) );
+ ADDTEXT( " shortcut=" ); __AddHex( t, nKey );
+ PRINT();
+
+ LINESTART();
+ ADDTEXT( "fmla-size=" ); __AddDec( t, nFmlaSize );
+ ADDTEXT( " reserved=" ); __AddHex( t, nRes );
+ ADDTEXT( " tab=" ); __AddDec( t, nTab );
+ if( !nTab ) ADDTEXT( " (global)" );
+ PRINT();
+
+ LINESTART();
+ sal_uInt16 nBuiltIn = 0;
+ bool bBuiltIn = (nNameLen == 1) && (__nFlags & 0x0020);
+ if( bBuiltIn )
+ {
+ rIn.PushPosition();
+ sal_uInt8 nStrFlags;
+ rIn >> nStrFlags;
+ nBuiltIn = (nStrFlags & 1) ? rIn.ReaduInt16() : rIn.ReaduInt8();
+ rIn.PopPosition();
+ }
+ ADDTEXT( "name=" );
+ ByteString aName;
+ AddUNICODEString( t, rIn, false, nNameLen, &aName );
+ if( bBuiltIn )
+ {
+ static const sal_Char* const ppcNames[] = {
+ "Consolidate_Area", "Auto_Open", "Auto_Close", "Extract", "Database",
+ "Criteria", "Print_Area", "Print_Titles", "Recorder", "Data_Form",
+ "Auto_Activate", "Auto_Deactivate", "Sheet_Title", "_FilterDatabase" };
+ lcl_AddEnum( t, nBuiltIn, ppcNames, STATIC_TABLE_SIZE( ppcNames ) );
+ if( (0 <= nBuiltIn) && (nBuiltIn < STATIC_TABLE_SIZE( ppcNames )) )
+ aName.Assign( ppcNames[ nBuiltIn ] );
+ }
+ maNames.push_back( aName );
+ PRINT();
+
+ if( nFmlaSize && (rIn.GetRecLeft() > 0) )
+ {
+ LINESTART();
+ ADDTEXT( "name-definition=" );
+ PRINT();
+ FormulaDump( nFmlaSize, FT_RangeName );
+ }
+ if( nMenuLen )
+ {
+ LINESTART();
+ ADDTEXT( "menu-text=" );
+ AddUNICODEString( t, rIn, false, nMenuLen );
+ PRINT();
+ }
+ if( nDescrLen )
+ {
+ LINESTART();
+ ADDTEXT( "descr-text=" );
+ AddUNICODEString( t, rIn, false, nDescrLen );
+ PRINT();
+ }
+ if( nHelpLen )
+ {
+ LINESTART();
+ ADDTEXT( "help-text=" );
+ AddUNICODEString( t, rIn, false, nHelpLen );
+ PRINT();
+ }
+ if( nStatusLen )
+ {
+ LINESTART();
+ ADDTEXT( "status-text=" );
+ AddUNICODEString( t, rIn, false, nStatusLen );
+ PRINT();
+ }
+ }
+ break;
+ case 0x001D: // SELECTION - list of selections
+ {
+ ADDTEXT( "pane: " ); ADDDEC( 1 );
+ ADDTEXT( " active cell: " );
+ UINT16 nR, nC;
+ rIn >> nR >> nC;
+ lcl_AddRef( t, nC, nR );
+ ADDTEXT( " active index: " ); ADDDEC( 2 );
+ ADDTEXT( " ref count: " );
+ UINT16 nCount;
+ rIn >> nCount;
+ __AddDec( t, nCount );
+ PRINT();
+ for( UINT16 nIndex = 0; nIndex < nCount && rIn.IsValid(); nIndex++ )
+ {
+ LINESTART();
+ UINT16 nR1, nR2;
+ UINT8 nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ ADDTEXT( "ref#" ); __AddDec( t, nIndex, 3 );
+ ADDTEXT( ": " ); lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ PRINT();
+ }
+ }
+ break;
+ case 0x0023: // EXTERNNAME
+ {
+ PreDump( rIn.GetRecSize() );
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "builtin" );
+ ADDFLAG( 0x0002, "automatic" );
+ ADDFLAG( 0x0004, "wantcliprepr" );
+ ADDFLAG( 0x0008, "DDEstddocname" );
+ ADDFLAG( 0x0010, "OLE" );
+ ADDRESERVED( 0x8000 );
+ sal_uInt16 nClip = (__nFlags & 0x7FE0) >> 5;
+ ADDTEXT( " clip-format=" ); __AddHex( t, nClip );
+ PRINT(); LINESTART();
+ bool bFormula = false, bArray = false;
+ if( (__nFlags & 0x0001) || !(__nFlags & 0x7FFE) )
+ {
+ ADDTEXT( "type=external name" );
+ ADDTEXT( " table=" ); ADDDEC( 2 );
+ ADDTEXT( " reserved=" ); ADDHEX( 2 );
+ bFormula = true;
+ }
+ else if( __nFlags & 0x0010 )
+ {
+ ADDTEXT( "type=OLE" );
+ ADDTEXT( " stream-id=" ); ADDHEX( 4 );
+ }
+ else
+ {
+ ADDTEXT( "type=DDE" );
+ ADDTEXT( " reserved=" ); ADDHEX( 4 );
+ bArray = true;
+ }
+ PRINT(); LINESTART();
+ ADDTEXT( "name=" ); AddUNICODEString( t, rIn, FALSE );
+ PRINT();
+ if( rIn.GetRecLeft() > 0 )
+ {
+ LINESTART();
+ if( bFormula )
+ {
+ sal_uInt16 nSize = rIn.ReaduInt16();
+ ADDTEXT( "formula (size=" ); __AddDec( t, nSize );
+ ADDTEXT( "):" );
+ PRINT();
+ FormulaDump( nSize, FT_RangeName );
+ }
+ else if( bArray && (rIn.GetRecLeft() >= 3) )
+ {
+ LINESTART();
+ ADDTEXT( "constant array width=" ); ADDDEC( 1 );
+ ADDTEXT( " height=" ); ADDDEC( 2 );
+ PRINT();
+ while( rIn.GetRecLeft() > 0 )
+ {
+ sal_uInt8 nType = rIn.ReaduInt8();
+ LINESTART();
+ ADDTEXT( "type=" ); __AddHex( t, nType );
+ ADDTEXT( " (" );
+ switch( nType )
+ {
+ case 0x00:
+ ADDTEXT( "empty) reserved=" ); ADDHEX( 4 );
+ ADDTEXT( " " ); ADDHEX( 4 );
+ break;
+ case 0x01:
+ ADDTEXT( "double) value=" ); ADDDOUBLE();
+ break;
+ case 0x02:
+ ADDTEXT( "string) text=" ); AddUNICODEString( t, rIn );
+ break;
+ case 0x04:
+ ADDTEXT( "bool) value=" ); lcl_AddFlag( t, rIn.ReaduInt8() );
+ ADDTEXT( " reserved=" ); ADDHEX( 1 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 4 );
+ break;
+ case 0x10:
+ ADDTEXT( "error) code=" ); ADDHEX( 1 );
+ ADDTEXT( " reserved=" ); ADDHEX( 1 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 4 );
+ break;
+ default:
+ ADDTEXT( "!unknown!)" );
+ rIn.Ignore( 8 );
+ }
+ PRINT();
+ }
+ }
+ if( rIn.GetRecLeft() > 0 )
+ {
+ LINESTART();
+ ADDTEXT( "additional data:" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ }
+ }
+ break;
+ case 0x0026:
+ case 0x0027:
+ case 0x0028:
+ case 0x0029:
+ LINESTART();
+ ADDDOUBLE();
+ PRINT();
+ break;
+ case 0x002F: // FILEPASS
+ {
+ LINESTART();
+ sal_uInt16 nType;
+ rIn >> nType;
+ ADDTEXT( "encrypt-type=" ); __AddHex( t, nType );
+ ADDTEXT( " (" );
+ switch( nType )
+ {
+ case 0x0000:
+ {
+ ADDTEXT( "BIFF2-BIFF7 XOR) key=" );
+ ADDHEX( 2 );
+ ADDTEXT( " hash=" );
+ ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+
+ case 0x0001:
+ {
+ ADDTEXT( "BIFF8 standard/strong)" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved=" ); ADDHEX( 2 );
+ sal_uInt16 nMode;
+ rIn >> nMode;
+ ADDTEXT( " mode=" ); __AddHex( t, nMode );
+ ADDTEXT( " (" );
+ switch( nMode )
+ {
+ case 0x0001:
+ {
+ ADDTEXT( "BIFF8 standard)" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "document-id=..." );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "salt-data=..." );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "salt-hash=..." );
+ PRINT();
+ ContDump( 16 );
+ }
+ break;
+ case 0x0002:
+ {
+ ADDTEXT( "BIFF8X strong) flags=" );
+ ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "info-size=" ); ADDHEX( 4 );
+ ADDTEXT( " flags=" ); ADDHEX( 4 );
+ ADDTEXT( " unknown=" ); ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "stream-crypt-id=" ); ADDHEX( 4 );
+ ADDTEXT( " hash-algo-id=" ); ADDHEX( 4 );
+ ADDTEXT( " hash-key-len=" ); ADDDEC( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "crypt-prov-type=" ); ADDHEX( 4 );
+ ADDTEXT( " unknown=" ); ADDHEX( 4 );
+ ADDTEXT( " unknown=" ); ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "crypt-provider-name='" );
+ sal_uInt16 nChar;
+ do
+ {
+ rIn >> nChar;
+ if( nChar )
+ t += (sal_Char)(((32 <= nChar) && (nChar <=127)) ? nChar : '.');
+ }
+ while( nChar );
+ ADDTEXT( "'" );
+ PRINT();
+ LINESTART();
+ sal_uInt32 nLen;
+ rIn >> nLen;
+ ADDTEXT( "*** document-id *** len=" ); __AddHex( t, nLen );
+ PRINT();
+ ContDump( nLen );
+ LINESTART();
+ ADDTEXT( "*** salt-data *** len=" ); __AddHex( t, nLen );
+ PRINT();
+ ContDump( nLen );
+ LINESTART();
+ rIn >> nLen;
+ ADDTEXT( "*** salt-hash *** len=" ); __AddHex( t, nLen );
+ PRINT();
+ ContDump( nLen );
+ }
+ break;
+ default:
+ {
+ ADDTEXT( "!unknown!)" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ ADDTEXT( "!unknown!)" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ }
+ }
+ break;
+ case 0x0031: // FONT
+ case 0x0231:
+ {
+ LINESTART();
+ ADDTEXT( "(index=" ); __AddDec( t, nFontIndex );
+ ADDTEXT( ") " );
+ nFontIndex++; if( nFontIndex == 4 ) nFontIndex++;
+ ADDTEXT( "height: " ); ADDDEC( 2 );
+ ADDTEXT( "/20pt " );
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0002, "fItalic" );
+ ADDFLAG( 0x0008, "fStrikeout" );
+ ADDFLAG( 0x0010, "fOutline" );
+ ADDFLAG( 0x0020, "fShadow" );
+ ADDRESERVED( 0xFFC5 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "color: " ); ADDDEC( 2 );
+ ADDTEXT( " boldness: " ); ADDDEC( 2 );
+ ADDTEXT( " sub/sup: " ); ADDDEC( 2 );
+ ADDTEXT( " underline: " ); ADDHEX( 1 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "family: " ); ADDDEC( 1 );
+ ADDTEXT( " charset: " ); ADDDEC( 1 );
+// ADDTEXT( " reserved: " ); ADDHEX( 1 );
+ rIn.Ignore( 1 );
+ ADDTEXT( " " );
+ AddUNICODEString( t, rIn, FALSE );
+ PRINT();
+ }
+ break;
+ case 0x003D: // WINDOW1
+ {
+ LINESTART();
+ ADDTEXT( "pos-x=" ); ADDDEC( 2 );
+ ADDTEXT( " pos-y=" ); ADDDEC( 2 );
+ ADDTEXT( " width=" ); ADDDEC( 2 );
+ ADDTEXT( " height=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "hide-window" );
+ ADDFLAG( 0x0002, "min-window" );
+ ADDFLAG( 0x0008, "show-hscroll" );
+ ADDFLAG( 0x0010, "show-vscroll" );
+ ADDFLAG( 0x0020, "show-tabbar" );
+ ADDRESERVED( 0xFFC4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "active-tab=" ); ADDDEC( 2 );
+ ADDTEXT( " first-vis-tab=" ); ADDDEC( 2 );
+ ADDTEXT( " selected-tabs=" ); ADDDEC( 2 );
+ ADDTEXT( " tabbar-width=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x0041: // PANE
+ {
+ LINESTART();
+ ADDTEXT( "vert-split-pos=" ); ADDDEC( 2 );
+ ADDTEXT( " hor-split-pos=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "first-row=" ); ADDDEC( 2 );
+ ADDTEXT( " first-col=" ); ADDDEC( 2 );
+ ADDTEXT( " active-pane=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x0042: // CODEPAGE
+ {
+ LINESTART();
+ sal_uInt16 nCodePage = rIn.ReaduInt16();
+ ADDTEXT( "codepage=" ); __AddHex( t, nCodePage );
+ ADDTEXT( " (" ); __AddDec( t, nCodePage );
+ ADDTEXT( ")" );
+ PRINT();
+ }
+ break;
+ case 0x004D: // PLS
+ {
+ LINESTART();
+ static const sal_Char* const ppcTypes[] = { "Win", "Mac" };
+ sal_uInt16 nType = rIn.ReaduInt16();
+ ADDTEXT( "environment=" );
+ lcl_AddEnum( t, nType, ppcTypes, STATIC_TABLE_SIZE( ppcTypes ) );
+ PRINT();
+ if( nType == 0 )
+ {
+ String aData;
+ sal_uInt32 __nFlags;
+ LINESTART();
+ rIn.SetNulSubstChar( '\0' );
+ aData = rIn.ReadRawUniString( 32, true );
+ ADDTEXT( "device-name='" ); ADDTEXT( GETSTR( aData ) );
+ ADDTEXT( "'" );
+ PRINT(); LINESTART();
+ ADDTEXT( "spec-version=" ); ADDDEC( 2 );
+ ADDTEXT( " driver-version=" ); ADDDEC( 2 );
+ sal_uInt16 nOwnSize, nPrvSize;
+ rIn >> nOwnSize >> nPrvSize;
+ ADDTEXT( " own-size=" ); __AddDec( t, nOwnSize );
+ ADDTEXT( " prv-size=" ); __AddDec( t, nPrvSize );
+ PRINT(); LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x00000001, "orient" );
+ ADDFLAG( 0x00000002, "paper-size" );
+ ADDFLAG( 0x00000004, "paper-height" );
+ ADDFLAG( 0x00000008, "paper-width" );
+ ADDFLAG( 0x00000010, "scale" );
+ ADDFLAG( 0x00000100, "copies" );
+ ADDRESERVED( 0xE0000080 );
+ PRINT(); LINESTART();
+ static const sal_Char* const ppcOrient[] = { 0, "portrait", "landsc" };
+ sal_uInt16 nOrient = rIn.ReaduInt16();
+ ADDTEXT( "orientation=" );
+ lcl_AddEnum( t, nOrient, ppcOrient, STATIC_TABLE_SIZE( ppcOrient ) );
+ ADDTEXT( " paper-size=" ); ADDDEC( 2 );
+ ADDTEXT( " paper-width=" ); ADDDEC( 2 );
+ ADDTEXT( " paper-height=" ); ADDDEC( 2 );
+ PRINT(); LINESTART();
+ ADDTEXT( "scale=" ); ADDDEC( 2 );
+ ADDTEXT( " copies=" ); ADDDEC( 2 );
+ PRINT();
+ if( nOwnSize > 88 )
+ {
+ LINESTART(); ADDTEXT( "additional data:" ); PRINT();
+ ContDump( nOwnSize - 88 );
+ }
+ if( nPrvSize > 0 )
+ {
+ LINESTART(); ADDTEXT( "private data:" ); PRINT();
+ ContDump( nPrvSize );
+ }
+ }
+ if( rIn.GetRecLeft() > 0 )
+ {
+ LINESTART(); ADDTEXT( "unknown data:" ); PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ }
+ break;
+ case 0x51:
+ {
+ UINT16 nR1, nR2;
+ UINT8 nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "workbook: " );
+ AddUNICODEString( t, rIn, TRUE );
+ PRINT();
+ }
+ break;
+ case 0x0052: // DCONNAME
+ {
+ ADDTEXT( "name=" );
+ AddUNICODEString( t, rIn, TRUE );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "sheet=" );
+ AddUNICODEString( t, rIn, TRUE );
+ PRINT();
+ }
+ break;
+ case 0x5B: // FILESHARING
+ {
+ PreDump( nL );
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fReadOnlyRec" );
+ PRINT();
+ }
+ DumpValidPassword( rIn, pPre );
+ }
+ break;
+ case 0x5D:
+ ObjDump( nL );
+ break;
+ case 0x007D: // COLINFO - col range info
+ {
+ LINESTART();
+ ADDTEXT( "col range: " );
+ ADDDEC( 2 );
+ ADDTEXT( "-" );
+ ADDDEC( 2 );
+ ADDTEXT( " width: " );
+ ADDDEC( 2 );
+ ADDTEXT( "/256 charwidth ix to XF: " );
+ ADDDEC( 2 );
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fHidden" );
+ ADDTEXT( " outlnlev=" );
+ __AddDec( t, (UINT16)((__nFlags & 0x0700) >> 8) );
+ ADDFLAG( 0x1000, "fCollapsed" );
+ ADDRESERVED( 0xE8FE );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved: " );
+ ADDHEX( 1 );
+ PRINT();
+ }
+ break;
+ case 0x7E:
+ {
+// LINESTART();
+ ADDCELLHEAD();
+ ADDTEXT( " val = " );
+ __AddRK( t, rIn.ReadInt32() );
+ PRINT();
+ }
+ break;
+ case 0x0080: // GUTS - row & col gutters for outlines
+ {
+ LINESTART();
+ ADDTEXT( "size row gutter: " );
+ __AddDec( t, Read2( rIn ), 5 );
+ ADDTEXT( " | size col gutter: " );
+ __AddDec( t, Read2( rIn ), 5 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "max outline lev: " );
+ __AddDec( t, Read2( rIn ), 5 );
+ ADDTEXT( " | max outline lev: " );
+ __AddDec( t, Read2( rIn ), 5 );
+ PRINT();
+ }
+ break;
+ case 0x0081: // WSBOOL - additional workspace info
+ {
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ if( __nFlags & 0x00F1 )
+ {
+ ADDFLAG( 0x0001, "fShowAutoBreaks" );
+ ADDFLAG( 0x0010, "fDialog" );
+ ADDFLAG( 0x0020, "fApplyStyles" );
+ ADDFLAG( 0x0040, "fRowSumsBelow" );
+ ADDFLAG( 0x0080, "fColSumsBelow" );
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & (0xCD00 | 0x320E) )
+ {
+ ADDTEXT( " " );
+ ADDFLAG( 0x0100, "fFitToPage" );
+ ADDFLAG( 0x0400, "fDispRowGuts" );
+ ADDFLAG( 0x0800, "fDispColGuts" );
+ ADDFLAG( 0x4000, "fAee" );
+ ADDFLAG( 0x8000, "fAfe" );
+ ADDRESERVED( 0x320E );
+ PRINT();
+ }
+ if( !__nFlags )
+ PRINT();
+ }
+ break;
+ case 0x008C: // COUNTRY
+ {
+ LINESTART();
+ ADDTEXT( "ui-country=" ); ADDDEC( 2 );
+ ADDTEXT( " doc-country=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x92: // PALETTE
+ {
+ UINT16 nColCnt;
+ rIn >> nColCnt;
+ LINESTART();
+ ADDTEXT( "count: " );
+ __AddDec( t, nColCnt );
+ PRINT();
+ LINESTART();
+ for( UINT16 nCol = 0; nCol < nColCnt; nCol++ )
+ {
+ __AddDec( t, nCol, 2 );
+ ADDTEXT( "=" );
+ ADDHEX( 4 );
+ ADDTEXT( " " );
+ if( (nCol % 5 == 4) || (nCol == nColCnt - 1) )
+ {
+ PRINT();
+ LINESTART();
+ }
+ }
+ }
+ break;
+ case 0x9D: // AUTOFILTERINFO -- count of drop-down arrows
+ {
+ LINESTART();
+ ADDTEXT( "count of drop-down arrows: " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x9E: // AUTOFILTER -- autofilter settings
+ {
+ UINT8 nType;
+ UINT8 nCompare;
+ ByteString sTemp[ 2 ];
+ UINT16 nLen[ 2 ] = { 0, 0 };
+ UINT8 nF;
+ LINESTART();
+ ADDTEXT( "count: " );
+ ADDDEC( 2 );
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0003, "fJoin" );
+ ADDFLAG( 0x0004, "fSimpleEq1" );
+ ADDFLAG( 0x0008, "fSimpleEq2" );
+ ADDFLAG( 0x0010, "fTop10" );
+ ADDFLAG( 0x0020, "fTop" );
+ ADDFLAG( 0x0040, "fPercent" );
+ PRINT();
+ LINESTART();
+ if( __nFlags & 0x0003 )
+ ADDTEXT( "(custom conditions are OR-ed" );
+ else
+ ADDTEXT( "(custom conditions are AND-ed" );
+ if( __nFlags & 0x0010 )
+ {
+ if( __nFlags & 0x0020 )
+ ADDTEXT( "; show top " );
+ else
+ ADDTEXT( "; show bottom " );
+ __AddDec( t, (UINT16)(__nFlags >> 7) );
+ if( __nFlags & 0x0040 )
+ ADDTEXT( " percent" );
+ else
+ ADDTEXT( " items" );
+ }
+ ADDTEXT( ")" );
+ PRINT();
+ for( nF = 0; nF < 2; nF++ )
+ {
+ LINESTART();
+ __AddDec( t, (UINT16)(nF + 1) );
+ ADDTEXT( ". Filter: " );
+ rIn >> nType >> nCompare;
+ switch( nType )
+ {
+ case 0x00: ADDTEXT( "not used " ); break;
+ case 0x02: ADDTEXT( "RK " ); break;
+ case 0x04: ADDTEXT( "double " ); break;
+ case 0x06: ADDTEXT( "string " ); break;
+ case 0x08: ADDTEXT( "bool/err " ); break;
+ case 0x0A: ADDTEXT( "show nothing " ); break;
+ case 0x0C: ADDTEXT( "all blanks " ); break;
+ case 0x0E: ADDTEXT( "all non-blanks " ); break;
+ default:
+ ADDTEXT( "unknown (" );
+ __AddHex( t, nType );
+ ADDTEXT( ") " );
+ }
+ switch( nCompare )
+ {
+ case 0x01: ADDTEXT( "< " ); break;
+ case 0x02: ADDTEXT( "= " ); break;
+ case 0x03: ADDTEXT( "<= " ); break;
+ case 0x04: ADDTEXT( "> " ); break;
+ case 0x05: ADDTEXT( "<> " ); break;
+ case 0x06: ADDTEXT( ">= " ); break;
+ default: if( nCompare ) __AddHex( t, nCompare );
+ }
+ sTemp[ nF ] = t;
+ switch( nType )
+ {
+ case 0x02:
+ __AddRK( sTemp[ nF ], rIn.ReadInt32() );
+ IGNORE( 4 );
+ break;
+ case 0x04:
+ __AddDouble( sTemp[ nF ], Read8( rIn ) );
+ break;
+ case 0x06:
+ IGNORE( 4 );
+ nLen[ nF ] = Read1( rIn );
+ IGNORE( 3 );
+ break;
+ case 0x08:
+ __AddHex( sTemp[ nF ], Read1( rIn ) );
+ sTemp[ nF ] += " ";
+ __AddHex( sTemp[ nF ], Read1( rIn ) );
+ IGNORE( 6 );
+ break;
+ default:
+ IGNORE( 8 );
+ }
+ }
+ for( nF = 0; nF < 2; nF++ )
+ {
+ t = sTemp[ nF ];
+ if( nLen[ nF ] )
+ AddUNICODEString( t, rIn, TRUE, nLen[ nF ] );
+ PRINT();
+ }
+ }
+ break;
+ case 0xA0:
+ {
+ UINT16 nN, nD;
+ rIn >> nN >> nD;
+ LINESTART();
+ ADDTEXT( "Window Zoom Magnification = " );
+ __AddDec( t, nN );
+ ADDTEXT( "/" );
+ __AddDec( t, nD );
+ PRINT();
+ }
+ break;
+ case 0x00A1: // SETUP
+ {
+ LINESTART();
+ ADDTEXT( "paper size: " ); ADDDEC( 2 );
+ ADDTEXT( " scaling: " ); ADDDEC( 2 );
+ ADDTEXT( " start page: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "fit to width: " ); ADDDEC( 2 );
+ ADDTEXT( " fit to height: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fLeftRight" );
+ ADDFLAG( 0x0002, "fPortrait" );
+ ADDFLAG( 0x0004, "fNoPrintSettings" );
+ ADDFLAG( 0x0008, "fMonochrom" );
+ ADDFLAG( 0x0010, "fDraft" );
+ ADDFLAG( 0x0020, "fNotes" );
+ ADDFLAG( 0x0040, "fNoOrientation" );
+ ADDFLAG( 0x0080, "fCustomNumber" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Print res: " ); ADDDEC( 2 );
+ ADDTEXT( " vert print res: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "header margin: " ); ADDDOUBLE();
+ ADDTEXT( " footer margin: " ); ADDDOUBLE();
+ ADDTEXT( " copies: " ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0xAF:
+ {
+ UINT16 nCref;
+ UINT8 nLocked, nHidden, nName, nComment, nNameUser;
+ rIn >> nCref >> nLocked >> nHidden >> nName >> nComment >> nNameUser;
+ LINESTART();
+ ADDTEXT( "Changing Cells = " );
+ __AddDec( t, nCref );
+ if( nLocked )
+ ADDTEXT( " fLocked" );
+ if( nHidden )
+ ADDTEXT( " fHidden" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Name = " );
+ __AddDec( t, nName );
+ ADDTEXT( " Comment = " );
+ __AddDec( t, nComment );
+ ADDTEXT( " Name User = " );
+ __AddDec( t, nNameUser );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ break;
+ case 0xB0: // SXVIEW
+ {
+ UINT16 nColFirst, nColLast, nRowFirst, nRowLast;
+ rIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+ nSXLIIndex = 0; // new pivot table
+ LINESTART();
+ ADDTEXT( "PivotTable: " ); __AddDec( t, nColFirst );
+ ADDTEXT( " / " ); __AddDec( t, nRowFirst );
+ ADDTEXT( " - " ); __AddDec( t, nColLast );
+ ADDTEXT( " / " ); __AddDec( t, nRowLast );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "1st Head: " ); ADDDEC( 2 );
+ rIn >> nRowFirst;
+ ADDTEXT( " First Data: " ); ADDDEC( 2 );
+ ADDTEXT( " / " ); __AddDec( t, nRowFirst );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Cache index: " ); ADDDEC( 2 );
+ ADDTEXT( " reserved: " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "axis 4 data: " ); ADDDEC( 2 );
+ ADDTEXT( " pos 4 Data: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "num of fields: " ); ADDDEC( 2 );
+ rIn >> nSXLISize[0] >> nSXLISize[1];
+ ADDTEXT( " ...row fields: " ); __AddDec( t, nSXLISize[0] );
+ ADDTEXT( " ...col fields: " ); __AddDec( t, nSXLISize[1] );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "num of page fields: " ); ADDDEC( 2 );
+ ADDTEXT( " ...data fields: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "data rows: " ); ADDDEC( 2 );
+ ADDTEXT( " data cols: " ); ADDDEC( 2 );
+ rIn >> __nFlags;
+ PRINT();
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fRowGrand" );
+ ADDFLAG( 0x0002, "fColGrand" );
+ ADDFLAG( 0x0008, "fAutoFormat" );
+ ADDFLAG( 0x0010, "fWidthHeightAuto" );
+ ADDFLAG( 0x0020, "fFontAuto" );
+ ADDFLAG( 0x0040, "fAlignAuto" );
+ ADDFLAG( 0x0080, "fBorderAuto" );
+ ADDFLAG( 0x0100, "fPatternAuto" );
+ ADDFLAG( 0x0200, "fNumberAuto" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "index 2 PivotTable autoform: " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ UINT16 nTableLen = Read2( rIn );
+ UINT16 nDataLen = Read2( rIn );
+ ADDTEXT( "PivotTable name: " );
+ if( nTableLen )
+ AddUNICODEString( t, rIn, TRUE, nTableLen );
+ else
+ ADDTEXT( "-/-" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "data field name: " );
+ if( nDataLen )
+ AddUNICODEString( t, rIn, TRUE, nDataLen );
+ else
+ ADDTEXT( "-/-" );
+ PRINT();
+ }
+ break;
+ case 0xB1: // SXVD
+ {
+ rIn >> __nFlags;
+ LINESTART();
+ ADDTEXT( "Axis (" );
+ __AddHex( t, __nFlags );
+ ADDTEXT( "):" );
+ if( __nFlags )
+ {
+ ADDFLAG( 0x0001, "row" );
+ ADDFLAG( 0x0002, "col" );
+ ADDFLAG( 0x0004, "page" );
+ ADDFLAG( 0x0008, "data" );
+ }
+ else
+ ADDTEXT( " no axis" );
+ ADDTEXT( " num of att. subtotals: " );
+ ADDDEC( 2 );
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ ADDTEXT( "subtotal type(" );
+ __AddHex( t, __nFlags );
+ ADDTEXT( "):" );
+ if( __nFlags )
+ {
+ ADDFLAG( 0x0001, "Default" );
+ ADDFLAG( 0x0002, "Sum" );
+ ADDFLAG( 0x0004, "Counta" );
+ ADDFLAG( 0x0008, "Average" );
+ ADDFLAG( 0x0010, "Max" );
+ ADDFLAG( 0x0020, "Min" );
+ ADDFLAG( 0x0040, "Product" );
+ ADDFLAG( 0x0080, "Count" );
+ ADDFLAG( 0x0100, "Stdev" );
+ ADDFLAG( 0x0200, "Stddevp" );
+ ADDFLAG( 0x0400, "Var" );
+ ADDFLAG( 0x0800, "Varp" );
+ }
+ else
+ ADDTEXT( " none" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "num of items: " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Name: " );
+ UINT16 nLen = Read2( rIn );
+ if( nLen == 0xFFFF )
+ ADDTEXT( "<name in cache>" );
+ else if( nLen )
+ AddUNICODEString( t, rIn, TRUE, nLen );
+ PRINT();
+ }
+ break;
+ case 0xB2: // SXVI
+ {
+ UINT16 nType, nCache;
+ rIn >> nType >> __nFlags >> nCache;
+ LINESTART();
+ switch( nType )
+ {
+ case 0xFE: p = "Page"; break;
+ case 0xFF: p = "Null"; break;
+ case 0x00: p = "Data"; break;
+ case 0x01: p = "Default"; break;
+ case 0x02: p = "SUM"; break;
+ case 0x03: p = "COUNT"; break;
+ case 0x04: p = "AVERAGE"; break;
+ case 0x05: p = "MAX"; break;
+ case 0x06: p = "MIN"; break;
+ case 0x07: p = "PRODUCT"; break;
+ case 0x08: p = "COUNTA"; break;
+ case 0x09: p = "STDEV"; break;
+ case 0x0A: p = "STDEVP"; break;
+ case 0x0B: p = "VAR"; break;
+ case 0x0C: p = "VARP"; break;
+ case 0x0D: p = "Grand total"; break;
+ default: p = pU;
+ }
+ ADDTEXT( "Type (" );
+ __AddHex( t, nType );
+ ADDTEXT( "): " );
+ ADDTEXT( p );
+ ADDTEXT( " iCache: " );
+ __AddDec( t, nCache );
+ PRINT();
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x01, "fHidden" );
+ ADDFLAG( 0x02, "fHideDetail" );
+ ADDFLAG( 0x04, "fFormula" );
+ ADDFLAG( 0x08, "fMissing" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "Name: " );
+ UINT16 nCch = Read2( rIn );
+ if( nCch == 0xFFFF )
+ ADDTEXT( "<name in cache>" );
+ else if( nCch )
+ AddUNICODEString( t, rIn, TRUE, nCch );
+ else
+ ADDTEXT( "<empty string>" );
+ PRINT();
+ }
+ break;
+ case 0xB4: // SXIVD
+ {
+ const UINT16 nBrkNum = 5;
+ UINT16 nBrk = nBrkNum;
+ UINT16 nSize = (UINT16)(nL / 2);
+ LINESTART();
+ for( UINT16 i = 0; i < nSize; i++ )
+ {
+ ADDHEX( 2 );
+ nBrk--;
+ if( nBrk )
+ ADDTEXT( " " );
+ else
+ {
+ PRINT();
+ LINESTART();
+ nBrk = nBrkNum;
+ }
+ }
+ if( nBrk < nBrkNum ) PRINT();
+ }
+ break;
+ case 0xB5: // SXLI - pivot table line item array
+ {
+ UINT16 nIdent;
+ UINT16 nType;
+ UINT16 nMaxInd;
+ const sal_Char* pInd = " ";
+ const sal_Char* pType[] = {
+ "Data", "Default", "SUM", "COUNT","AVERAGE",
+ "MAX", "MIN", "PRODUCT", "COUNTA", "STDEV",
+ "STDEVP", "VAR", "VARP", "Grand total",
+ "Blank line" }; // undocumented
+ while( rIn.GetRecLeft() > 0 )
+ {
+ rIn >> nIdent >> nType >> nMaxInd >> __nFlags;
+ LINESTART();
+ ADDTEXT( "# of ident. items: " );
+ __AddDec( t, nIdent );
+ ADDTEXT( " Type (" );
+ __AddHex( t, nType );
+ ADDTEXT( "): " );
+ if( nType > 0x0E )
+ p = pU;
+ else
+ p = pType[ nType ];
+ ADDTEXT( p );
+ ADDTEXT( " relevant indexes: " );
+ __AddDec( t, nMaxInd );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pInd );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fMultiDataName" );
+ ADDFLAG( 0x0200, "fSub" );
+ ADDFLAG( 0x0400, "fBlock" );
+ ADDFLAG( 0x0800, "fGrand" );
+ ADDFLAG( 0x1000, "fMultiDataOnAxis" );
+ ADDFLAG( 0x2000, "fBlankLine" ); // undocumented
+ ADDFLAG( 0x4000, "fHideDetail" ); // undocumented
+ ADDRESERVED( 0x8000 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pInd );
+ ADDTEXT( "index to data field: " );
+ __AddDec( t, (UINT16) ( (__nFlags & 0x01FE) >> 1 ) );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pInd );
+ ADDTEXT( "array of " );
+ __AddDec( t, nSXLISize[nSXLIIndex] );
+ ADDTEXT( " indexes (^ are ident., * are irrelevant):" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pInd );
+ ADDTEXT( " " );
+ const UINT16 nBrkNum = 5;
+ UINT16 nBrk = nBrkNum;
+ for( UINT16 i = 0; i < nSXLISize[nSXLIIndex]; i++ )
+ {
+ __AddDec( t, Read2( rIn ), 7 );
+ if( i < nIdent )
+ ADDTEXT( "^" );
+ else if( i < nMaxInd )
+ ADDTEXT( " " );
+ else
+ ADDTEXT( "*" );
+ nBrk--;
+ if( !nBrk )
+ {
+ PRINT();
+ LINESTART();
+ ADDTEXT( pInd );
+ ADDTEXT( " " );
+ nBrk = nBrkNum;
+ }
+ }
+ if( nBrk < nBrkNum )
+ PRINT();
+ }
+ nSXLIIndex = 1 - nSXLIIndex;
+ }
+ break;
+ case 0xB6: // SXPI - pivot table page item(s)
+ {
+ UINT16 nArrayCnt = (UINT16)(nL / 6);
+ LINESTART();
+ __AddDec( t, nArrayCnt );
+ ADDTEXT( " page items:" );
+ PRINT();
+ for( UINT16 iArray = 0; iArray < nArrayCnt; iArray++ )
+ {
+ LINESTART();
+ ADDTEXT( "index SXVD: " );
+ __AddDec( t, Read2( rIn ), 3 );
+ ADDTEXT( " index SXVI: " );
+ UINT16 nSXVIInd;
+ rIn >> nSXVIInd;
+ __AddDec( t, nSXVIInd, 5 );
+ if( nSXVIInd == 32765 )
+ ADDTEXT( " (All items) Obj ID: " );
+ else
+ ADDTEXT( " Obj ID: " );
+ ADDHEX( 2 );
+ PRINT();
+ }
+ }
+ break;
+ case 0xBD:
+ {
+ UINT16 nC, nR, nXF;
+ INT32 nRK;
+ UINT16 n = (UINT16)((nL - 4) / 6);
+
+ rIn >> nR >> nC;
+ while( n )
+ {
+ rIn >> nXF >> nRK;
+ LINESTART();
+ __AddCellHead( t, nC, nR, nXF );
+ ADDTEXT( " val = " );
+ __AddRK( t, nRK );
+ PRINT();
+ nC++;
+ n--;
+ }
+ }
+ break;
+ case 0xBE:
+ {
+ LINESTART();
+ ADDCELLHEAD();
+ PRINT();
+ LINESTART();
+ ADDTEXT( "next XFs: " );
+ UINT16 n = (UINT16)((nL - 6) / 2);
+ while( n )
+ {
+ __AddDec( t, Read2( rIn ) );
+ n--;
+ if( n )
+ ADDTEXT( ' ' );
+ }
+ PRINT();
+ }
+ break;
+ case 0x00C5: // SXDI
+ {
+ LINESTART();
+ ADDTEXT( "Field: " );
+ ADDDEC( 2 );
+ UINT16 nFunc = Read2( rIn );
+ ADDTEXT( " aggregation func (" );
+ __AddHex( t, nFunc );
+ ADDTEXT( "): " );
+ const sal_Char* pFunc[] = { "Sum", "Count", "Average", "Max", "Min",
+ "Product", "Count Nums", "StdDev", "StdDevp", "Var",
+ "Varp" };
+ p = (nFunc > 0x0A) ? pU : pFunc[ nFunc ];
+ ADDTEXT( p );
+ ADDTEXT( " display format (" );
+ const sal_Char* pDispl[] = {
+ "Normal", "Difference", "Percentage of", "Percentage difference from", "Running total in",
+ "Percentage of row", "Percentage of column", "Percentage of total", "Index" };
+ UINT16 nDispl = Read2( rIn );
+ __AddHex( t, nDispl );
+ ADDTEXT( "): " );
+ p = (nDispl > 0x08) ? pU : pDispl[ nDispl ];
+ ADDTEXT( p );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "ind. to SXVD: " ); ADDDEC( 2 );
+ ADDTEXT( " ind. to SXVI: " ); ADDDEC( 2 );
+ ADDTEXT( " num format: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "name: " );
+ UINT16 nCch = Read2( rIn );
+ if( nCch == 0xFFFF )
+ ADDTEXT( "<name in cache>" );
+ else if( nCch )
+ AddUNICODEString( t, rIn, TRUE, nCch );
+ else
+ ADDTEXT( "<empty string>" );
+ PRINT();
+ }
+ break;
+ case 0x00C6: // SXDB - cache info
+ {
+ ADDTEXT( "number of recs: " ); ADDDEC( 4 );
+ ADDTEXT( " stream id: " ); ADDHEX( 2 );
+ ADDTEXT( " flags: " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "DB block recs: " ); ADDDEC( 2 );
+ ADDTEXT( " base fields: " ); ADDDEC( 2 );
+ ADDTEXT( " all fields: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved: " ); ADDHEX( 2 );
+ ADDTEXT( " type: " ); ADDHEX( 2 );
+ ADDTEXT( " changed by:" );
+ PRINT();
+ LINESTART();
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ break;
+ case 0x00C7: // SXFIELD - Pivot Field
+ {
+ nItemCnt = 0;
+
+ ADDTEXT( "#" );
+ __AddDec( t, nFieldCnt, 3 );
+ nFieldCnt++;
+ ADDTEXT( " (pivot field): " );
+ if( rIn.GetRecLeft() < 14 )
+ {
+ ADDTEXT( "<break in pivot field start>" );
+ PRINT();
+ }
+ else
+ {
+ PRINT();
+ LINESTART();
+ ADDTEXT( pPre );
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fOrigItems" );
+ ADDFLAG( 0x0002, "fPostponed" );
+ ADDFLAG( 0x0004, "fCalculated" );
+ ADDFLAG( 0x0008, "fGroupChild" );
+ ADDFLAG( 0x0010, "fNumGroup" );
+ ADDFLAG( 0x0200, "fLongIndex" );
+ ADDFLAG( 0x1000, "f1000?" );
+ ADDFLAG( 0x8000, "f8000?" );
+ ADDRESERVED( 0x6000 );
+ ADDTEXT( " data-type=" );
+ __AddHex( t, static_cast< sal_uInt16 >( __nFlags & 0x0DE0 ) );
+ ADDTEXT( "=" );
+ switch( __nFlags & 0x0DE0 )
+ {
+ case 0x0000: ADDTEXT( "spc" ); break;
+ case 0x0480: ADDTEXT( "str" ); break;
+ case 0x0520: ADDTEXT( "int[+dbl]" ); break;
+ case 0x0560: ADDTEXT( "dbl" ); break;
+ case 0x05A0: ADDTEXT( "str+int[+dbl]" ); break;
+ case 0x05E0: ADDTEXT( "str+dbl" ); break;
+ case 0x0900: ADDTEXT( "dat" ); break;
+ case 0x0D00: ADDTEXT( "dat+int/dbl" ); break;
+ case 0x0D80: ADDTEXT( "dat+str[+int/dbl]" ); break;
+ default: ADDTEXT( pU );
+ }
+ PRINT();
+ LINESTART();
+ ADDTEXT( pPre );
+ ADDTEXT( "group-subfield=" ); ADDDEC( 2 );
+ ADDTEXT( " group-basefield=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pPre );
+ ADDTEXT( "item-count=" ); ADDDEC( 2 );
+ ADDTEXT( " group-item-count=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pPre );
+ ADDTEXT( "base-item-count=" ); ADDDEC( 2 );
+ ADDTEXT( " source-item-count=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( pPre );
+ if( rIn.GetRecLeft() < 3 )
+ {
+ ADDTEXT( "<break in pivot field name>" );
+ PRINT();
+ }
+ else
+ {
+ ADDTEXT( "name=" );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ }
+ }
+ break;
+ case 0x00C8: // SXINDEXLIST - indexes to source data
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nTabIndexCnt, 3 );
+ nTabIndexCnt++;
+ ADDTEXT( " (index list):" );
+ for( UINT16 iIndex = 0; iIndex < rIn.GetRecSize(); iIndex++ )
+ {
+ ADDTEXT( " " );
+ ADDHEX( 1 );
+ }
+ PRINT();
+ }
+ break;
+ case 0x00C9: // SXDOUBLE - cache entry: double value
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (double): " );
+ nItemCnt++;
+ ADDTEXT( " " );
+ ADDDOUBLE();
+ PRINT();
+ }
+ break;
+ case 0x00CA: // SXBOOLEAN - cache entry: boolean value
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (boolean): " );
+ nItemCnt++;
+ ADDTEXT( " " );
+ lcl_AddFlag( t, rIn.ReaduInt16() != 0 );
+ PRINT();
+ }
+ break;
+ case 0x00CB: // SXERROR - cache entry: error code
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (error): " );
+ nItemCnt++;
+ ADDTEXT( " " );
+ ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+ case 0x00CC: // SXINTEGER - signed 16bit integer
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (integer): " );
+ nItemCnt++;
+ ADDTEXT( " " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x00CD: // SXSTRING - String
+ {
+ if( bSubStream )
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (string): " );
+ nItemCnt++;
+ }
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ break;
+ case 0x00CE: // SXDATETIME - date & time special format
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (date/time): " );
+ nItemCnt++;
+ UINT8 nDay, nHour, nMin, nSec;
+ UINT16 nYear, nMonth;
+ rIn >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+ if( nDay )
+ {
+ __AddDec( t, nDay );
+ ADDTEXT( "." );
+ __AddDec( t, nMonth );
+ ADDTEXT( "." );
+ __AddDec( t, nYear );
+ ADDTEXT( " " );
+ }
+ __AddDec( t, nHour, 2, '0' );
+ ADDTEXT( ":" );
+ __AddDec( t, nMin, 2, '0' );
+ ADDTEXT( ":" );
+ __AddDec( t, nSec, 2, '0' );
+ PRINT();
+ }
+ break;
+ case 0x00CF: // SXEMPTY - cache entry: empty
+ {
+ ADDTEXT( "#" );
+ __AddDec( t, nItemCnt, 3 );
+ ADDTEXT( " (empty): " );
+ nItemCnt++;
+ PRINT();
+ }
+ break;
+ case 0x00D5: // SXIDSTM - pivot table cache stream id
+ {
+ LINESTART();
+ UINT16 nStrId = Read2( rIn );
+ ADDTEXT( "Stream ID: " );
+ __AddHex( t, nStrId );
+ PRINT();
+ DumpRecordStream( OpenStorage( EXC_STORAGE_PTCACHE ), ScfTools::GetHexStr( nStrId ), EMPTY_STRING );
+ }
+ break;
+ case 0x00D8: // SXNUMGROUP - numerical grouping in pivot cache field
+ {
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAutoMin" );
+ ADDFLAG( 0x0002, "fAutoMax" );
+ ADDTEXT( " data-type=" );
+ switch( (__nFlags & 0x003C) >> 2 )
+ {
+ case 0x0001: ADDTEXT( "seconds" ); break;
+ case 0x0002: ADDTEXT( "minutes" ); break;
+ case 0x0003: ADDTEXT( "hours" ); break;
+ case 0x0004: ADDTEXT( "days" ); break;
+ case 0x0005: ADDTEXT( "months" ); break;
+ case 0x0006: ADDTEXT( "quarters" ); break;
+ case 0x0007: ADDTEXT( "years" ); break;
+ case 0x0008: ADDTEXT( "numeric" ); break;
+ default: ADDTEXT( pU );
+ }
+ (__nFlags &= 0xFFC0) >>= 6;
+ ADDTEXT( " remaining=" ); __AddHex( t, __nFlags );
+ ADDTEXT( "=" ); __AddDec( t, __nFlags );
+ PRINT();
+ }
+ break;
+ case 0xE0:
+ DumpXF( rIn, pPre );
+ break;
+ case 0xE3:
+ {
+ LINESTART();
+ ADDTEXT( "view source (" );
+ UINT16 n = Read2( rIn );
+ __AddHex( t, n );
+ ADDTEXT( "): " );
+ switch( n )
+ {
+ case 0x01: p = "M$ Excel list or database"; break;
+ case 0x02: p = "external data source"; break;
+ case 0x04: p = "multiple consolidation ranges"; break;
+ case 0x08: p = "pivot table"; break;
+ case 0x10: p = "scenario manager summary report"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ PRINT();
+ }
+ break;
+ case 0x00E5: // CELLMERGING
+ {
+ UINT16 nCount, nInd;
+ UINT16 nRow1, nRow2, nCol1, nCol2;
+ rIn >> nCount;
+ LINESTART();
+ ADDTEXT( "Count: " );
+ __AddDec( t, nCount );
+ PRINT();
+ LINESTART();
+ for( nInd = 0; nInd < 3; nInd++ )
+ ADDTEXT( " row - row / col-col | " );
+ PRINT();
+ LINESTART();
+ if( (ULONG)(nCount * 8 + 2) == nL )
+ {
+ for( nInd = 0; nInd < nCount; nInd++ )
+ {
+ rIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ __AddDec( t, nRow1, 5 );
+ ADDTEXT( "-" );
+ __AddDec( t, nRow2, 5 );
+ ADDTEXT( " / " );
+ __AddDec( t, nCol1, 3 );
+ ADDTEXT( "-" );
+ __AddDec( t, nCol2, 3 );
+ ADDTEXT( " | " );
+ if( (nInd % 3 == 2) || (nInd == nCount - 1) )
+ {
+ PRINT();
+ LINESTART();
+ }
+ }
+ }
+ else
+ {
+ LINESTART();
+ ADDTEXT( "<Wrong record length!>" );
+ PRINT();
+ }
+ }
+ break;
+ case 0xEB:
+ case 0xEC:
+ case 0xED:
+ EscherDump( nL, true );
+ break;
+ case 0x00F6: // SXNAME
+ {
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0002, "fNameErr" );
+ ADDRESERVED( 0xFFFD );
+ ADDTEXT( " field=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ sal_Int16 nFunc;
+ rIn >> nFunc;
+ ADDTEXT( "function=" ); __AddHex( t, (INT32)nFunc );
+ static const sal_Char* const ppcFuncs[] = {
+ "none", 0, "sum", "counta", "count", "average", "max", "min",
+ "product", "stdev", "stdevp", "var", "varp" };
+ lcl_AddEnum( t, nFunc, ppcFuncs, STATIC_TABLE_SIZE( ppcFuncs ), 0, -1 );
+ ADDTEXT( " SXPAIR-count=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x00F9: // SXFMLA
+ {
+ LINESTART();
+ sal_uInt16 nSize;
+ rIn >> nSize;
+ ADDTEXT( "formula-size=" ); __AddDec( t, nSize );
+ ADDTEXT( " SXNAME-count=" ); ADDDEC( 2 );
+ PRINT();
+ FormulaDump( nSize, FT_RangeName );
+ }
+ break;
+ case 0xFC:
+ {
+ UINT16 nCnt = 0;
+ BOOL bOK = TRUE;
+ ContDump( 8 );
+
+ while( bOK && (rIn.GetRecLeft() > 0) )
+ {
+ LINESTART();
+ __AddDec( t, nCnt );
+ ADDTEXT( ": " );
+ bOK = AddUNICODEString( t, rIn );
+ PRINT();
+ nCnt++;
+ }
+ }
+ break;
+ case 0xFD:
+ {
+ LINESTART();
+ ADDCELLHEAD();
+ ADDTEXT( " sst = " );
+ ADDDEC(4);
+ PRINT();
+ }
+ break;
+ case 0x0100: // SXVDEX
+ {
+ LINESTART();
+ sal_uInt32 __nFlags = Read4( rIn );
+ STARTFLAG();
+ if( __nFlags & 0x0000009F )
+ {
+ ADDFLAG( 0x00000001, "fShowAllItems" );
+ ADDFLAG( 0x00000002, "fDragToRow" );
+ ADDFLAG( 0x00000004, "fDragToColumn" );
+ ADDFLAG( 0x00000008, "fDragToPage" );
+ ADDFLAG( 0x00000010, "fDragToHide" );
+ ADDFLAG( 0x00000080, "fServerBased" );
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & 0x00007E00 )
+ {
+ ADDTEXT( " " );
+ ADDFLAG( 0x00000200, "fAutoSort" );
+ ADDFLAG( 0x00000400, "fAscendSort" );
+ ADDFLAG( 0x00000800, "fAutoShow" );
+ ADDFLAG( 0x00001000, "fAscendShow" );
+ ADDFLAG( 0x00002000, "fCalculatedField" );
+ ADDFLAG( 0x00004000, "fLONewPage" ); // undocumented
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & 0xFFE00000 )
+ {
+ ADDTEXT( " " ); // Layout flags:
+ ADDFLAG( 0x00200000, "fLOReport" ); // undocumented
+ ADDFLAG( 0x00400000, "fLOBlankLine" ); // undocumented
+ ADDFLAG( 0x00800000, "fLOSubTotalTop" ); // undocumented
+ ADDTEXT( " show-items=" ); __AddDec( t, sal_uInt32( __nFlags >> 24 ) );
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & 0x001F8160 )
+ {
+ ADDTEXT( " !RESERVED!" );
+ PRINT();
+ }
+ if( !__nFlags )
+ PRINT();
+ LINESTART();
+ ADDTEXT( " sort-field=" );
+ ADDDEC( 2 );
+ ADDTEXT( " show-field=" );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "format=" );
+ UINT16 n = Read2( rIn );
+ if( n )
+ __AddDec( t, n );
+ else
+ ADDTEXT( "none" );
+ PRINT();
+ }
+ break;
+ case 0x0122: // SXDBEX - ext. cache info
+ {
+ ADDTEXT( "last changed: " ); ADDDOUBLE();
+ ADDTEXT( " SXFORMULA recs: " ); ADDDEC( 4 );
+ PRINT();
+ }
+ break;
+ case 0x0138: // CHTRINFO - change tracking info
+ {
+ rIn.DisableDecryption();
+ ADDTEXT( "14 bytes of unknown data..." );
+ PRINT();
+ ContDump( 14 );
+ LINESTART();
+ ADDTEXT( "16 bytes unknown identification:" );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "unknown: " ); ADDHEX( 2 );
+ ADDTEXT( " user: " );
+ if( rIn.GetRecLeft() > 3 )
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ __AddDec( t, (UINT16)(rIn.GetRecLeft() - 10) );
+ ADDTEXT( " bytes of unknown data..." );
+ PRINT();
+ ContDump( rIn.GetRecLeft() - 10 );
+ LINESTART();
+ ADDTEXT( "date/time: " ); ADDDEC( 2 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( " " ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( " unknown: " ); ADDHEX( 1 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+ case 0x0137: // CHTRINSERT - change tracking: insert/remove
+ {
+ ADDTEXT( "len: " ); ADDDEC( 4 );
+ ADDTEXT( " index: " ); ADDDEC( 4 );
+ ADDTEXT( " op: " );
+ UINT16 nOp;
+ rIn >> nOp;
+ switch( nOp )
+ {
+ case 0x0000: ADDTEXT( "insert row" ); break;
+ case 0x0001: ADDTEXT( "insert column" ); break;
+ case 0x0002: ADDTEXT( "delete row" ); break;
+ case 0x0003: ADDTEXT( "delete column" ); break;
+ default:
+ __AddHex( t, nOp );
+ ADDTEXT( " *UNKNOWN*" );
+ }
+ ADDTEXT( " accept: " ); ADDHEX( 2 );
+ ADDTEXT( " tab: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ UINT16 __nFlags = Read2( rIn );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAuto" );
+ ADDRESERVED( 0xFFFE );
+ UINT16 nCol1, nRow1, nCol2, nRow2;
+ rIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ ADDTEXT( " range: " ); lcl_AddRangeRef( t, nCol1, nRow1, nCol2, nRow2 );
+ ADDTEXT( " unknown: " ); ADDHEX( 4 );
+ PRINT();
+ }
+ break;
+ case 0x013B: // CHTRCELLCONTENT: change tracking: changed cell
+ {
+ PreDump( nL );
+ ADDTEXT( "len: " ); ADDDEC( 4 );
+ ADDTEXT( " index: " ); ADDDEC( 4 );
+ ADDTEXT( " opcode: " ); ADDHEX( 2 );
+ ADDTEXT( " accept: " ); ADDHEX( 2 );
+ ADDTEXT( " tab: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ UINT16 nChg, nOldType, nNewType;
+ rIn >> nChg;
+ nOldType = (nChg & 0x0038) >> 3;
+ nNewType = nChg & 0x0007;
+ ADDTEXT( "change (" ); __AddHex( t, nChg );
+ ADDTEXT( "): " );
+ switch( nOldType )
+ {
+ case 0x0000: ADDTEXT( "empty->" ); break;
+ case 0x0001: ADDTEXT( "RK->" ); break;
+ case 0x0002: ADDTEXT( "double->" ); break;
+ case 0x0003: ADDTEXT( "string->" ); break;
+ case 0x0004: ADDTEXT( "bool->" ); break;
+ case 0x0005: ADDTEXT( "formula->" ); break;
+ default: ADDTEXT( "*UNKNOWN*->" );
+ }
+ switch( nNewType )
+ {
+ case 0x0000: ADDTEXT( "empty" ); break;
+ case 0x0001: ADDTEXT( "RK" ); break;
+ case 0x0002: ADDTEXT( "double" ); break;
+ case 0x0003: ADDTEXT( "string" ); break;
+ case 0x0004: ADDTEXT( "bool" ); break;
+ case 0x0005: ADDTEXT( "formula" ); break;
+ default: ADDTEXT( "*UNKNOWN*" );
+ }
+ UINT16 nFormatData = (nChg & 0xFF00);
+ if( (nFormatData == 0x1100) || (nFormatData == 0x1300) )
+ ADDTEXT( "; contains add. data" );
+ ADDTEXT( " format: " ); ADDHEX( 2 );
+ UINT16 nCol, nRow;
+ rIn >> nRow >> nCol;
+ ADDTEXT( " address: " ); lcl_AddRef( t, nCol, nRow );
+ PRINT();
+ LINESTART();
+ UINT16 nOldLen;
+ rIn >> nOldLen;
+ ADDTEXT( "old value len: " ); __AddHex( t, nOldLen );
+ if( nOldType == 0x0003 )
+ nOldLen >>= 1;
+ ADDTEXT( " unknown: " ); ADDHEX( 4 );
+ PRINT();
+ UINT16 nCount = 0;
+ switch( nFormatData )
+ {
+ case 0x1100: nCount = 8; break;
+ case 0x1300: nCount = 4; break;
+ }
+ if( nCount )
+ {
+ LINESTART();
+ ADDTEXT( "additional format data:" );
+ for( UINT16 nIndex = 0; nIndex < nCount; nIndex ++ )
+ {
+ ADDTEXT( " " );
+ ADDHEX( 2 );
+ }
+ PRINT();
+ }
+ if( nOldType )
+ {
+ LINESTART();
+ ADDTEXT( "old value: " );
+ switch( nOldType )
+ {
+ case 0x0001:
+ __AddRK( t, rIn.ReadInt32() );
+ PRINT();
+ break;
+ case 0x0002:
+ ADDDOUBLE();
+ PRINT();
+ break;
+ case 0x0003:
+ AddUNICODEString( t, rIn );
+ PRINT();
+ break;
+ case 0x0004:
+ if( Read2( rIn ) )
+ ADDTEXT( "true" );
+ else
+ ADDTEXT( "false" );
+ PRINT();
+ break;
+ case 0x0005:
+ {
+ PRINT();
+ UINT16 nLen;
+ rIn >> nLen;
+ FormulaDump( nLen, FT_CellFormula );
+ IGNORE( 1 );
+ }
+ break;
+ }
+ }
+ if( nNewType )
+ {
+ LINESTART();
+ ADDTEXT( "new value: " );
+ switch( nNewType )
+ {
+ case 0x0001:
+ __AddRK( t, rIn.ReadInt32() );
+ PRINT();
+ break;
+ case 0x0002:
+ ADDDOUBLE();
+ PRINT();
+ break;
+ case 0x0003:
+ AddUNICODEString( t, rIn );
+ PRINT();
+ break;
+ case 0x0004:
+ if( Read2( rIn ) )
+ ADDTEXT( "true" );
+ else
+ ADDTEXT( "false" );
+ PRINT();
+ break;
+ case 0x0005:
+ {
+ PRINT();
+ UINT16 nLen;
+ rIn >> nLen;
+ FormulaDump( nLen, FT_CellFormula );
+ IGNORE( 1 );
+ }
+ break;
+ }
+ }
+ if( rIn.GetRecLeft() > 0 )
+ {
+ LINESTART();
+ ADDTEXT( "*UNKNOWN* data:" );
+ PRINT();
+ PreDump( rIn.GetRecLeft() );
+ }
+ }
+ break;
+ case 0x013D: // TABID
+ {
+ ADDTEXT( "tab ids:" );
+ while( rIn.GetRecLeft() )
+ {
+ ADDTEXT( " " );
+ ADDDEC( 2 );
+ }
+ PRINT();
+ }
+ break;
+ case 0x0140: // CHTRMOVE - change tracking: moved range
+ {
+ ADDTEXT( "len: " ); ADDDEC( 4 );
+ ADDTEXT( " index: " ); ADDDEC( 4 );
+ ADDTEXT( " opcode: " ); ADDHEX( 2 );
+ ADDTEXT( " accept: " ); ADDHEX( 2 );
+ PRINT();
+ UINT16 nTab1, nTab2;
+ UINT16 nCol11, nCol12, nCol21, nCol22;
+ UINT16 nRow11, nRow12, nRow21, nRow22;
+ rIn >> nTab2 >> nRow11 >> nRow12 >> nCol11 >> nCol12 >> nRow21 >> nRow22 >> nCol21 >> nCol22 >> nTab1;
+ LINESTART();
+ ADDTEXT( "move range from: tab=" ); __AddDec( t, nTab1 );
+ ADDTEXT( " " ); lcl_AddRangeRef( t, nCol11, nRow11, nCol12, nRow12 );
+ ADDTEXT( " to: tab=" ); __AddDec( t, nTab2 );
+ ADDTEXT( " " ); lcl_AddRangeRef( t, nCol21, nRow21, nCol22, nRow22 );
+ ADDTEXT( " unknown: " ); ADDHEX( 4 );
+ PRINT();
+ }
+ break;
+ case 0x014D: // CHTRINSERTTAB - change tracking: insert tab
+ {
+ ADDTEXT( "len: " ); ADDDEC( 4 );
+ ADDTEXT( " index: " ); ADDDEC( 4 );
+ ADDTEXT( " opcode: " ); ADDHEX( 2 );
+ ADDTEXT( " accept: " ); ADDHEX( 2 );
+ ADDTEXT( " tab: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "unknown: " ); ADDHEX( 4 );
+ ADDTEXT( " table name: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ __AddDec( t, (sal_uInt32)rIn.GetRecLeft() );
+ ADDTEXT( " bytes of unknown data:" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ break;
+ case 0x015F: // LABELRANGES
+ {
+ UINT16 nCnt, nR1, nR2, nC1, nC2;
+ rIn >> nCnt;
+ ADDTEXT( "row headers: " ); __AddDec( t, nCnt );
+ PRINT();
+ while( nCnt-- )
+ {
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ LINESTART();
+ AddRangeRef( t, nR1, nC1 | 0xC000, nR2, nC2 | 0xC000, FALSE );
+ PRINT();
+ }
+ rIn >> nCnt;
+ LINESTART();
+ ADDTEXT( "column headers: " ); __AddDec( t, nCnt );
+ PRINT();
+ while( nCnt-- )
+ {
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ LINESTART();
+ AddRangeRef( t, nR1, nC1 | 0xC000, nR2, nC2 | 0xC000, FALSE );
+ PRINT();
+ }
+ }
+ break;
+ case 0x0193:
+ {
+ ADDTEXT( "unknown: " ); ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "16 bytes unknown identification:" );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "date/time: " ); ADDDEC( 2 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( " " ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( " unknown: " ); ADDHEX( 1 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "user: " );
+ if( rIn.GetRecLeft() > 3 )
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ break;
+ case 0x0194:
+ {
+ rIn.DisableDecryption();
+ ADDTEXT( "unknown: " ); ADDHEX( 4 );
+ ADDTEXT( " date/time: " ); ADDDEC( 2 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( "-" ); ADDDEC( 1 );
+ ADDTEXT( " " ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( ":" ); ADDDEC( 1 );
+ ADDTEXT( " unknown: " ); ADDHEX( 1 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "user: " );
+ if( rIn.GetRecLeft() > 3 )
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ __AddDec( t, (sal_uInt32)rIn.GetRecLeft() );
+ ADDTEXT( " bytes of unknown data:" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ break;
+ case 0x0195:
+ rIn.DisableDecryption();
+ ContDump( nL );
+ break;
+ case 0x0196:
+ {
+ rIn.DisableDecryption();
+ ADDTEXT( "unknown: " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "16 bytes unknown identification:" );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "16 bytes unknown identification:" );
+ PRINT();
+ ContDump( 16 );
+ LINESTART();
+ ADDTEXT( "count of changes: " ); ADDDEC( 2 );
+ ADDTEXT( " " );
+ __AddDec( t, (sal_uInt32)rIn.GetRecLeft() );
+ ADDTEXT( " bytes of unknown data:" );
+ PRINT();
+ ContDump( rIn.GetRecLeft() );
+ }
+ break;
+ case 0x01A9: // USERBVIEW
+ {
+ LINESTART();
+ ADDTEXT( "view id: " ); ADDHEX( 4 );
+ ADDTEXT( " tab id: " ); ADDDEC( 4 );
+ ADDTEXT( " guid: " ); __AddGUID( t, rIn );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "window x: " ); ADDDEC( 4 );
+ ADDTEXT( " y: " ); ADDDEC( 4 );
+ ADDTEXT( " width: " ); ADDDEC( 4 );
+ ADDTEXT( " height: " ); ADDDEC( 4 );
+ ADDTEXT( " ratio: " ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ UINT16 __nFlags = Read2( rIn );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fDsplFormulaBar" );
+ ADDFLAG( 0x0002, "fDsplStatus" );
+ ADDFLAG( 0x0004, "fNoteOff" );
+ ADDFLAG( 0x0008, "fDsplHScroll" );
+ ADDFLAG( 0x0010, "fDsplVScroll" );
+ ADDFLAG( 0x0020, "fBotAdornment" );
+ ADDFLAG( 0x0040, "fZoom" );
+ ADDFLAG( 0x0080, "fShowPlaceHld" );
+ ADDFLAG( 0x0100, "fHideAll" );
+ if( !(__nFlags & 0x0180) )
+ ADDTEXT( " fShowAll" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "flags2: " ); ADDHEX( 2 );
+ ADDTEXT( " merge int: " ); ADDDEC( 2 );
+ ADDTEXT( " reserved: " ); ADDHEX( 2 );
+ PRINT();
+ if( rIn.GetRecLeft() > 3 )
+ {
+ LINESTART();
+ ADDTEXT( "name: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ }
+ break;
+ case 0x01AA: // USERSVIEWBEGIN
+ {
+ LINESTART();
+ ADDTEXT( "guid: " ); __AddGUID( t, rIn );
+ ADDTEXT( " tab id: " ); ADDDEC( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "wscale: " ); ADDDEC( 4 );
+ ADDTEXT( " icolor: " ); ADDDEC( 4 );
+ ADDTEXT( " pane: " ); ADDDEC( 4 );
+ PRINT();
+ LINESTART();
+ UINT32 __nFlags = Read4( rIn );
+ STARTFLAG();
+ if( __nFlags & 0x000000FF )
+ {
+ ADDFLAG( 0x00000001, "fShowPgBrk" );
+ ADDFLAG( 0x00000002, "fDsplForml" );
+ ADDFLAG( 0x00000004, "fDsplGrid" );
+ ADDFLAG( 0x00000008, "fDsplRCHead" );
+ ADDFLAG( 0x00000010, "fDsplGuts" );
+ ADDFLAG( 0x00000020, "fDsplZeros" );
+ ADDFLAG( 0x00000040, "fPrintHorC" );
+ ADDFLAG( 0x00000080, "fPrintVerC" );
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & 0x00007F00 )
+ {
+ ADDTEXT( " " );
+ ADDFLAG( 0x00000100, "fPrintRCHead" );
+ ADDFLAG( 0x00000200, "fPrintGrid" );
+ ADDFLAG( 0x00000400, "fFitToPage" );
+ ADDFLAG( 0x00000800, "fPrintArea" );
+ ADDFLAG( 0x00001000, "fOnePrintArea" );
+ ADDFLAG( 0x00002000, "fFilter" );
+ ADDFLAG( 0x00004000, "fAutoFilter" );
+ PRINT();
+ LINESTART();
+ }
+ if( __nFlags & 0xFFF80000 )
+ {
+ ADDTEXT( " " );
+ ADDFLAG( 0x00020000, "fSplitV" );
+ ADDFLAG( 0x00040000, "fSplitH" );
+ ADDFLAG( 0x00180000, "fHiddenRow" );
+ ADDFLAG( 0x00200000, "fHiddenCol" );
+ ADDFLAG( 0x01000000, "fChartSize" );
+ ADDFLAG( 0x02000000, "fFilterUnique" );
+ ADDFLAG( 0x04000000, "fLayoutView" );
+ ADDRESERVED( 0xF8C18000 );
+ PRINT();
+ LINESTART();
+ }
+ if( !__nFlags )
+ PRINT();
+ ADDTEXT( "visible: " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "pane pos vert: " ); ADDDOUBLE();
+ ADDTEXT( " hor: " ); ADDDOUBLE();
+ ADDTEXT( " 1st vis right: " ); ADDDEC( 2 );
+ ADDTEXT( " bott: " ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x01AB: // USERSVIEWEND
+ {
+ LINESTART();
+ ADDTEXT( "settings are valid: " ); ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+ case 0x01AD: // QSI - web query range
+ {
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fTitles" );
+ ADDFLAG( 0x0002, "fRowNums" );
+ ADDFLAG( 0x0004, "fDisRefr" );
+ ADDFLAG( 0x0080, "fFill" );
+ ADDFLAG( 0x0100, "fAutoFmt" );
+ ADDFLAG( 0x0400, "fDisEdit" );
+ ADDRESERVED( 0xFA78 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "AutoFmt: " ); ADDDEC( 2 );
+ ADDTEXT( " AutoFmtAttr: " ); ADDHEX( 2 );
+ ADDTEXT( " reserved: " ); ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "name: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ break;
+ case 0x01AE:
+ {
+ LINESTART();
+ ADDTEXT( "# of tabs: " );
+ UINT16 nTabs;
+ rIn >> nTabs;
+ __AddDec( t, nTabs );
+ rIn.PushPosition();
+ PRINT();
+ LINESTART();
+ if( nL <= (ULONG)(2 + 2 * nTabs) )
+ {
+ ADDTEXT( "----- shortened record -----" );
+ PRINT();
+
+ rIn.PopPosition();
+ ContDump( nL - 2 );
+ }
+ else
+ {
+ rIn.RejectPosition();
+ ADDTEXT( "file name: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ while( nTabs )
+ {
+ LINESTART();
+ ADDTEXT( " " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ nTabs--;
+ }
+ }
+
+ }
+ break;
+ case 0x01B0: // CONDFMT
+ {
+ LINESTART();
+ ADDTEXT( "cf-count=" ); ADDDEC( 2 );
+ rIn >> __nFlags;
+ ADDTEXT( " " );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "tough-recalc" );
+ ADDRESERVED( 0xFFFE );
+ PRINT();
+ LINESTART();
+ sal_uInt16 nR1, nR2, nC1, nC2, nCount;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2 >> nCount;
+ ADDTEXT( "max-range=" ); lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ ADDTEXT( " range-count=" ); __AddDec( t, nCount );
+ PRINT();
+
+ for( sal_uInt16 nRange = 0; rIn.IsValid() && (nRange < nCount); ++nRange )
+ {
+ if( !(nRange % 4) )
+ {
+ LINESTART();
+ ADDTEXT( pPre );
+ }
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ ByteString aRef;
+ lcl_AddRangeRef( aRef, nC1, nR1, nC2, nR2 );
+ aRef.Expand( 16, ' ' );
+ ADDTEXT( aRef );
+ if( (nRange % 4 == 3) || (nRange + 1 == nCount) )
+ PRINT();
+ }
+ }
+ break;
+ case 0x01B1: // CF - conditional format
+ {
+ sal_uInt8 nType, nOp;
+ sal_uInt16 nSize1, nSize2;
+ sal_uInt32 nFlags;
+ rIn >> nType >> nOp >> nSize1 >> nSize2 >> nFlags;
+ LINESTART();
+ ADDTEXT( "type=" ); __AddHex( t, nType );
+ ADDTEXT( " (" );
+ switch( nType )
+ {
+ case 0x01: ADDTEXT( "compare" ); break;
+ case 0x02: ADDTEXT( "formula" ); break;
+ default: ADDTEXT( "!unknown!" );
+ }
+ ADDTEXT( ") operator=" ); __AddHex( t, nOp );
+ ADDTEXT( " (" );
+ switch( nOp )
+ {
+ case 0x00: ADDTEXT( "none" ); break;
+ case 0x01: ADDTEXT( "between" ); break;
+ case 0x02: ADDTEXT( "not-between" ); break;
+ case 0x03: ADDTEXT( "equal" ); break;
+ case 0x04: ADDTEXT( "not-equal" ); break;
+ case 0x05: ADDTEXT( "greater" ); break;
+ case 0x06: ADDTEXT( "less" ); break;
+ case 0x07: ADDTEXT( "greater-eq" ); break;
+ case 0x08: ADDTEXT( "less-eq" ); break;
+ default: ADDTEXT( "!unknown!" );
+ }
+ ADDTEXT( ")" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "formula-size-1=" ); __AddDec( t, nSize1 );
+ ADDTEXT( " formula-size-2=" ); __AddDec( t, nSize2 );
+ PRINT();
+ LINESTART();
+ sal_uInt32 __nFlags = nFlags;
+ STARTFLAG();
+ __nFlags = ~__nFlags;
+ ADDFLAG( 0x00000400, "bord-lft" );
+ ADDFLAG( 0x00000800, "bord-rgt" );
+ ADDFLAG( 0x00001000, "bord-top" );
+ ADDFLAG( 0x00002000, "bord-bot" );
+ ADDFLAG( 0x00010000, "patt-style" );
+ ADDFLAG( 0x00020000, "patt-fgcol" );
+ ADDFLAG( 0x00040000, "patt-bgcol" );
+ __nFlags = ~__nFlags;
+ ADDFLAG( 0x04000000, "font" );
+ ADDFLAG( 0x10000000, "bord" );
+ ADDFLAG( 0x20000000, "patt" );
+ ADDRESERVED( 0xCBC00000 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "unknown=" ); ADDHEX( 2 );
+ PRINT();
+ if( nFlags & 0x04000000 )
+ {
+ LINESTART(); ADDTEXT( "*** FONT ***" ); PRINT();
+ ContDump( 64 );
+ LINESTART();
+ ADDTEXT( "height=" ); ADDHEX( 4 );
+ rIn >> __nFlags;
+ ADDTEXT( " style-" );
+ STARTFLAG();
+ ADDFLAG( 0x00000002, "italic" );
+ ADDFLAG( 0x00000080, "strikeout" );
+ ADDRESERVED( 0xFFFFFF7D );
+ ADDTEXT( " weight=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ sal_uInt16 nEsc;
+ rIn >> nEsc;
+ ADDTEXT( "escapement=" ); __AddDec( t, nEsc );
+ ADDTEXT( " (" );
+ switch( nEsc )
+ {
+ case 0x0000: ADDTEXT( "none" ); break;
+ case 0x0001: ADDTEXT( "super" ); break;
+ case 0x0002: ADDTEXT( "sub" ); break;
+ default: ADDTEXT( "!unknown!" );
+ }
+ sal_uInt8 nUnd;
+ rIn >> nUnd;
+ ADDTEXT( ") underline=" ); __AddDec( t, nUnd );
+ ADDTEXT( " (" );
+ switch( nUnd )
+ {
+ case 0x00: ADDTEXT( "none" ); break;
+ case 0x01: ADDTEXT( "single" ); break;
+ case 0x02: ADDTEXT( "double" ); break;
+ default: ADDTEXT( "!unknown!" );
+ }
+ ADDTEXT( ") unknown=" ); ADDHEX( 1 );
+ ADDTEXT( " " ); ADDHEX( 1 );
+ ADDTEXT( " " ); ADDHEX( 1 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "color=" ); ADDHEX( 4 );
+ ADDTEXT( " unknown=" ); ADDHEX( 4 );
+ rIn >> __nFlags;
+ ADDTEXT( " used-" );
+ STARTFLAG();
+ __nFlags = ~__nFlags;
+ ADDFLAG( 0x00000002, "italic" );
+ ADDFLAG( 0x00000080, "strikeout" );
+ __nFlags = ~__nFlags;
+ ADDRESERVED( 0xFFFFFF65 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "escape-def=" ); ADDHEX( 4 );
+ ADDTEXT( " underl-def=" ); ADDHEX( 4 );
+ PRINT();
+ ContDump( 18 );
+ }
+ if( nFlags & 0x10000000 )
+ {
+ LINESTART(); ADDTEXT( "*** BORDER ***" ); PRINT();
+ sal_uInt16 nLine;
+ sal_uInt32 nColor;
+ rIn >> nLine >> nColor;
+ LINESTART();
+ ADDTEXT( "line-style=" ); __AddHex( t, nLine );
+ ADDTEXT( " (lft=" ); __AddDec( t, (sal_uInt16)(nLine & 0x000F) );
+ ADDTEXT( " rgt=" ); __AddDec( t, (sal_uInt16)((nLine & 0x00F0) >> 4) );
+ ADDTEXT( " top=" ); __AddDec( t, (sal_uInt16)((nLine & 0x0F00) >> 8) );
+ ADDTEXT( " bot=" ); __AddDec( t, (sal_uInt16)((nLine & 0xF000) >> 12) );
+ ADDTEXT( ")" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "line-color=" ); __AddHex( t, nColor );
+ ADDTEXT( " (lft=" ); __AddDec( t, (sal_uInt16)(nColor & 0x0000007F) );
+ ADDTEXT( " rgt=" ); __AddDec( t, (sal_uInt16)((nColor & 0x00003F80) >> 7) );
+ ADDTEXT( " top=" ); __AddDec( t, (sal_uInt16)((nColor & 0x007F0000) >> 16) );
+ ADDTEXT( " bot=" ); __AddDec( t, (sal_uInt16)((nColor & 0x3F800000) >> 23) );
+ ADDTEXT( ") unknown=" ); ADDHEX( 2 );
+ PRINT();
+ }
+ if( nFlags & 0x20000000 )
+ {
+ LINESTART(); ADDTEXT( "*** AREA ***" ); PRINT();
+ sal_uInt16 nPatt, nColor;
+ rIn >> nPatt >> nColor;
+ LINESTART();
+ ADDTEXT( "pattern=" ); __AddHex( t, nPatt );
+ ADDTEXT( " (" ); __AddDec( t, (sal_uInt16)((nPatt & 0xFC00) >> 10) );
+ ADDTEXT( ") color=" ); __AddHex( t, nColor );
+ ADDTEXT( " (fg=" ); __AddDec( t, (sal_uInt16)(nColor & 0x007F) );
+ ADDTEXT( " bg=" ); __AddDec( t, (sal_uInt16)((nColor & 0x3F80) >> 7) );
+ ADDTEXT( ")" );
+ PRINT();
+ }
+ if( rIn.IsValid() && nSize1 && (rIn.GetRecLeft() >= nSize1) )
+ {
+ LINESTART(); ADDTEXT( "*** FORMULA 1 ***" ); PRINT();
+ FormulaDump( nSize1, FT_RangeName );
+ }
+ if( rIn.IsValid() && nSize2 && (rIn.GetRecLeft() >= nSize2) )
+ {
+ LINESTART(); ADDTEXT( "*** FORMULA 2 ***" ); PRINT();
+ FormulaDump( nSize2, FT_RangeName );
+ }
+ }
+ break;
+ case 0x01B2: // DVAL - header of DV recs
+ {
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDTEXT( " (" );
+ __AddPureBin( t, __nFlags );
+ ADDTEXT( ")" );
+ ADDTEXT( "):" );
+ ADDFLAG( 0x0001, "fWnClosed" );
+ ADDFLAG( 0x0002, "fWnPinned" );
+ ADDFLAG( 0x0004, "fCached" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "input window: " );
+ ADDHEX( 4 );
+ ADDTEXT( " / " );
+ ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "object id: " );
+ ADDHEX( 4 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "num of DV recs: " );
+ ADDDEC( 4 );
+ PRINT();
+ }
+ break;
+ case 0x01B6: // TXO - text box
+ {
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ switch( __nFlags & 0x000E )
+ {
+ case 0x0002: ADDTEXT( " h-left" ); break;
+ case 0x0004: ADDTEXT( " h-center" ); break;
+ case 0x0006: ADDTEXT( " h-right" ); break;
+ case 0x0008: ADDTEXT( " h-block" ); break;
+ default: ADDTEXT( " *h-unknown*" );
+ }
+ switch( __nFlags & 0x0070 )
+ {
+ case 0x0010: ADDTEXT( " v-top" ); break;
+ case 0x0020: ADDTEXT( " v-center" ); break;
+ case 0x0030: ADDTEXT( " v-bottom" ); break;
+ case 0x0040: ADDTEXT( " v-block" ); break;
+ default: ADDTEXT( " *v-unknown*" );
+ }
+ ADDFLAG( 0x0200, "lock-text" );
+ ADDRESERVED( 0xFD81 );
+ ADDTEXT( " orient=" );
+ sal_uInt16 nOrient = rIn.ReaduInt16();
+ __AddDec( t, nOrient );
+ ADDTEXT( " (" );
+ switch( nOrient )
+ {
+ case 0: ADDTEXT( "no-rot" ); break;
+ case 1: ADDTEXT( "stacked" ); break;
+ case 2: ADDTEXT( "90\xB0 ccw" ); break;
+ case 3: ADDTEXT( "90\xB0 cw" ); break;
+ default: ADDTEXT( "!unknown!" );
+ }
+ ADDTEXT( ")" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved=" );
+ ADDHEX( 2 ); ADDTEXT( " " ); ADDHEX( 2 ); ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " text-len=" ); ADDDEC( 2 );
+ ADDTEXT( " format-size=" ); ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved=" ); ADDHEX( 2 );
+ sal_uInt16 nLinkSize = rIn.ReaduInt16();
+ ADDTEXT( " link-size=" ); __AddDec( t, nLinkSize );
+ PRINT();
+ if( nLinkSize > 0 )
+ {
+ LINESTART();
+ sal_uInt16 nFmlaSize = rIn.ReaduInt16();
+ ADDTEXT( "fmla-size=" ); __AddDec( t, nFmlaSize );
+ ADDTEXT( " reserved=" ); ADDHEX( 4 );
+ PRINT();
+ FormulaDump( nFmlaSize, FT_CellFormula );
+ }
+ }
+ break;
+ case 0x01BE: // DV - data validation record
+ {
+ UINT32 __nFlags;
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDTEXT( " (" );
+ __AddPureBin( t, __nFlags );
+ ADDTEXT( ")" );
+ PRINT();
+ LINESTART();
+ if( __nFlags )
+ {
+ ADDTEXT( " " );
+ ADDFLAG( 0x00000080, "fStrLookup" );
+ ADDFLAG( 0x00000100, "fAllowBlank" );
+ ADDFLAG( 0x00000200, "fSuppressCombo" );
+ ADDFLAG( 0x00040000, "fShowInputMsg" );
+ ADDFLAG( 0x00080000, "fShowErrorMsg" );
+ }
+ PRINT();
+ LINESTART();
+ ADDTEXT( "error style: " );
+ const char* pErrStyle[] = { "stop", "warning", "info", "4" };
+ ADDTEXT( pErrStyle[ ( __nFlags >> 4 ) & 0x03 ] );
+ PRINT();
+ LINESTART();
+ const char* pValType[] =
+ {
+ "all", "integer", "decimal", "list", "date", "time", "text len", "user",
+ "8", "9", "A", "B", "C", "D", "E", "F"
+ };
+ LINESTART();
+ ADDTEXT( "validation type: " );
+ ADDTEXT( pValType[ __nFlags & 0x0000000F ] );
+ PRINT();
+
+ const char* pOpType[] =
+ {
+ "between", "not between", "equal", "not equal",
+ "greater", "less", "greater or equal", "less or equal",
+ "8", "9", "A", "B", "C", "D", "E", "F"
+ };
+ LINESTART();
+ ADDTEXT( "operator type: " );
+ ADDTEXT( pOpType[ ( __nFlags >> 20 ) & 0x0000000F ] );
+ PRINT();
+
+ LINESTART();
+ ADDTEXT( "Prompt Title: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Error Title: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Prompt Message: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Error Message: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ if( rIn.GetRecLeft() > 8 )
+ {
+ UINT16 nLen;
+ rIn >> nLen;
+ LINESTART();
+ ADDTEXT( "Len1: " );
+ __AddDec( t, nLen );
+ ADDTEXT( " (unknown1: " );
+ ADDHEX( 2 );
+ ADDTEXT( ")" );
+ PRINT();
+ FormulaDump( nLen, FT_RangeName );
+
+ rIn >> nLen;
+ LINESTART();
+ ADDTEXT( "Len2: " );
+ __AddDec( t, nLen );
+ ADDTEXT( " (unknown2: " );
+ ADDHEX( 2 );
+ ADDTEXT( ")" );
+ PRINT();
+ FormulaDump( nLen, FT_RangeName );
+
+ LINESTART();
+ ADDTEXT( "range count: " );
+ ADDHEX( 2 );
+ PRINT();
+ }
+
+ while( rIn.GetRecLeft() >= 8 )
+ {
+ // Row-Row / Col-Col
+ UINT16 nR1, nR2, nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ LINESTART();
+ AddRangeRef( t, nR1, nC1 | 0xC000, nR2, nC2 | 0xC000, FALSE );
+ PRINT();
+ }
+ }
+ break;
+ case 0x01B8: // HLINK
+ {
+ PreDump( nL );
+
+ UINT32 n1, n2;
+ LINESTART();
+ PRINT();
+ UINT16 nR1, nR2, nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ ADDTEXT( "Cellrange=" );
+ lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "GUID StdLink=" ); __AddGUID( t, rIn );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " must=79EAC9D0-BAF9-11CE-8C82-00AA004BA90B" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "unknown=" ); ADDHEX( 4 );
+ PRINT();
+ UINT32 __nFlags = Read4( rIn );
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x00000001, "fBody" );
+ ADDFLAG( 0x00000002, "fAbs" );
+ ADDFLAG( 0x00000014, "fDescr" );
+ ADDFLAG( 0x00000008, "fMark" );
+ ADDFLAG( 0x00000080, "fFrame" );
+ ADDFLAG( 0x00000100, "fUNC" );
+ ADDRESERVED( 0xFFFFFE60 );
+ PRINT();
+
+ //description
+ String aData;
+ if( __nFlags & 0x00000014 )
+ {
+ LINESTART();
+ rIn >> n1;
+ ADDTEXT( "## Description ## [l=" );
+ __AddDec( t, n1 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)(n1 - 1), TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 2 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ }
+
+ // frame name
+ if( __nFlags & 0x00000080 )
+ {
+ LINESTART();
+ rIn >> n1;
+ ADDTEXT( "## Frame ## [l=" );
+ __AddDec( t, n1 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)(n1 - 1), TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 2 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ }
+
+ // network path
+ if( __nFlags & 0x00000100 )
+ {
+ LINESTART();
+ rIn >> n1;
+ ADDTEXT( "## UNC ## [l=" );
+ __AddDec( t, n1 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)(n1 - 1), TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 2 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ }
+
+ // file link or URL
+ else if( __nFlags & 0x00000001 )
+ {
+ rIn.PushPosition();
+ rIn >> n1;
+ rIn.PopPosition();
+ LINESTART();
+ ADDTEXT( "## Content GUID ## " );
+ __AddGUID( t, rIn );
+ switch( n1 )
+ {
+ case 0x00000303: // file
+ {
+ ADDTEXT( " File Moniker" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " must=00000303-0000-0000-C000-000000000046" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "## File link ## up level=" );
+ ADDDEC( 2 );
+ rIn >> n2;
+ ADDTEXT( " [l=" ); __AddDec( t, n2 );
+ ADDTEXT( ", 8-Bit]: '" );
+ aData = rIn.ReadRawByteString( (USHORT)(n2 - 1) );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 1 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ ContDump( 24 );
+ rIn >> n2;
+ LINESTART();
+ ADDTEXT( "bytes left=" ); __AddDec( t, n2 );
+ if( n2 )
+ {
+ rIn >> n2;
+ LINESTART();
+ ADDTEXT( " string byte count=" );
+ __AddDec( t, n2 );
+ ADDTEXT( " unknown=" );
+ ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "[l=" );
+ __AddDec( t, n2 / 2 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)n2, TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "'" );
+ }
+ PRINT();
+ }
+ break;
+ case 0x79EAC9E0: // URL
+ {
+ ADDTEXT( " URL Moniker" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " must=79EAC9E0-BAF9-11CE-8C82-00AA004BA90B" );
+ PRINT();
+ rIn >> n2;
+ LINESTART();
+ ADDTEXT( "## URL ## string byte count=" );
+ __AddDec( t, n2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "[l=" );
+ __AddDec( t, n2 / 2 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)(n2 / 2 - 1), TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 2 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ }
+ break;
+ default:
+ {
+ ADDTEXT( " (!!UNKNOWN!!)" );
+ PRINT();
+ }
+ break;
+ }
+ }
+
+ // text mark
+ if( __nFlags & 0x00000008 )
+ {
+ LINESTART();
+ rIn >> n1;
+ ADDTEXT( "## Text mark ## [l=" );
+ __AddDec( t, n1 );
+ ADDTEXT( "]: '" );
+ aData = rIn.ReadRawUniString( (USHORT)(n1 - 1), TRUE );
+ t += GETSTR( aData );
+ ADDTEXT( "<" ); ADDHEX( 2 ); ADDTEXT( ">'" ); // trailing zero
+ PRINT();
+ }
+ }
+ break;
+ case 0x01BB: // SXFDBTYPE - SQL data type
+ {
+ ADDTEXT( "SQL data type: " ); ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+ case 0x0201:
+ {
+ LINESTART();
+ ADDCELLHEAD();
+ PRINT();
+ }
+ break;
+ case 0x0203:
+ {
+ LINESTART();
+ ADDCELLHEAD();
+ ADDTEXT( " val = " );
+ ADDDOUBLE();
+ PRINT();
+ }
+ break;
+ case 0x0205:
+ {
+ LINESTART();
+ ADDCELLHEAD();
+ ADDTEXT( " val = " ); ADDHEX( 1 );
+ ADDTEXT( " type = " ); ADDDEC( 1 );
+ PRINT();
+ }
+ break;
+ case 0x0208: // ROW - row info
+ {
+ LINESTART();
+ ADDTEXT( "row #: " ); ADDDEC( 2 );
+ ADDTEXT( " def. cols: " ); ADDDEC( 2 );
+ ADDTEXT( "-" ); ADDDEC( 2 );
+ ADDTEXT( " ht: " ); ADDDEC( 2 );
+ ADDTEXT( " reserved: " ); ADDHEX( 4 );
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDTEXT( " outlnlev=" );
+ __AddDec( t, (UINT16)(__nFlags & 0x0007) );
+ ADDFLAG( 0x0010, "fCollapsed" );
+ ADDFLAG( 0x0020, "fRowHeightZero" );
+ ADDFLAG( 0x0040, "fUnsynced" );
+ ADDFLAG( 0x0080, "fGhostDirty" );
+ ADDRESERVED( 0xFF08 );
+ PRINT();
+ UINT16 nXF;
+ rIn >> nXF;
+ LINESTART();
+ ADDTEXT( "ix to XF: " ); __AddDec( t, (UINT16)(nXF & 0x0FFF) );
+ ADDTEXT( " add. flags(" ); __AddHex( t, nXF );
+ ADDTEXT( "):" );
+ ADDFLAG( 0x1000, "fExAsc" );
+ ADDFLAG( 0x2000, "fExDsc" );
+ ADDRESERVED( 0xC000 );
+ PRINT();
+ }
+ break;
+ case 0x0021: // ARRAY
+ case 0x0221:
+ {
+ UINT16 nR1, nR2;
+ UINT8 nC1, nC2;
+ rIn >> nR1 >> nR2 >> nC1 >> nC2 >> __nFlags;
+ LINESTART();
+ ADDTEXT( "range: " );
+ lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ PRINT();
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAlwaysCalc" );
+ ADDFLAG( 0x0002, "fCalcOnLoad" );
+ ADDRESERVED( 0xFFFC );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "chn = " );
+ ADDHEX( 4 );
+ UINT16 n;
+ rIn >> n;
+ ADDTEXT( " cce = " );
+ __AddDec( t, n );
+ PRINT();
+ FormulaDump( n, FT_SharedFormula );
+ }
+ break;
+ case 0x0225: // DEFAULTROWHEIGHT - height & flags
+ {
+ rIn >> __nFlags;
+ LINESTART();
+ ADDTEXT( "default row " );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fUnsynced" );
+ ADDFLAG( 0x0002, "fRowHtZero" );
+ ADDFLAG( 0x0004, "fExAsc" );
+ ADDFLAG( 0x0008, "fExDsc" );
+ ADDRESERVED( 0xFFF0 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "default row height: " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x023E: // WINDOW2
+ {
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "show-formulas" );
+ ADDFLAG( 0x0002, "show-grid" );
+ ADDFLAG( 0x0004, "show-headers" );
+ ADDFLAG( 0x0008, "frozen" );
+ ADDFLAG( 0x0010, "show-zero" );
+ ADDFLAG( 0x0020, "auto-grid-color" );
+ ADDFLAG( 0x0040, "right-to-left" );
+ ADDFLAG( 0x0080, "show-outline" );
+ ADDFLAG( 0x0100, "remove-splits" );
+ ADDFLAG( 0x0200, "sheet-selected" );
+ ADDFLAG( 0x0400, "sheet-visible" );
+ ADDFLAG( 0x0800, "show-pagebreak" );
+ ADDRESERVED( 0xF000 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "first-row=" ); ADDDEC( 2 );
+ ADDTEXT( " first-col=" ); ADDDEC( 2 );
+ ADDTEXT( " grid-color=" ); ADDDEC( 2 );
+ ADDTEXT( " reserved=" ); ADDHEX( 2 );
+ PRINT();
+ // reallife: WINDOW2 in charts do not have teh following fields
+ if( rIn.GetRecLeft() >= 8 )
+ {
+ LINESTART();
+ ADDTEXT( "pagebreak-zoom=" ); ADDDEC( 2 );
+ ADDTEXT( "% view-zoom=" ); ADDDEC( 2 );
+ ADDTEXT( "% reserved=" ); ADDHEX( 4 );
+ PRINT();
+ }
+ }
+ break;
+ case 0x027E:
+ {
+ ADDCELLHEAD();
+ ADDTEXT( " val = " );
+ __AddRK( t, rIn.ReadInt32() );
+ PRINT();
+ }
+ break;
+ case 0x0293: // STYLE
+ {
+ LINESTART();
+ sal_uInt16 nXF;
+ rIn >> nXF;
+ ADDTEXT( "xf-ref=" ); __AddHex( t, nXF );
+ ADDTEXT( " (xf=#" ); __AddDec( t, static_cast< sal_uInt16 >( nXF & EXC_STYLE_XFMASK ) );
+ if( ::get_flag( nXF, EXC_STYLE_BUILTIN ) )
+ {
+ sal_uInt8 nStyleId, nLevel;
+ rIn >> nStyleId >> nLevel;
+ ADDTEXT( " builtin) style-id=" ); __AddDec( t, nStyleId );
+ ADDTEXT( " (" );
+ static const sal_Char* ppcStyles[] = {
+ "Normal", "RowLevel", "ColLevel", "Comma", "Currency",
+ "Percent", "Comma_0", "Currency_0",
+ "Hyperlink", "Followed_Hyperlink" };
+ if( nStyleId < STATIC_TABLE_SIZE( ppcStyles ) )
+ ADDTEXT( ppcStyles[ nStyleId ] );
+ else
+ ADDTEXT( "!unknown!" );
+ ADDTEXT( ") outline-level=" ); __AddDec( t, nLevel );
+ }
+ else
+ {
+ ADDTEXT( ") name=" );
+ AddUNICODEString( t, rIn );
+ }
+ PRINT();
+ }
+ break;
+ case 0x041E:
+ {
+ LINESTART();
+ ADDTEXT( "Index: " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Format: " ); AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ break;
+ case 0x04BC:
+ {
+ UINT16 nR1, nR2;
+ UINT8 nC1, nC2;
+ LINESTART();
+ rIn >> nR1 >> nR2 >> nC1 >> nC2;
+ lcl_AddRangeRef( t, nC1, nR1, nC2, nR2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved = " );
+ __AddPureHex( t, Read2( rIn ) );
+ UINT16 n;
+ rIn >> n;
+ ADDTEXT( " cce = " );
+ __AddDec( t, n );
+ PRINT();
+ FormulaDump( n, FT_SharedFormula );
+ }
+ break;
+ case 0x0803: // WEBQRYSETTINGS - web query: options
+ {
+ UINT16 nCnt;
+ LINESTART();
+ ADDTEXT( "repeated recnum: " );
+ ADDHEX( 2 );
+ ADDTEXT( " unknown:" );
+ for( nCnt = 0; nCnt < 3; nCnt++ )
+ {
+ ADDTEXT( " " );
+ ADDHEX( 2 );
+ }
+ PRINT();
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fImportPRE" );
+ ADDFLAG( 0x0002, "fIgnoreSep" );
+ ADDFLAG( 0x0004, "fUseSetting" );
+ ADDFLAG( 0x0010, "fIgnoreDate" );
+ ADDFLAG( 0x0020, "fWhatIsIt?" );
+ ADDRESERVED( 0xFFC8 );
+ PRINT();
+ LINESTART();
+ rIn >> __nFlags;
+ STARTFLAG();
+ ADDFLAG( 0x0002, "fTables" );
+ ADDRESERVED( 0xFFFD );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "unknown: " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "refresh: " ); ADDDEC( 2 );
+ ADDTEXT( " unknown: " ); ADDHEX( 2 );
+ ADDTEXT( " " ); ADDHEX( 2 );
+ PRINT();
+ }
+ break;
+ case 0x0804: // WEBQRYTABLES - web query: selected tables
+ {
+ LINESTART();
+ ADDTEXT( "repeated recnum: " ); ADDHEX( 2 );
+ ADDTEXT( " unknown: " ); ADDHEX( 2 );
+ PRINT();
+ if( nL > 6 )
+ {
+ LINESTART();
+ ADDTEXT( "text: " );
+ AddUNICODEString( t, rIn );
+ PRINT();
+ }
+ }
+ break;
+ case 0x0809: // BOF
+ {
+ rIn.DisableDecryption();
+ LINESTART();
+ ADDTEXT( "version number: " );
+ ADDHEX( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "substream type: " );
+ rIn >> mnSubstream;
+ __AddHex( t, mnSubstream );
+ ADDTEXT( " (" );
+ switch( mnSubstream )
+ {
+ case 0x0005: p = "Workbook globals"; break;
+ case 0x0006: p = "Visual Basic module"; break;
+ case 0x0010: p = "Worksheet or dialog sheet"; break;
+ case 0x0020: p = "Chart"; break;
+ case 0x0040: p = "MS 4.0 Macro"; break;
+ case 0x0100: p = "Workspace file"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ ADDTEXT( ")" );
+ PRINT();
+ LINESTART();
+ UINT16 n;
+ rIn >> n;
+ ADDTEXT( "build identifier: ");
+ __AddHex( t, n );
+ ADDTEXT( " (=" );
+ __AddDec( t, n );
+ ADDTEXT( ")" );
+ PRINT();
+
+ LINESTART();
+ rIn >> n;
+ ADDTEXT( "build year: ");
+ __AddHex( t, n );
+ ADDTEXT( " (=" );
+ __AddDec( t, n );
+ ADDTEXT( ")" );
+ PRINT();
+
+ UINT32 __nFlags;
+ rIn >> __nFlags;
+ LINESTART();
+ ADDTEXT( "file history " );
+ STARTFLAG();
+ if( __nFlags )
+ {
+ ADDFLAG( 0x00000001, "fWin" );
+ ADDFLAG( 0x00000002, "fRisc" );
+ ADDFLAG( 0x00000004, "fBeta" );
+ ADDFLAG( 0x00000008, "fWinAny" );
+ ADDFLAG( 0x00000010, "fMacAny" );
+ ADDFLAG( 0x00000020, "fBetaAny" );
+ ADDFLAG( 0x00000100, "fRiscAny" );
+ ADDRESERVED( 0xFFFFE0C0 );
+ }
+ PRINT();
+
+ LINESTART();
+ ADDTEXT( "lowest BIFF version: ");
+ ADDHEX( 4 );
+ PRINT();
+ }
+ break;
+ case 0x1002: // ChartChart
+ {
+ LINESTART();
+ ADDTEXT( "Pos = " );
+ ADD16P16();
+ ADDTEXT( " / " );
+ ADD16P16();
+ ADDTEXT( " Size = " );
+ ADD16P16();
+ ADDTEXT( " / " );
+ ADD16P16();
+ PRINT();
+ }
+ break;
+ case 0x1003: // ChartSeries
+ {
+ sal_uInt16 nCatType, nValType, nCatCnt, nValCnt, nBubType, nBubCnt;
+ rIn >> nCatType >> nValType >> nCatCnt >> nValCnt >> nBubType >> nBubCnt;
+ LINESTART();
+ ADDTEXT( "category-type=" ); __AddDec( t, nCatType );
+ ADDTEXT( " " ); ADDTEXT( GetSeriesType( nCatType ) );
+ ADDTEXT( " count=" ); __AddDec( t, nCatCnt );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " value-type=" ); __AddDec( t, nValType );
+ ADDTEXT( " " ); ADDTEXT( GetSeriesType( nValType ) );
+ ADDTEXT( " count=" ); __AddDec( t, nValCnt );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " bubble-type=" ); __AddDec( t, nBubType );
+ ADDTEXT( " " ); ADDTEXT( GetSeriesType( nBubType ) );
+ ADDTEXT( " count=" ); __AddDec( t, nBubCnt );
+ PRINT();
+ }
+ break;
+ case 0x1006: // ChartDataformat
+ {
+ INT16 n;
+ LINESTART();
+ rIn >> n;
+ ADDTEXT( "Point number = " );
+ __AddDec( t, n );
+ if( n == -1 )
+ ADDTEXT( " (entire series)" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "Series index = " );
+ ADDDEC( 2 );
+ ADDTEXT( " Series number = " );
+ ADDDEC( 2 );
+ if( Read2( rIn ) & 0x01 )
+ ADDTEXT( " (fXL4iss)" );
+ PRINT();
+ }
+ break;
+ case 0x1007: // ChartLineform
+ {
+ LINESTART();
+ ADDTEXT( "Color = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ ADDTEXT( " Pattern : " );
+ ADDTEXT( GetLineType( Read2( rIn ) ) );
+ switch( ( INT16 ) Read2( rIn ) )
+ {
+ case -1: p = "hairline"; break;
+ case 0: p = "narrow (single)"; break;
+ case 1: p = "medium (double)"; break;
+ case 2: p = "wide (triple)"; break;
+ default: p = pU;
+ }
+ ADDTEXT( ", " );
+ ADDTEXT( p );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAuto" );
+ ADDFLAG( 0x0004, "fDrawTick" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "color index = " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x1009: // ChartMarkerformat
+ {
+ UINT16 n;
+ LINESTART();
+ ADDTEXT( "Fore = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ ADDTEXT( " Back = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ rIn >> n;
+ switch( n )
+ {
+ case 0: p = "no marker"; break;
+ case 1: p = "square"; break;
+ case 2: p = "diamond"; break;
+ case 3: p = "triangle"; break;
+ case 4: p = "X"; break;
+ case 5: p = "star"; break;
+ case 6: p = "Dow-Jones"; break;
+ case 7: p = "std deviation"; break;
+ case 8: p = "circle"; break;
+ case 9: p = "plus sign"; break;
+ default: p = pU;
+ }
+ ADDTEXT( " Type = " );
+ ADDTEXT( p );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAuto" );
+ ADDFLAG( 0x0010, "fNoBackg" );
+ ADDFLAG( 0x0020, "fNoFore" );
+ ADDRESERVED( 0xFFCE );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "border color = " );
+ ADDDEC( 2 );
+ ADDTEXT( " fill color = " );
+ ADDDEC( 2 );
+ ADDTEXT( " size = " );
+ ADDDEC(4);
+ PRINT();
+ }
+ break;
+ case 0x100A: // ChartAreaformat
+ {
+ LINESTART();
+ ADDTEXT( "Fore = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ ADDTEXT( " Back = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ ADDTEXT( " Pattern = " );
+ UINT16 n;
+ rIn >> n >> __nFlags;
+ __AddDec( t, n );
+ ADDTEXT( " (" );
+ __AddHex( t, n );
+ ADDTEXT( ")" );
+ PRINT();
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x01, "fAuto" );
+ ADDFLAG( 0x02, "fInvertNeg" );
+ PRINT();
+ }
+ }
+ LINESTART();
+ ADDTEXT( "color index fore = " );
+ ADDDEC( 2 );
+ ADDTEXT( ", back = " );
+ ADDDEC( 2 );
+ PRINT();
+ break;
+ case 0x100B: // ChartPieformat
+ LINESTART();
+ ADDDEC( 2 );
+ ADDTEXT( "%" );
+ PRINT();
+ break;
+ case 0x100C: // ChartAttachedlabel
+ ContDump( nL );
+ break;
+ case 0x100D: // ChartSeriestext
+ ContDump( nL );
+ break;
+ case 0x1014: // ChartChartformat
+ {
+ ContDump( 16 );
+ LINESTART();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fVaried" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "drawing order = " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x1015: // ChartLegend
+ {
+ UINT32 nX, nY, nDx, nDy;
+ UINT8 nWType, nWSpacing;
+ rIn >> nX >> nY >> nDx >> nDy >> nWType >> nWSpacing >> __nFlags;
+ LINESTART();
+ __AddDec( t, nX );
+ ADDTEXT( " / " );
+ __AddDec( t, nY );
+ ADDTEXT( " [" );
+ __AddDec( t, nDx );
+ ADDTEXT( " / " );
+ __AddDec( t, nDy );
+ ADDTEXT( "]" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " Type: " );
+ switch( nWType )
+ {
+ case 0: p = "bottom"; break;
+ case 1: p = "corner"; break;
+ case 2: p = "top"; break;
+ case 3: p = "right"; break;
+ case 4: p = "left"; break;
+ case 7: p = "not docked or inside the plot area"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ ADDTEXT( " Spacing: " );
+ switch( nWSpacing )
+ {
+ case 0: p = "close"; break;
+ case 1: p = "medium"; break;
+ case 2: p = "open"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ PRINT();
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x01, "fAutoPosition" );
+ ADDFLAG( 0x02, "fAutoSeries" );
+ ADDFLAG( 0x04, "fAutoPosX" );
+ ADDFLAG( 0x08, "fAutoPosY" );
+ ADDFLAG( 0x10, "fVert" );
+ ADDFLAG( 0x20, "fWasDataTable" );
+ PRINT();
+ }
+ }
+ break;
+ case 0x1016: // ChartSerieslist
+ ContDump( nL );
+ break;
+ case 0x1017: // ChartBar
+ {
+ LINESTART();
+ ADDTEXT( "space betw. bars = " );
+ ADDDEC( 2 );
+ ADDTEXT( " space betw. cat = " );
+ ADDDEC( 2 );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fTranspose" );
+ ADDFLAG( 0x0002, "fStacked" );
+ ADDFLAG( 0x0004, "f100" );
+ ADDFLAG( 0x0008, "fHasShadow" );
+ PRINT();
+ }
+ }
+ break;
+ case 0x1018: // ChartLine
+ ContDump( nL );
+ break;
+ case 0x1019: // ChartPie
+ ContDump( nL );
+ break;
+ case 0x101A: // ChartArea
+ ContDump( nL );
+ break;
+ case 0x101C: // ChartLine
+ ContDump( nL );
+ break;
+ case 0x101D: // ChartAxis
+ {
+ static const sal_Char* const ppcIds[] = { "x-axis", "y-axis", "z-axis" };
+ LINESTART();
+ sal_uInt16 nAxisId = rIn.ReaduInt16();
+ ADDTEXT( "axis-id=" ); __AddDec( t, nAxisId );
+ lcl_AddEnum( t, nAxisId, ppcIds, STATIC_TABLE_SIZE( ppcIds ) );
+ PRINT();
+ ContDump( 16 );
+ }
+ break;
+ case 0x101E: // CHTICK
+ {
+ static const sal_Char* const ppcTickMode[] = { "off", "inside", "outside", "cross" };
+ static const sal_Char* const ppcTickPos[] = { "off", "low", "high", "next-to-axis" };
+ static const sal_Char* const ppcText[] = { "transparent", "opaque" };
+ LINESTART();
+ sal_uInt8 nMajor, nMinor, nPos, nText;
+ rIn >> nMajor >> nMinor >> nPos >> nText;
+ ADDTEXT( "major=" ); __AddDec( t, nMajor );
+ lcl_AddEnum( t, nMajor, ppcTickMode, STATIC_TABLE_SIZE( ppcTickMode ) );
+ ADDTEXT( " minor=" ); __AddDec( t, nMinor );
+ lcl_AddEnum( t, nMinor, ppcTickMode, STATIC_TABLE_SIZE( ppcTickMode ) );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "position=" ); __AddDec( t, nPos );
+ lcl_AddEnum( t, nPos, ppcTickPos, STATIC_TABLE_SIZE( ppcTickPos ) );
+ ADDTEXT( " text-mode=" ); __AddDec( t, nText );
+ lcl_AddEnum( t, nText, ppcText, STATIC_TABLE_SIZE( ppcText ) );
+ ADDTEXT( " text-color=" );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved=" ); ADDHEX( 4 );
+ ADDTEXT( "," ); ADDHEX( 4 );
+ ADDTEXT( "," ); ADDHEX( 4 );
+ ADDTEXT( "," ); ADDHEX( 4 );
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAutoCol" );
+ ADDFLAG( 0x0002, "fAutoBack" );
+ ADDFLAG( 0x0020, "fAutoRot" );
+ ADDRESERVED( 0xFFDC );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "color=" ); ADDDEC( 2 );
+ ADDTEXT( " rotation=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x101F: // CHVALUERANGE
+ {
+ LINESTART();
+ ADDTEXT( "min=" ); ADDDOUBLE();
+ ADDTEXT( " max=" ); ADDDOUBLE();
+ ADDTEXT( " major=" ); ADDDOUBLE();
+ ADDTEXT( " minor=" ); ADDDOUBLE();
+ ADDTEXT( " axis-cross=" ); ADDDOUBLE();
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAutoMin" );
+ ADDFLAG( 0x0002, "fAutoMax" );
+ ADDFLAG( 0x0004, "fAutoMajor" );
+ ADDFLAG( 0x0008, "fAutoMinor" );
+ ADDFLAG( 0x0010, "fAutoCross" );
+ ADDFLAG( 0x0020, "fLogScale" );
+ ADDFLAG( 0x0040, "fReverse" );
+ ADDFLAG( 0x0080, "fMaxCross" );
+ ADDRESERVED( 0xFF00 );
+ PRINT();
+ }
+ break;
+ case 0x1020: // CHEXTRANGE
+ {
+ LINESTART();
+ ADDTEXT( "axis-cross=" ); ADDDEC( 2 );
+ ADDTEXT( " label-freq=" ); ADDDEC( 2 );
+ ADDTEXT( " mark-freq=" ); ADDDEC( 2 );
+ PRINT();
+ rIn >> __nFlags;
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fBetween" );
+ ADDFLAG( 0x0002, "fMaxCross" );
+ ADDFLAG( 0x0004, "fReverse" );
+ ADDRESERVED( 0xFFF8 );
+ PRINT();
+ }
+ break;
+ case 0x1021: // ChartAxislineformat
+ {
+ LINESTART();
+ switch( Read2( rIn ) )
+ {
+ case 0: p = "axis line itself"; break;
+ case 1: p = "major grid line"; break;
+ case 2: p = "minor grid line"; break;
+ case 3: p = "walls or floor"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ PRINT();
+ }
+ break;
+ case 0x1022: // CHARTFORMATLINK
+ ContDump( nL );
+ break;
+ case 0x1024: // ChartDefaulttext
+ ContDump( nL );
+ break;
+ case 0x1025: // ChartText
+ {
+ LINESTART();
+ UINT8 nAt, nVat;
+ UINT16 nBkgMode;
+ INT32 nX, nY, nDx, nDy;
+ UINT16 nGrbit2, nIcvText;
+ INT16 nTrot;
+ rIn >> nAt >> nVat >> nBkgMode;
+ ADDTEXT( "h = " );
+ switch( nAt )
+ {
+ case 1: p = "left"; break;
+ case 2: p = "center"; break;
+ case 3: p = "right"; break;
+ case 4: p = "justify"; break;
+ case 5: p = "distribute"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ ADDTEXT( " v = " );
+ switch( nVat )
+ {
+ case 1: p = "top"; break;
+ case 2: p = "center"; break;
+ case 3: p = "bottom"; break;
+ case 4: p = "justify"; break;
+ case 5: p = "distribute"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ ADDTEXT( " mode = " );
+ if( nBkgMode == 1 )
+ ADDTEXT( "transparent" );
+ else if( nBkgMode == 2 )
+ ADDTEXT( "opaque" );
+ else
+ ADDTEXT( pU );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "color = " );
+ ADDTEXT( GetRGB( Read4( rIn ) ) );
+ rIn >> nX >> nY >> nDx >> nDy >> __nFlags >> nIcvText >> nGrbit2 >> nTrot;
+ ADDTEXT( " pos[size] = " );
+ __AddDec( t, nX );
+ ADDTEXT( " / " );
+ __AddDec( t, nY );
+ ADDTEXT( " [" );
+ __AddDec( t, nDx );
+ ADDTEXT( " / " );
+ __AddDec( t, nDy );
+ ADDTEXT( "]" );
+ PRINT();
+ LINESTART();
+ ADDTEXT( " (pos[size] = " );
+ __AddHex( t, nX );
+ ADDTEXT( " / " );
+ __AddHex( t, nY );
+ ADDTEXT( " [" );
+ __AddHex( t, nDx );
+ ADDTEXT( " / " );
+ __AddHex( t, nDy );
+ ADDTEXT( "])" );
+ PRINT();
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAutoColor" );
+ ADDFLAG( 0x0002, "fShowKey" );
+ ADDFLAG( 0x0004, "fShowValue" );
+ ADDFLAG( 0x0008, "fVert" );
+ ADDFLAG( 0x0010, "fAutoText" );
+ ADDFLAG( 0x0020, "fGenerated" );
+ ADDFLAG( 0x0040, "fDeleted" );
+ ADDFLAG( 0x0080, "fAutoMode" );
+ ADDFLAG( 0x0800, "fShLabPct" );
+ ADDFLAG( 0x1000, "fShowPct" );
+ ADDFLAG( 0x2000, "fShowBubbleSizes" );
+ ADDFLAG( 0x4000, "fShowLabel" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "rot = " );
+ switch( __nFlags & 0x0700 )
+ {
+ case 0x0000: p = "no rotation"; break;
+ case 0x0100: p = "top to bottom, upright"; break;
+ case 0x0200: p = "90 deg counterclockwise"; break;
+ case 0x0300: p = "90 deg clockwise"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ ADDTEXT( " trot = " );
+ __AddDec( t, nTrot );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "text color = " );
+ __AddDec( t, nIcvText );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "placement: " );
+ switch( nGrbit2 & 0x000F )
+ {
+ case 0: p = "0 default"; break;
+ case 1: p = "outside"; break;
+ case 2: p = "inside"; break;
+ case 3: p = "center"; break;
+ case 4: p = "axis"; break;
+ case 5: p = "above"; break;
+ case 6: p = "below"; break;
+ case 7: p = "left"; break;
+ case 8: p = "right"; break;
+ case 9: p = "auto"; break;
+ case 10: p = "moved"; break;
+ default: p = pU;
+ }
+ ADDTEXT( p );
+ PRINT();
+ }
+ break;
+ case 0x1026: // ChartFontx
+ ContDump( nL );
+ break;
+ case 0x1027: // CHOBJECTLINK
+ {
+ static const sal_Char* const ppcObjLink[] = { 0, "title", "y-axis", "x-axis", "data", "legend", "none", "z-axis" };
+ LINESTART();
+ sal_uInt16 nObjLink;
+ rIn >> nObjLink;
+ ADDTEXT( "link=" ); __AddDec( t, nObjLink );
+ lcl_AddEnum( t, nObjLink, ppcObjLink, STATIC_TABLE_SIZE( ppcObjLink ) );
+ ADDTEXT( " series=" ); ADDDEC( 2 );
+ ADDTEXT( " point=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x1032: // ChartFrame
+ {
+ LINESTART();
+ switch( Read2( rIn ) )
+ {
+ case 0: p = "no border"; break;
+ case 1:
+ case 2:
+ case 3: p = "reserved"; break;
+ case 4: p = "with shadow"; break;
+ default: p = pU;
+ }
+ ADDTEXT( "Frame type: " );
+ ADDTEXT( p );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x01, "fAutoSize" );
+ ADDFLAG( 0x02, "fAutoPosition" );
+ PRINT();
+ }
+ }
+ break;
+ case 0x1035: // ChartPlotarea
+ ContDump( nL );
+ break;
+ case 0x103A: // Chart3D
+ ContDump( nL );
+ break;
+ case 0x103C: // ChartPicf
+ LINESTART();
+ ADDTEXT( "bmp-mode=" ); ADDDEC( 2 );
+ ADDTEXT( " format=" ); ADDDEC( 2 );
+ ADDTEXT( " flags=" ); ADDHEX( 2 );
+ ADDTEXT( " scale=" ); ADDDOUBLE();
+ PRINT();
+ break;
+ case 0x103D: // ChartDropbar
+ ContDump( nL );
+ break;
+ case 0x103E: // ChartRadar
+ ContDump( nL );
+ break;
+ case 0x103F: // ChartSurface
+ ContDump( nL );
+ break;
+ case 0x1040: // ChartRadararea
+ ContDump( nL );
+ break;
+ case 0x1041: // ChartAxisparent
+ {
+ LINESTART();
+ switch( Read2( rIn ) )
+ {
+ case 0: p = "main"; break;
+ case 1: p = "secondary"; break;
+ default: p = pU;
+ }
+ ADDTEXT( "Index: " );
+ ADDTEXT( p );
+ ADDTEXT( " " );
+ ADDDEC(4);
+ ADDTEXT( '/' );
+ ADDDEC(4);
+ ADDTEXT( " [" );
+ ADDDEC(4);
+ ADDTEXT( '/' );
+ ADDDEC(4);
+ ADDTEXT( ']' );
+ PRINT();
+ }
+ break;
+ case 0x1043: // ChartLegendxn
+ ContDump( nL );
+ break;
+ case 0x1044: // ChartShtprops
+ ContDump( nL );
+ break;
+ case 0x1045: // ChartSertocrt
+ ContDump( nL );
+ break;
+ case 0x1046: // ChartAxesused
+ {
+ LINESTART();
+ ADDTEXT( "Used : " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x1048: // ChartSbaseref
+ ContDump( nL );
+ break;
+ case 0x104A: // CHSERPARENT
+ LINESTART();
+ ADDTEXT( "parent-index=" ); ADDDEC( 2 );
+ ADDTEXT( " (one-based)" );
+ PRINT();
+ break;
+ case 0x104B: // CHSERTRENDLINE
+ {
+ static const sal_Char* const ppcType[] =
+ { "poynomial", "exponential", "logarithmic", "power", "moving-avg" };
+ sal_uInt8 nType;
+ rIn >> nType;
+ LINESTART();
+ ADDTEXT( "line-type=" ); __AddDec( t, nType );
+ lcl_AddEnum( t, nType, ppcType, STATIC_TABLE_SIZE( ppcType ) );
+ ADDTEXT( " order=" ); ADDDEC( 1 );
+ ADDTEXT( " intercept=" ); ADDDOUBLE();
+ PRINT();
+ LINESTART();
+ ADDTEXT( "show-equation=" ); ADDDEC( 1 );
+ ADDTEXT( " show-r-sqr=" ); ADDDEC( 1 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "forecast-for=" ); ADDDOUBLE();
+ ADDTEXT( " forecast-back=" ); ADDDOUBLE();
+ PRINT();
+ }
+ break;
+ case 0x104E: // ChartIfmt
+ ContDump( nL );
+ break;
+ case 0x104F: // ChartPos
+ {
+ LINESTART();
+ UINT16 nMdTopLt, nMdBotRt;
+ INT32 nX, nY, nDx, nDy;
+ rIn >> nMdTopLt >> nMdBotRt >> nX >> nY >> nDx >> nDy;
+ ADDTEXT( "TopLr = " );
+ __AddDec( t, nMdTopLt );
+ ADDTEXT( " BotRt = " );
+ __AddDec( t, nMdBotRt );
+ PRINT();
+ LINESTART();
+ __AddDec( t, nX );
+ ADDTEXT( " / " );
+ __AddDec( t, nY );
+ ADDTEXT( " [" );
+ __AddDec( t, nDx );
+ ADDTEXT( " / " );
+ __AddDec( t, nDy );
+ ADDTEXT( "]" );
+ PRINT();
+ }
+ break;
+ case 0x1050: // ChartAlruns
+ ContDump( nL );
+ break;
+ case 0x1051: // AI
+ {
+ LINESTART();
+ UINT8 n8 = Read1( rIn );
+ switch( n8 )
+ {
+ case 0: p = "title or text"; break;
+ case 1: p = "values"; break;
+ case 2: p = "categories"; break;
+ case 3: p = "bubble sizes"; break;
+ default: p = pU;
+ }
+ ADDTEXT( "Link index identifier: " );
+ ADDTEXT( p );
+ if ( p == pU )
+ __AddHex( t, n8 );
+ PRINT();
+ LINESTART();
+ switch( Read1( rIn ) )
+ {
+ case 0: p = "default categories"; break;
+ case 1: p = "text or value"; break;
+ case 2: p = "linked to worksheet"; break;
+ case 3: p = "not used (HaHaHa...)"; break;
+ case 4: p = "error reported"; break;
+ default: p = pU;
+ }
+ ADDTEXT( "Refernce type: " );
+ ADDTEXT( p );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x01, "fCustomIfmt" );
+ PRINT();
+ }
+ LINESTART();
+ ADDTEXT( "Numberformat = " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ UINT16 n;
+ rIn >> n;
+ ADDTEXT( "Formula [" );
+ __AddDec( t, n );
+ ADDTEXT( "]: ---------------- " );
+ PRINT();
+ FormulaDump( n, FT_CellFormula );
+ }
+ break;
+ case 0x105B: // CHSERERRORBAR
+ {
+ static const sal_Char* const ppcType[] = { 0, "x-plus", "x-minus", "y-plus", "y-minus" };
+ static const sal_Char* const ppcSource[] = { 0, "percent", "fixed", "std-dev", "custom", "std-error" };
+ static const sal_Char* const ppcLineEnd[] = { "blank", "t-shape" };
+ sal_uInt8 nType, nSource, nLineEnd;
+ rIn >> nType >> nSource >> nLineEnd;
+ LINESTART();
+ ADDTEXT( "bar-type=" ); __AddDec( t, nType );
+ lcl_AddEnum( t, nType, ppcType, STATIC_TABLE_SIZE( ppcType ) );
+ ADDTEXT( " value-source=" ); __AddDec( t, nSource );
+ lcl_AddEnum( t, nSource, ppcSource, STATIC_TABLE_SIZE( ppcSource ) );
+ ADDTEXT( " line-end=" ); __AddDec( t, nLineEnd );
+ lcl_AddEnum( t, nLineEnd, ppcLineEnd, STATIC_TABLE_SIZE( ppcLineEnd ) );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "reserved=" ); ADDHEX( 1 );
+ ADDTEXT( " value=" ); ADDDOUBLE();
+ ADDTEXT( " ref-count=" ); ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x105D: // ChartSerfmt
+ ContDump( nL );
+ break;
+ case 0x105F: // Chart3DDataForm
+ {
+ UINT8 nGround, nTop;
+ nGround = Read1( rIn );
+ nTop = Read1( rIn );
+ UINT16 nStyle = ((UINT16)nGround << 8) | nTop;
+ LINESTART();
+ ADDTEXT( "3D - format (" );
+ __AddHex( t, nGround );
+ ADDTEXT( " " );
+ __AddHex( t, nTop );
+ ADDTEXT( "): " );
+ switch( nStyle )
+ {
+ case 0x0000: ADDTEXT( "bar" ); break;
+ case 0x0001: ADDTEXT( "pyramid" ); break;
+ case 0x0002: ADDTEXT( "pyramid, cut" ); break;
+ case 0x0100: ADDTEXT( "cylinder" ); break;
+ case 0x0101: ADDTEXT( "cone" ); break;
+ case 0x0102: ADDTEXT( "cone, cut" ); break;
+ default: ADDTEXT( pU );
+ }
+ PRINT();
+ }
+ break;
+ case 0x1060: // ChartFbi
+ {
+ LINESTART();
+ ADDTEXT( "dmixBasis = " );
+ ADDDEC( 2 );
+ ADDTEXT( " dmiyBasis = " );
+ ADDDEC( 2 );
+ ADDTEXT( " twpHeightBasis = " );
+ ADDDEC( 2 );
+ ADDTEXT( " scab = " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "ifnt = " );
+ ADDDEC( 2 );
+ PRINT();
+ }
+ break;
+ case 0x1061: // ChartBoppop
+ ContDump( nL );
+ break;
+ case 0x1062: // ChartAxcext
+ {
+ LINESTART();
+ ADDTEXT( "cat on axis: " );
+ ADDDEC( 2 );
+ ADDTEXT( " ... " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "major unit: val = " );
+ ADDDEC( 2 );
+ ADDTEXT( " units = " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "minor unit: val = " );
+ ADDDEC( 2 );
+ ADDTEXT( " units = " );
+ ADDDEC( 2 );
+ PRINT();
+ LINESTART();
+ ADDTEXT( "base unit = " );
+ ADDDEC( 2 );
+ ADDTEXT( " crossing point of val axis = " );
+ ADDDEC( 2 );
+ PRINT();
+ rIn >> __nFlags;
+ if( __nFlags )
+ {
+ LINESTART();
+ STARTFLAG();
+ ADDFLAG( 0x0001, "fAutoMin" );
+ ADDFLAG( 0x0002, "fAutoMax" );
+ ADDFLAG( 0x0004, "fAutoMajor" );
+ ADDFLAG( 0x0008, "fAutoMinor" );
+ ADDFLAG( 0x0010, "fDateAxis" );
+ ADDFLAG( 0x0020, "fAutoBase" );
+ ADDFLAG( 0x0040, "fAutoCross" );
+ ADDFLAG( 0x0080, "fAutoDate" );
+ PRINT();
+ }
+ }
+ break;
+ case 0x1063: // ChartDat
+ ContDump( nL );
+ break;
+ case 0x1064: // ChartPlotgrowth
+ {
+ UINT32 nDx, nDy;
+ rIn >> nDx >> nDy;
+ LINESTART();
+ ADDTEXT( "dxPlotGrowth = " );
+ __Add16p16( t, nDx );
+ ADDTEXT( " (" );
+ __AddHex( t, nDx );
+ ADDTEXT( ") dyPlotGrowth = " );
+ __Add16p16( t, nDy );
+ ADDTEXT( " (" );
+ __AddHex( t, nDy );
+ ADDTEXT( ")" );
+ PRINT();
+ }
+ break;
+ case 0x1065: // ChartSiindex
+ ContDump( nL );
+ break;
+ case 0x1066: // ChartGelframe
+ EscherDump( nL, false );
+ break;
+ case 0x1067: // ChartBoppcustom
+ ContDump( nL );
+ break;
+ default:
+ if( !bEncrypted )
+ ContDump( nL );
+ }
+
+ }
+
+ if( nR == EXC_ID_FILEPASS )
+ {
+ bEncrypted = true;
+ pIn->Seek( EXC_REC_SEEK_TO_BEGIN );
+ bool bValid = (XclImpDecryptHelper::ReadFilepass( *pIn ) == ERRCODE_NONE);
+ LINESTART();
+ ADDTEXT( "decrypter=" ); lcl_AddOnOff( t, bValid );
+ PRINT();
+ bBIFF8 = bBIFF8 && bValid; // dump BIFF8 hex only on invalid decrypter
+ }
+
+ if( bDec )
+ pLevelPre -= nLevelInc;
+}
+
+
+static const sal_Char* GetBlipType( UINT8 n )
+{
+ switch ( n )
+ {
+ case 0 :
+ return " ERROR";
+ break;
+ case 1 :
+ return " UNKNOWN";
+ break;
+ case 2 :
+ return " EMF";
+ break;
+ case 3 :
+ return " WMF";
+ break;
+ case 4 :
+ return " PICT";
+ break;
+ case 5 :
+ return " JPEG";
+ break;
+ case 6 :
+ return " PNG";
+ break;
+ case 7 :
+ return " DIB";
+ break;
+ default:
+ if ( n < 32 )
+ return " NotKnown";
+ else
+ return " Client";
+ }
+}
+
+void Biff8RecDumper::EscherDump( const ULONG nMaxLen, bool bDumpOffset )
+{
+ ULONG n = nMaxLen;
+ UINT16 nPre, nR;
+ UINT32 nL;
+ const sal_Char* p;
+ ByteString aT;
+ UINT16 nDumpSize;
+
+ aT += pLevelPre;
+
+ ULONG nStartPos = pIn->GetSvStreamPos();
+ while( pIn->IsValid() && (n > 0) )
+ {
+ ULONG nCurrPos = pIn->GetSvStreamPos();
+ *pIn >> nPre >> nR >> nL;
+ n -= sizeof( nPre ) + sizeof( nR ) + sizeof( nL );
+
+ switch( nR )
+ {
+ case 0xF000: p = "MsofbtDggContainer"; break;
+ case 0xF006: p = "MsofbtDgg"; break;
+ case 0xF016: p = "MsofbtCLSID"; break;
+ case 0xF00B: p = "MsofbtOPT"; break;
+ case 0xF11A: p = "MsofbtColorMRU"; break;
+ case 0xF11E: p = "MsofbtSplitMenuColors"; break;
+ case 0xF001: p = "MsofbtBstoreContainer"; break;
+ case 0xF007: p = "MsofbtBSE"; break;
+ case 0xF002: p = "MsofbtDgContainer"; break;
+ case 0xF008: p = "MsofbtDg"; break;
+ case 0xF118: p = "MsofbtRegroupItem"; break;
+ case 0xF120: p = "MsofbtColorScheme"; break;
+ case 0xF003: p = "MsofbtSpgrContainer"; break;
+ case 0xF004: p = "MsofbtSpContainer"; break;
+ case 0xF009: p = "MsofbtSpgr"; break;
+ case 0xF00A: p = "MsofbtSp"; break;
+ case 0xF00C: p = "MsofbtTextbox"; break;
+ case 0xF00D: p = "MsofbtClientTextbox"; break;
+ case 0xF00E: p = "MsofbtAnchor"; break;
+ case 0xF00F: p = "MsofbtChildAnchor"; break;
+ case 0xF010: p = "MsofbtClientAnchor"; break;
+ case 0xF011: p = "MsofbtClientData"; break;
+ case 0xF11F: p = "MsofbtOleObject"; break;
+ case 0xF11D: p = "MsofbtDeletedPspl"; break;
+ case 0xF005: p = "MsofbtSolverContainer"; break;
+ case 0xF012: p = "MsofbtConnectorRule"; break;
+ case 0xF013: p = "MsofbtAlignRule"; break;
+ case 0xF014: p = "MsofbtArcRule"; break;
+ case 0xF015: p = "MsofbtClientRule"; break;
+ case 0xF017: p = "MsofbtCalloutRule"; break;
+ case 0xF119: p = "MsofbtSelection"; break;
+ case 0xF122: p = "MsofbtUDefProp"; break;
+ default:
+ if( nR >= 0xF018 && nR <= 0xF117 )
+ p = "MsofbtBLIP";
+ else if ( ( nPre & 0x000F ) == 0x000F )
+ p = "UNKNOWN container";
+ else
+ p = "UNKNOWN ID";
+ }
+
+ aT += " ";
+ __AddHex( aT, nR );
+ ((aT += " ") += p) += " [";
+ __AddHex( aT, nPre );
+ aT += ',';
+ __AddHex( aT, nL );
+ aT += "] instance: ";
+ __AddDec( aT, (UINT16)(nPre >> 4) );
+ if( bDumpOffset )
+ {
+ aT.Append( " pos=" );
+ __AddHex( aT, static_cast< sal_uInt32 >( mnEscherPos + nCurrPos - nStartPos ) );
+ }
+ Print( aT );
+
+ if ( nR == 0xF007 && 36 <= n && 36 <= nL )
+ { // BSE, FBSE
+ ULONG nP = pIn->GetRecPos();
+ UINT8 n8;
+ UINT16 n16;
+ UINT32 n32;
+
+ aT = " btWin32: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ aT += GetBlipType( n8 );
+ aT += " btMacOS: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ aT += GetBlipType( n8 );
+ Print( aT );
+
+ aT = " rgbUid:";
+ Print( aT );
+ ContDump( 16 );
+
+ aT = " tag: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ Print( aT );
+
+ aT = " size: ";
+ *pIn >> n32;
+ __AddHex( aT, n32 );
+ Print( aT );
+
+ aT = " cRef: ";
+ *pIn >> n32;
+ __AddHex( aT, n32 );
+ Print( aT );
+
+ aT = " offs: ";
+ *pIn >> n32;
+ __AddHex( aT, n32 );
+ Print( aT );
+
+ aT = " usage: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ aT += " cbName: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ aT += " unused2: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ aT += " unused3: ";
+ *pIn >> n8;
+ __AddHex( aT, n8 );
+ Print( aT );
+
+ n -= pIn->GetRecPos() - nP;
+ nL = 0; // loop to MsofbtBLIP
+ }
+ else if ( nR == 0xF00F && 0x10 <= n && 0x10 <= nL )
+ { // ChildAnchor
+ ULONG nP = pIn->GetRecPos();
+ sal_Int32 n32;
+
+ aT.Assign( " pos1=" );
+ *pIn >> n32; lclAppendDec( aT, n32 );
+ aT.Append( " pos2=" );
+ *pIn >> n32; lclAppendDec( aT, n32 );
+ aT.Append( " pos3=" );
+ *pIn >> n32; lclAppendDec( aT, n32 );
+ aT.Append( " pos4=" );
+ *pIn >> n32; lclAppendDec( aT, n32 );
+ Print( aT );
+
+ ULONG nC = pIn->GetRecPos() - nP;
+ n -= nC;
+ nL -= nC;
+ }
+ else if ( nR == 0xF010 && 0x12 <= n && 0x12 <= nL )
+ { // ClientAnchor
+ ULONG nP = pIn->GetRecPos();
+ UINT16 n16;
+
+ aT = " Flag: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ if( n16 & 0x0001 ) aT += " -fixedpos";
+ if( n16 & 0x0002 ) aT += " -fixedsize";
+ Print( aT );
+
+ aT = " Col1: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " dX1: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " Row1: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " dY1: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ Print( aT );
+
+ aT = " Col2: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " dX2: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " Row2: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ aT += " dY2: ";
+ *pIn >> n16;
+ __AddHex( aT, n16 );
+ Print( aT );
+
+ ULONG nC = pIn->GetRecPos() - nP;
+ n -= nC;
+ nL -= nC;
+ }
+ else if ( nR == 0xF00A )
+ {
+ sal_uInt32 nId, nFlags;
+ *pIn >> nId >> nFlags;
+ aT.Assign( " shape-id=" );
+ __AddHex( aT, nId );
+ aT.Append( " flags=" );
+ __AddHex( aT, nFlags );
+ Print( aT );
+ nL -= 8; n -= 8;
+ }
+ else if ( nR == 0xF00B || nR == 0xF122 )
+ { // OPT
+ sal_uInt32 nComplex = 0;
+ while ( nL >= 6 + nComplex && n >= 6 + nComplex )
+ {
+ UINT16 n16;
+ UINT32 n32;
+ *pIn >> n16 >> n32;
+ nL -= 6; n -= 6;
+ aT = " ";
+ __AddHex( aT, n16 );
+ aT += " (";
+ __AddDec( aT, n16 & 0x3FFF, 5 );
+ if ( (n16 & 0x8000) == 0 )
+ {
+ if ( n16 & 0x4000 )
+ aT += ", fBlipID";
+ aT += ") ";
+ __AddHex( aT, n32 );
+ if ( (n16 & 0x4000) == 0 )
+ {
+ aT += " (";
+ __AddDec1616( aT, n32 );
+ aT += ')';
+ }
+ Print( aT );
+ }
+ else
+ {
+ aT += ", fComplex) ";
+ __AddHex( aT, n32 );
+ Print( aT );
+ nComplex += n32;
+ }
+ }
+ // complex property data
+ while ( nComplex && n > 0 )
+ {
+ sal_uInt32 nDumpSize = (nComplex > n) ? n : nComplex;
+ ContDump( nDumpSize );
+ nComplex -= nDumpSize;
+ nL -= nDumpSize;
+ n -= nDumpSize;
+ }
+ }
+ else if ( nR == 0xF012 )
+ {
+ aT = " Connector rule: "; __AddDec( aT, pIn->ReaduInt32() );
+ aT += " ShapeID A: "; __AddHex( aT, pIn->ReaduInt32() );
+ aT += " ShapeID B: "; __AddHex( aT, pIn->ReaduInt32() );
+ Print( aT );
+ aT = " ShapeID connector: "; __AddHex( aT, pIn->ReaduInt32() );
+ aT += " Connect pt A: "; __AddHex( aT, pIn->ReaduInt32() );
+ aT += " Connect pt B: "; __AddHex( aT, pIn->ReaduInt32() );
+ Print( aT );
+ nL -= 24; n -= 24;
+ }
+
+ if( ( nPre & 0x000F ) == 0x000F )
+ { // Container
+ if ( nL <= (UINT32) n )
+ Print( " completed within" );
+ else
+ Print( " continued elsewhere" );
+ }
+ else
+ // -> 0x0000 ... 0x0FFF
+ {
+ nDumpSize = ( ( UINT32 ) nL > ( UINT32 ) n )? ( UINT16 ) n : ( UINT16 ) nL;
+
+ if( nDumpSize )
+ {
+ ContDump( nDumpSize );
+ n -= nDumpSize;
+ }
+ }
+
+ aT.Erase();
+ }
+ if( bDumpOffset )
+ mnEscherPos += nMaxLen;
+}
+
+
+void Biff8RecDumper::ObjDump( const ULONG nMaxLen )
+{
+#if 0
+// if an entire hex block is needed
+ pIn->PushPosition();
+ ContDump( nMaxLen );
+ pIn->PopPosition();
+#endif
+
+ ULONG n = nMaxLen;
+ UINT16 nR, nL;
+ const sal_Char* p;
+ ByteString t;
+ XclImpStream& rIn = *pIn;
+ UINT16 nDumpSize;
+ sal_uInt16 nObjFlags = 0;
+
+ t += pLevelPre;
+
+ while( n > 0 )
+ {
+ rIn >> nR >> nL;
+ n -= sizeof( nR ) + sizeof( nL );
+
+ BOOL bDetails = FALSE;
+ switch( nR )
+ {
+ case 0x0000: p = "ftEnd"; break;
+ case 0x0001: p = "(Reserved)"; break;
+ case 0x0002: p = "(Reserved)"; break;
+ case 0x0003: p = "(Reserved)"; break;
+ case 0x0004: p = "ftMacro"; break;
+ case 0x0005: p = "ftButton"; break;
+ case 0x0006: p = "ftGmo"; break;
+ case 0x0007: p = "ftCf"; break;
+ case 0x0008: p = "ftPioGrbit"; bDetails = TRUE; break;
+ case 0x0009: p = "ftPictFmla"; bDetails = TRUE; break;
+ case 0x000A: p = "ftCbls"; break;
+ case 0x000B: p = "ftRbo"; break;
+ case 0x000C: p = "ftSbs"; break;
+ case 0x000D: p = "ftNts"; break;
+ case 0x000E: p = "ftSbsFmla"; break;
+ case 0x000F: p = "ftGboData"; break;
+ case 0x0010: p = "ftEdoData"; break;
+ case 0x0011: p = "ftRboData"; break;
+ case 0x0012: p = "ftCblsData"; break;
+ case 0x0013: p = "ftLbsData"; break;
+ case 0x0014: p = "ftCblsFmla"; break;
+ case 0x0015: p = "ftCmo"; bDetails = TRUE; break;
+ default:
+ p = "UNKNOWN ID";
+ }
+
+ t += " ";
+ __AddHex( t, nR );
+ t += " [";
+ __AddHex( t, nL );
+ (t += "] ") += p;
+ Print( t );
+
+ nDumpSize = ( ( UINT32 ) nL > ( UINT32 ) n )? ( UINT16 ) n : ( UINT16 ) nL;
+
+ if( nDumpSize )
+ {
+ ULONG nPos1 = (bDetails ? rIn.GetRecPos() : 0);
+ ContDump( nDumpSize );
+ n -= nDumpSize;
+ if ( bDetails )
+ {
+ ULONG nPos2 = rIn.GetRecPos();
+ rIn.Seek( nPos1 );
+ t.Erase();
+ switch ( nR )
+ {
+ case 0x0008 : // ftPioGrbit
+ {
+ rIn >> nObjFlags;
+ UINT16 __nFlags = nObjFlags;
+ if ( __nFlags )
+ {
+ ADDTEXT( " " );
+ STARTFLAG();
+ ADDFLAG( 0x0001, "man-size" );
+ ADDFLAG( 0x0002, "linked" );
+ ADDFLAG( 0x0008, "symbol" );
+ ADDFLAG( 0x0010, "control" );
+ ADDFLAG( 0x0020, "ctls-stream" );
+ ADDFLAG( 0x0200, "autoload" );
+ ADDRESERVED( 0xFDC4 );
+ }
+ }
+ break;
+ case 0x0009 : // ftPictFmla
+ {
+ ADDTEXT( " Document type " );
+ UINT16 nFmlaLen;
+ rIn >> nFmlaLen;
+ if( nObjFlags & 0x0002 )
+ {
+ ADDTEXT( "linked\n OLE stream: LNK??? (from EXTERNNAME) " );
+ rIn >> nFmlaLen;
+ ADDTEXT( " unknown=" ); ADDHEX( 4 );
+ PRINT();
+ t.Erase();
+ FormulaDump( nFmlaLen, FT_CellFormula );
+ }
+ else
+ {
+ ADDTEXT( "embedded " );
+ const UINT16 nStringOffset = 14; // MAY be right
+ rIn.Seek( nPos1 + nStringOffset );
+ INT32 nBytesLeft = nL - nStringOffset;
+ UINT16 nStrLen = rIn.ReaduInt16();
+ ULONG nPos3 = rIn.GetRecPos();
+ if( nStrLen )
+ AddUNICODEString( t, rIn, TRUE, nStrLen );
+ nBytesLeft -= (rIn.GetRecPos() - nPos3);
+ ADDTEXT( '\n' );
+ if ( nBytesLeft < 4 )
+ ADDTEXT( " >> ByteString OVERRUN <<\n" );
+
+ rIn.Seek( nPos1 + sizeof(nFmlaLen) + nFmlaLen );
+ if( nObjFlags & 0x0020 )
+ {
+ sal_uInt32 nStrmStart, nStrmLen;
+ rIn >> nStrmStart >> nStrmLen;
+ ADDTEXT( " 'Ctls' stream start=" );
+ __AddHex( t, nStrmStart );
+ ADDTEXT( " size=" );
+ __AddHex( t, nStrmLen );
+ maCtlsPosMap[ nStrmStart ] = nStrmLen;
+ }
+ else
+ {
+ ADDTEXT( " OLE storage name: MBD" );
+ __AddPureHex( t, rIn.ReaduInt32() );
+ }
+ }
+ }
+ break;
+ case 0x0015 : // ftCmo
+ {
+ UINT16 nType, nId;
+ rIn >> nType >> nId;
+ ADDTEXT( " Object ID " );
+ __AddHex( t, nId );
+ switch ( nType )
+ {
+ case 0x0000 : p = "Group"; break;
+ case 0x0001 : p = "Line"; break;
+ case 0x0002 : p = "Rectangle"; break;
+ case 0x0003 : p = "Oval"; break;
+ case 0x0004 : p = "Arc"; break;
+ case 0x0005 : p = "Chart"; break;
+ case 0x0006 : p = "Text"; break;
+ case 0x0007 : p = "Button"; break;
+ case 0x0008 : p = "Picture"; break;
+ case 0x0009 : p = "Polygon"; break;
+ case 0x000a : p = "(Reserved)"; break;
+ case 0x000b : p = "Check box"; break;
+ case 0x000c : p = "Option button";break;
+ case 0x000d : p = "Edit box"; break;
+ case 0x000e : p = "Label"; break;
+ case 0x000f : p = "Dialog box"; break;
+ case 0x0010 : p = "Spinner"; break;
+ case 0x0011 : p = "Scroll bar"; break;
+ case 0x0012 : p = "List box"; break;
+ case 0x0013 : p = "Group box"; break;
+ case 0x0014 : p = "Combo box"; break;
+ case 0x0015 : p = "(Reserved)"; break;
+ case 0x0016 : p = "(Reserved)"; break;
+ case 0x0017 : p = "(Reserved)"; break;
+ case 0x0018 : p = "(Reserved)"; break;
+ case 0x0019 : p = "Comment"; break;
+ case 0x001a : p = "(Reserved)"; break;
+ case 0x001b : p = "(Reserved)"; break;
+ case 0x001c : p = "(Reserved)"; break;
+ case 0x001d : p = "(Reserved)"; break;
+ case 0x001e : p = "Microsoft Office drawing"; break;
+ default:
+ p = "UNKNOWN";
+ }
+ ADDTEXT( ", type " );
+ __AddHex( t, nType );
+ ADDTEXT( ' ' );
+ ADDTEXT( p );
+ }
+ break;
+ }
+ if ( t.Len() )
+ PRINT();
+ rIn.Seek( nPos2 );
+ }
+ }
+
+ t.Erase();
+ }
+}
+
+
+#undef LINESTART
+#undef IGNORE
+#undef ADDHEX
+#undef ADDDEC
+#undef PRINT
+#undef PreDump
+#undef ADDCELLHEAD
+
+void Biff8RecDumper::ContDump( const ULONG nL )
+{
+ UINT32 nC = nMaxBodyLines;
+ UINT32 n = nL;
+ UINT32 nInL, nTmp;
+ UINT8* pB = new UINT8[ nL ];
+ UINT8* p;
+ const UINT16 nLineLen = 16;
+ UINT16 nCharCnt;
+ BOOL bPart;
+ ByteString aT;
+
+ aT += pLevelPre;
+
+ while( n && nC )
+ {
+ bPart = n < nLineLen;
+ nInL = bPart? n : nLineLen;
+ n -= nInL;
+
+ pIn->Read( pB, nInL );
+
+ // als Hex-Codes
+ nTmp = nInL;
+ p = pB;
+ nCharCnt = 0;
+ while( nTmp )
+ {
+ if( nCharCnt == nLineLen / 2 )
+ aT += ' ';
+
+ nCharCnt++;
+
+ aT += ' ';
+ __AddPureHex( aT, *p );
+ p++;
+
+ nTmp--;
+ }
+
+ if( bPart )
+ aT += GetBlanks( ( UINT16 ) ( ( nLineLen - nInL ) * 3 ) );
+
+ // als chars
+
+ aT += " ";
+ if( nInL < 9 )
+ aT += ' ';
+
+ nTmp = nInL;
+ p = pB;
+ nCharCnt = 0;
+ while( nTmp )
+ {
+ if( nCharCnt == nLineLen / 2 )
+ aT += ' ';
+
+ nCharCnt++;
+
+ if( IsPrintable( *p ) )
+ aT += static_cast< sal_Char >( *p );
+ else
+ aT += '.';
+
+ p++;
+
+ nTmp--;
+ }
+
+ Print( aT );
+ aT.Erase();
+ aT += pLevelPre;
+
+ nC--;
+ }
+
+ delete[] pB;
+}
+
+
+// Formula dumper =============================================================
+
+/** Name and parameter count of an Excel function. */
+struct XclDumpFunc
+{
+ const sal_Char* pName; /// Name of the function.
+ sal_uInt16 nParam; /// Parameter count for fixed functions.
+};
+
+static const XclDumpFunc pFuncData[] =
+{
+/* 0*/ { "COUNT", 0 },
+ { "IF", 0 },
+ { "ISNA", 1 },
+ { "ISERROR", 1 },
+ { "SUM", 0 },
+/* 5*/ { "AVERAGE", 0 },
+ { "MIN", 0 },
+ { "MAX", 0 },
+ { "ROW", 0 },
+ { "COLUMN", 0 },
+/* 10*/ { "NA", 0 },
+ { "NPV", 0 },
+ { "STDEV", 0 },
+ { "DOLLAR", 0 },
+ { "FIXED", 0 },
+/* 15*/ { "SIN", 1 },
+ { "COS", 1 },
+ { "TAN", 1 },
+ { "ATAN", 1 },
+ { "PI", 0 },
+/* 20*/ { "SQRT", 1 },
+ { "EXP", 1 },
+ { "LN", 1 },
+ { "LOG10", 1 },
+ { "ABS", 1 },
+/* 25*/ { "INT", 1 },
+ { "SIGN", 1 },
+ { "ROUND", 2 },
+ { "LOOKUP", 0 },
+ { "INDEX", 0 },
+/* 30*/ { "REPT", 2 },
+ { "MID", 3 },
+ { "LEN", 1 },
+ { "VALUE", 1 },
+ { "TRUE", 0 },
+/* 35*/ { "FALSE", 0 },
+ { "AND", 0 },
+ { "OR", 0 },
+ { "NOT", 1 },
+ { "MOD", 2 },
+/* 40*/ { "DCOUNT", 3 },
+ { "DSUM", 3 },
+ { "DAVERAGE", 3 },
+ { "DMIN", 3 },
+ { "DMAX", 3 },
+/* 45*/ { "DSTDEV", 3 },
+ { "VAR", 0 },
+ { "DVAR", 3 },
+ { "TEXT", 2 },
+ { "LINEST", 0 },
+/* 50*/ { "TREND", 0 },
+ { "LOGEST", 0 },
+ { "GROWTH", 0 },
+ { "GOTO" }, // macro/internal
+ { "HALT" }, // macro/internal
+/* 55*/ { "RETURN" }, // macro/internal
+ { "PV", 0 },
+ { "FV", 0 },
+ { "NPER", 0 },
+ { "PMT", 0 },
+/* 60*/ { "RATE", 0 },
+ { "MIRR", 3 },
+ { "IRR", 0 },
+ { "RAND", 0 },
+ { "MATCH", 0 },
+/* 65*/ { "DATE", 3 },
+ { "TIME", 3 },
+ { "DAY", 1 },
+ { "MONTH", 1 },
+ { "YEAR", 1 },
+/* 70*/ { "WEEKDAY", 0 },
+ { "HOUR", 1 },
+ { "MINUTE", 1 },
+ { "SECOND", 1 },
+ { "NOW", 0 },
+/* 75*/ { "AREAS", 1 },
+ { "ROWS", 1 },
+ { "COLUMNS", 1 },
+ { "OFFSET", 0 },
+ { "ABSREF" }, // macro/internal
+/* 80*/ { "RELREF" }, // macro/internal
+ { "ARGUMENT" }, // macro/internal
+ { "SEARCH", 0 },
+ { "TRANSPOSE", 1 },
+ { "ERROR" }, // macro/internal
+/* 85*/ { "STEP" }, // macro/internal
+ { "TYPE", 1 },
+ { "ECHO" }, // macro/internal
+ { "SET.NAME" }, // macro/internal
+ { "CALLER" }, // macro/internal
+/* 90*/ { "DEREF" }, // macro/internal
+ { "WINDOWS" }, // macro/internal
+ { "SERIES" }, // macro/internal
+ { "DOCUMENTS" }, // macro/internal
+ { "ACTIVE.CELL" }, // macro/internal
+/* 95*/ { "SELECTION" }, // macro/internal
+ { "RESULT" }, // macro/internal
+ { "ATAN2", 2 },
+ { "ASIN", 1 },
+ { "ACOS", 1 },
+/*100*/ { "CHOOSE", 0 },
+ { "HLOOKUP", 0 },
+ { "VLOOKUP", 0 },
+ { "LINKS" }, // macro/internal
+ { "INPUT" }, // macro/internal
+/*105*/ { "ISREF", 1 },
+ { "GET.FORMULA" }, // macro/internal
+ { "GET.NAME" }, // macro/internal
+ { "SET.VALUE", 2 }, // macro/internal
+ { "LOG", 0 },
+/*110*/ { "EXEC" }, // macro/internal
+ { "CHAR", 1 },
+ { "LOWER", 1 },
+ { "UPPER", 1 },
+ { "PROPER", 1 },
+/*115*/ { "LEFT", 0 },
+ { "RIGHT", 0 },
+ { "EXACT", 2 },
+ { "TRIM", 1 },
+ { "REPLACE", 4 },
+/*120*/ { "SUBSTITUTE", 0 },
+ { "CODE", 1 },
+ { "NAMES" }, // macro/internal
+ { "DIRECTORY" }, // macro/internal
+ { "FIND", 0 },
+/*125*/ { "CELL", 0 },
+ { "ISERR", 1 },
+ { "ISTEXT", 1 },
+ { "ISNUMBER", 1 },
+ { "ISBLANK", 1 },
+/*130*/ { "T", 1 },
+ { "N", 1 },
+ { "FOPEN" }, // macro/internal
+ { "FCLOSE" }, // macro/internal
+ { "FSIZE" }, // macro/internal
+/*135*/ { "FREADLN" }, // macro/internal
+ { "FREAD" }, // macro/internal
+ { "FWRITELN" }, // macro/internal
+ { "FWRITE" }, // macro/internal
+ { "FPOS" }, // macro/internal
+/*140*/ { "DATEVALUE", 1 },
+ { "TIMEVALUE", 1 },
+ { "SLN", 3 },
+ { "SYD", 4 },
+ { "DDB", 0 },
+/*145*/ { "GET.DEF" }, // macro/internal
+ { "REFTEXT" }, // macro/internal
+ { "TEXTREF" }, // macro/internal
+ { "INDIRECT", 0 },
+ { "REGISTER" }, // macro/internal
+/*150*/ { "CALL" },
+ { "ADD.BAR" }, // macro/internal
+ { "ADD.MENU" }, // macro/internal
+ { "ADD.COMMAND" }, // macro/internal
+ { "ENABLE.COMMAND" }, // macro/internal
+/*155*/ { "CHECK.COMMAND" }, // macro/internal
+ { "RENAME.COMMAND" }, // macro/internal
+ { "SHOW.BAR" }, // macro/internal
+ { "DELETE.MENU" }, // macro/internal
+ { "DELETE.COMMAND" }, // macro/internal
+/*160*/ { "GET.CHART.ITEM" }, // macro/internal
+ { "DIALOG.BOX" }, // macro/internal
+ { "CLEAN", 1 },
+ { "MDETERM", 1 },
+ { "MINVERSE", 1 },
+/*165*/ { "MMULT", 2 },
+ { "FILES" }, // macro/internal
+ { "IPMT", 0 },
+ { "PPMT", 0 },
+ { "COUNTA", 0 },
+/*170*/ { "CANCEL.KEY" }, // macro/internal
+ { "FOR" }, // macro/internal
+ { "WHILE" }, // macro/internal
+ { "BREAK" }, // macro/internal
+ { "NEXT" }, // macro/internal
+/*175*/ { "INITIATE" }, // macro/internal
+ { "REQUEST" }, // macro/internal
+ { "POKE" }, // macro/internal
+ { "EXECUTE" }, // macro/internal
+ { "TERMINATE" }, // macro/internal
+/*180*/ { "RESTART" }, // macro/internal
+ { "HELP" }, // macro/internal
+ { "GET.BAR" }, // macro/internal
+ { "PRODUCT", 0 },
+ { "FACT", 1 },
+/*185*/ { "GET.CELL" }, // macro/internal
+ { "GET.WORKSPACE" }, // macro/internal
+ { "GET.WINDOW" }, // macro/internal
+ { "GET.DOCUMENT" }, // macro/internal
+ { "DPRODUCT", 3 },
+/*190*/ { "ISNONTEXT", 1 },
+ { "GET.NOTE" }, // macro/internal
+ { "NOTE" }, // macro/internal
+ { "STDEVP", 0 },
+ { "VARP", 0 },
+/*195*/ { "DSTDDEVP", 3 },
+ { "DVARP", 3 },
+ { "TRUNC", 0 },
+ { "ISLOGICAL", 1 },
+ { "DBCOUNTA", 3 },
+/*200*/ { "DELETE.BAR" }, // macro/internal
+ { "UNREGISTER" }, // macro/internal
+ { "202" }, // not used
+ { "203" }, // not used
+ { "USDOLLAR" },
+/*205*/ { "FINDB" },
+ { "SEARCHB" },
+ { "REPLACEB", 4 },
+ { "LEFTB" },
+ { "RIGHTB" },
+/*210*/ { "MIDB", 3 },
+ { "LENB", 1 },
+ { "ROUNDUP", 2 },
+ { "ROUNDDOWN", 2 },
+ { "ASC", 1 },
+/*215*/ { "DBSC", 1 },
+ { "RANK", 0 },
+ { "217" }, // not used
+ { "218" }, // not used
+ { "ADDRESS", 0 },
+/*220*/ { "DAYS360", 0 },
+ { "TODAY", 0 },
+ { "VDB", 0 },
+ { "ELSE" }, // macro/internal
+ { "ELSE.IF" }, // macro/internal
+/*225*/ { "END.IF" }, // macro/internal
+ { "FOR.CELL" }, // macro/internal
+ { "MEDIAN", 0 },
+ { "SUMPRODUCT", 0 },
+ { "SINH", 1 },
+/*230*/ { "COSH", 1 },
+ { "TANH", 1 },
+ { "ASINH", 1 },
+ { "ACOSH", 1 },
+ { "ATANH", 1 },
+/*235*/ { "DGET", 3 },
+ { "CREATE.OBJECT" }, // macro/internal
+ { "VOLATILE" }, // macro/internal
+ { "LAST.ERROR" }, // macro/internal
+ { "CUSTOM.UNDO" }, // macro/internal
+/*240*/ { "CUSTOM.REPEAT" }, // macro/internal
+ { "FORMULA.CONVERT" }, // macro/internal
+ { "GET.LINK.INFO" }, // macro/internal
+ { "TEXT.BOX" }, // macro/internal
+ { "INFO", 1 },
+/*245*/ { "GROUP" }, // macro/internal
+ { "GET.OBJECT" }, // macro/internal
+ { "DB", 0 },
+ { "PAUSE" }, // macro/internal
+ { "249" }, // not used
+/*250*/ { "250" }, // not used
+ { "RESUME" }, // macro/internal
+ { "FREQUENCY", 2 },
+ { "ADD.TOOLBAR" }, // macro/internal
+ { "DELETE.TOOLBAR" }, // macro/internal
+/*255*/ { "EXTERN.CALL" }, // macro/internal
+ { "RESET.TOOLBAR" }, // macro/internal
+ { "EVALUATE" }, // macro/internal
+ { "GET.TOOLBAR" }, // macro/internal
+ { "GET.TOOL" }, // macro/internal
+/*260*/ { "SPELLING.CHECK" }, // macro/internal
+ { "ERROR.TYPE", 1 },
+ { "APP.TITLE" }, // macro/internal
+ { "WINDOW.TITLE" }, // macro/internal
+ { "SAVE.TOOLBAR" }, // macro/internal
+/*265*/ { "ENABLE.TOOL" }, // macro/internal
+ { "PRESS.TOOL" }, // macro/internal
+ { "REGISTER.ID" }, // macro/internal
+ { "GET.WORKBOOK" }, // macro/internal
+ { "AVEDEV", 0 },
+/*270*/ { "BETADIST", 0 },
+ { "GAMMALN", 1 },
+ { "BETAINV", 0 },
+ { "BINOMDIST", 4 },
+ { "CHIDIST", 2 },
+/*275*/ { "CHIINV", 2 },
+ { "COMBIN", 2 },
+ { "CONFIDENCE", 3 },
+ { "CRITBINOM", 3 },
+ { "EVEN", 1 },
+/*280*/ { "EXPONDIST", 3 },
+ { "FDIST", 3 },
+ { "FINV", 3 },
+ { "FISHER", 1 },
+ { "FISHERINV", 1 },
+/*285*/ { "FLOOR", 2 },
+ { "GAMMADIST", 4 },
+ { "GAMMAINV", 3 },
+ { "CEILING", 2 },
+ { "HYPGEOMDIST", 4 },
+/*290*/ { "LOGNORMDIST", 3 },
+ { "LOGINV", 3 },
+ { "NEGBINOMDIST", 3 },
+ { "NORMDIST", 4 },
+ { "NORMSDIST", 1 },
+/*295*/ { "NORMINV", 3 },
+ { "NORMSINV", 1 },
+ { "STANDARDIZE", 3 },
+ { "ODD", 1 },
+ { "PERMUT", 2 },
+/*300*/ { "POISSON", 3 },
+ { "TDIST", 3 },
+ { "WEIBULL", 4 },
+ { "SUMXMY2", 2 },
+ { "SUMX2MY2", 2 },
+/*305*/ { "SUMX2PY2", 2 },
+ { "CHITEST", 2 },
+ { "CORREL", 2 },
+ { "COVAR", 2 },
+ { "FORECAST", 3 },
+/*310*/ { "FTEST", 2 },
+ { "INTERCEPT", 2 },
+ { "PEARSON", 2 },
+ { "RSQ", 2 },
+ { "STEYX", 2 },
+/*315*/ { "SLOPE", 2 },
+ { "TTEST", 4 },
+ { "PROB", 0 },
+ { "DEVSQ", 0 },
+ { "GEOMEAN", 0 },
+/*320*/ { "HARMEAN", 0 },
+ { "SUMSQ", 0 },
+ { "KURT", 0 },
+ { "SKEW", 0 },
+ { "ZTEST", 0 },
+/*325*/ { "LARGE", 2 },
+ { "SMALL", 2 },
+ { "QUARTILE", 2 },
+ { "PERCENTILE", 2 },
+ { "PERCENTRANK", 0 },
+/*330*/ { "MODE", 0 },
+ { "TRIMMEAN", 2 },
+ { "TINV", 2 },
+ { "333" }, // not used
+ { "MOVIE.COMMAND" }, // macro/internal
+/*335*/ { "GET.MOVIE" }, // macro/internal
+ { "CONCATENATE", 0 },
+ { "POWER", 2 },
+ { "PIVOT.ADD.DATA" }, // macro/internal
+ { "GET.PIVOT.TABLE" }, // macro/internal
+/*340*/ { "GET.PIVOT.FIELD" }, // macro/internal
+ { "GET.PIVOT.ITEM" }, // macro/internal
+ { "RADIANS", 1 },
+ { "DEGREES", 1 },
+ { "SUBTOTAL", 0 },
+/*345*/ { "SUMIF", 0 },
+ { "COUNTIF", 2 },
+ { "COUNTBLANK", 1 },
+ { "SCENARIO.GET" }, // macro/internal
+ { "OPTIONS.LISTS.GET" }, // macro/internal
+/*350*/ { "ISPMT", 4 },
+ { "DATEDIF", 3 },
+ { "DATESTRING", 1 },
+ { "NUMBERSTRING", 2 },
+ { "ROMAN", 0 },
+/*355*/ { "OPEN.DIALOG" }, // macro/internal
+ { "SAVE.DIALOG" }, // macro/internal
+ { "VIEW.GET" }, // macro/internal
+ { "GETPIVOTDATA", 0 },
+ { "HYPERLINK", 2 },
+/*360*/ { "PHONETIC", 1 },
+ { "AVERAGEA", 0 },
+ { "MAXA", 0 },
+ { "MINA", 0 },
+ { "STDEVPA", 0 },
+/*365*/ { "VARPA", 0 },
+ { "STDEVA", 0 },
+ { "VARA", 0 },
+ { "BAHTTEXT", 1 },
+ { "THAIDAYOFWEEK", 1 },
+/*370*/ { "THAIDIGIT", 1 },
+ { "THAIMONTHOFYEAR", 1 },
+ { "THAINUMSOUND", 1 },
+ { "THAINUMSTRING", 1 },
+ { "THAISTRINGLENGTH", 1 },
+/*375*/ { "ISTHAIDIGIT", 1 },
+ { "ROUNDBAHTDOWN", 1 },
+ { "ROUNDBAHTUP", 1 },
+ { "THAIYEAR", 1 },
+ { "RTD" },
+/*380*/ { "ISHYPERLINK", 1 }
+};
+
+const XclDumpFunc* lcl_GetFuncData( sal_uInt16 nIndex )
+{
+ return (nIndex < STATIC_TABLE_SIZE( pFuncData )) ? (pFuncData + nIndex) : NULL;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Stack helper to create a human readable formula string from UPN. */
+class XclDumpFormulaStackImpl : private ScfDelStack< ByteString >
+{
+public:
+ void PushOperand( const ByteString& rOperand );
+ void PushUnary( const ByteString& rOperator, bool bInFront );
+ void PushBinary( const ByteString& rOperator );
+ void PushFunction( const ByteString& rFuncName, sal_uInt16 nParamCount );
+ inline ByteString GetString() const { return Top() ? *Top() : ByteString(); }
+};
+
+void XclDumpFormulaStackImpl::PushOperand( const ByteString& rOperand )
+{
+ Push( new ByteString( rOperand ) );
+}
+
+void XclDumpFormulaStackImpl::PushUnary( const ByteString& rOperator, bool bInFront )
+{
+ if( !Count() ) return;
+ ByteString* pOp = Top();
+ pOp->Insert( rOperator, bInFront ? 0 : pOp->Len() );
+}
+
+void XclDumpFormulaStackImpl::PushBinary( const ByteString& rOperator )
+{
+ if( Count() < 2 ) return;
+ // second operand is on top
+ ByteString* pSecond = Pop();
+ ByteString* pFirst = Top();
+ *pFirst += rOperator;
+ *pFirst += *pSecond;
+ delete pSecond;
+}
+
+void XclDumpFormulaStackImpl::PushFunction( const ByteString& rFuncName, sal_uInt16 nParamCount )
+{
+ if( Count() < nParamCount ) return;
+ ByteString* pNew = new ByteString( ')' );
+ for( sal_uInt16 nIndex = 0; nIndex < nParamCount; ++nIndex )
+ {
+ if( nIndex ) pNew->Insert( ';', 0 );
+ ByteString* pOp = Pop();
+ pNew->Insert( *pOp, 0 );
+ delete pOp;
+ }
+ pNew->Insert( '(', 0 );
+ pNew->Insert( rFuncName, 0 );
+ Push( pNew );
+}
+
+// ----------------------------------------------------------------------------
+
+/** Stack to create a human readable formula and token class overview from UPN. */
+class XclDumpFormulaStack
+{
+public:
+ void PushOperand( const ByteString& rOperand, sal_uInt8 nToken );
+ inline void PushOperand( const sal_Char* pcOperand, sal_uInt8 nToken )
+ { PushOperand( ByteString( pcOperand ), nToken ); }
+
+ void PushUnary( const ByteString& rOperator, bool bInFront = true );
+ inline void PushUnary( const sal_Char* pcOperator, bool bInFront = true )
+ { PushUnary( ByteString( pcOperator ), bInFront ); }
+
+ void PushBinary( const ByteString& rOperator );
+ inline void PushBinary( const sal_Char* pcOperator )
+ { PushBinary( ByteString( pcOperator ) ); }
+
+ void PushFunction( const ByteString& rFuncName, sal_uInt16 nParamCount, sal_uInt8 nToken );
+ inline void PushFunction( const sal_Char* pcFuncName, sal_uInt16 nParamCount, sal_uInt8 nToken )
+ { PushFunction( ByteString( pcFuncName ), nParamCount, nToken ); }
+
+ inline ByteString GetFormula() const { return maFmla.GetString(); }
+ inline ByteString GetTokenClasses() const { return maClass.GetString(); }
+
+ static ByteString GetTokenClass( sal_uInt8 nToken );
+
+private:
+ void PushTokenClass( sal_uInt8 nToken );
+
+ XclDumpFormulaStackImpl maFmla;
+ XclDumpFormulaStackImpl maClass;
+};
+
+void XclDumpFormulaStack::PushOperand( const ByteString& rOperand, sal_uInt8 nToken )
+{
+ maFmla.PushOperand( rOperand );
+ maClass.PushOperand( GetTokenClass( nToken ) );
+}
+
+void XclDumpFormulaStack::PushUnary( const ByteString& rOperator, bool bInFront )
+{
+ maFmla.PushUnary( rOperator, bInFront );
+ maClass.PushUnary( rOperator, bInFront );
+}
+
+void XclDumpFormulaStack::PushBinary( const ByteString& rOperator )
+{
+ maFmla.PushBinary( rOperator );
+ maClass.PushBinary( rOperator );
+}
+
+void XclDumpFormulaStack::PushFunction( const ByteString& rFuncName, sal_uInt16 nParamCount, sal_uInt8 nToken )
+{
+ maFmla.PushFunction( rFuncName, nParamCount );
+ maClass.PushFunction( GetTokenClass( nToken ), nParamCount );
+}
+
+ByteString XclDumpFormulaStack::GetTokenClass( sal_uInt8 nToken )
+{
+ sal_Char cClass = 'B';
+ switch( nToken & 0xE0 )
+ {
+ case 0x20: cClass = 'R'; break;
+ case 0x40: cClass = 'V'; break;
+ case 0x60: cClass = 'A'; break;
+ }
+ return ByteString( cClass );
+}
+
+// ----------------------------------------------------------------------------
+
+const sal_Char* lcl_GetErrorString( sal_uInt8 nErr )
+{
+ switch( nErr )
+ {
+ case 0x00: return "#NULL!";
+ case 0x07: return "#DIV/0!";
+ case 0x0F: return "#VALUE!";
+ case 0x17: return "#REF!";
+ case 0x1D: return "#NAME?";
+ case 0x24: return "#NUM!";
+ case 0x2A: return "#N/A!";
+ }
+ return "!unknown!";
+}
+
+
+
+void lcl_StartToken( ByteString& rString, sal_uInt16 nPos, sal_uInt8 nToken, const sal_Char* pTokenName )
+{
+ rString.Erase();
+ rString.Append( " " );
+ __AddHex( rString, nPos );
+ rString.Append( " " );
+ __AddHex( rString, nToken );
+ rString.Append( " t" ).Append( pTokenName ).Expand( 33, ' ' );
+}
+
+void lcl_StartTokenClass( ByteString& rString, sal_uInt16 nPos, sal_uInt8 nToken, const sal_Char* pTokenName )
+{
+ ByteString aToken( pTokenName );
+ aToken.Append( XclDumpFormulaStack::GetTokenClass( nToken ) );
+ lcl_StartToken( rString, nPos, nToken, aToken.GetBuffer() );
+}
+
+void Biff8RecDumper::FormulaDump( const UINT16 nL, const FORMULA_TYPE eFT )
+{
+ if( !nL )
+ return;
+
+ sal_uInt32 nStartPos = pIn->GetRecPos();
+ const sal_uInt32 nAfterPos = nStartPos + nL;
+
+ BYTE nOp;
+ ByteString t, aOperand;
+ BOOL bError = FALSE;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ XclDumpFormulaStack aStack;
+ sal_Bool bPrinted = sal_True;
+
+#define PRINTTOKEN() { if( !bPrinted ) Print( t ); bPrinted = sal_True; }
+#define STARTTOKEN( name ) lcl_StartToken( t, static_cast< sal_uInt16 >( pIn->GetRecPos() - nStartPos - 1 ), nOp, name )
+#define STARTTOKENCLASS( name ) lcl_StartTokenClass( t, static_cast< sal_uInt16 >( pIn->GetRecPos() - nStartPos - 1 ), nOp, name )
+
+ while( pIn->IsValid() && ( pIn->GetRecPos() < nAfterPos ) && !bError )
+ {
+ *pIn >> nOp;
+ bPrinted = sal_False;
+ aOperand.Erase();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ {
+ STARTTOKEN( "Exp" );
+ sal_uInt16 nRow, nCol;
+ *pIn >> nRow >> nCol;
+ t += "array formula or shared formula, base-address=";
+ lcl_AddRef( t, nCol, nRow );
+ aStack.PushFunction( "ARRAY", 0, nOp );
+ }
+ break;
+ case 0x02: // Data Table [325 277]
+ {
+ STARTTOKEN( "Tbl" );
+ sal_uInt16 nRow, nCol;
+ *pIn >> nRow >> nCol;
+ t += "multiple operation, base-address=";
+ lcl_AddRef( t, nCol, nRow );
+ aStack.PushFunction( "MULTIPLE.OPERATIONS", 0, nOp );
+ }
+ break;
+ case 0x03: // Addition [312 264]
+ STARTTOKEN( "Add" );
+ aStack.PushBinary( "+" );
+ break;
+ case 0x04: // Subtraction [313 264]
+ STARTTOKEN( "Sub" );
+ aStack.PushBinary( "-" );
+ break;
+ case 0x05: // Multiplication [313 264]
+ STARTTOKEN( "Mul" );
+ aStack.PushBinary( "*" );
+ break;
+ case 0x06: // Division [313 264]
+ STARTTOKEN( "Div" );
+ aStack.PushBinary( "/" );
+ break;
+ case 0x07: // Exponetiation [313 265]
+ STARTTOKEN( "Power" );
+ aStack.PushBinary( "^" );
+ break;
+ case 0x08: // Concatenation [313 265]
+ STARTTOKEN( "Concat" );
+ aStack.PushBinary( "&" );
+ break;
+ case 0x09: // Less Than [313 265]
+ STARTTOKEN( "LT" );
+ aStack.PushBinary( "<" );
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ STARTTOKEN( "LE" );
+ aStack.PushBinary( "<=" );
+ break;
+ case 0x0B: // Equal [313 265]
+ STARTTOKEN( "EQ" );
+ aStack.PushBinary( "=" );
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ STARTTOKEN( "GE" );
+ aStack.PushBinary( ">=" );
+ break;
+ case 0x0D: // Greater Than [313 265]
+ STARTTOKEN( "GT" );
+ aStack.PushBinary( ">" );
+ break;
+ case 0x0E: // Not Equal [313 265]
+ STARTTOKEN( "NE" );
+ aStack.PushBinary( "<>" );
+ break;
+ case 0x0F: // Intersection [314 265]
+ STARTTOKEN( "Isect" );
+ aStack.PushBinary( " " );
+ break;
+ case 0x10: // List [314 265]
+ STARTTOKEN( "List" );
+ aStack.PushBinary( ";" );
+ break;
+ case 0x11: // Range [314 265]
+ STARTTOKEN( "Range" );
+ aStack.PushBinary( ":" );
+ break;
+ case 0x12: // Unary Plus [312 264]
+ STARTTOKEN( "Uplus" );
+ aStack.PushUnary( "+" );
+ break;
+ case 0x13: // Unary Minus [312 264]
+ STARTTOKEN( "Uminus" );
+ aStack.PushUnary( "-" );
+ break;
+ case 0x14: // Percent Sign [312 264]
+ STARTTOKEN( "Percent" );
+ aStack.PushUnary( "%", false );
+ break;
+ case 0x15: // Parenthesis [326 278]
+ STARTTOKEN( "Paren" );
+ // simulate two unary operators to enclose operand
+ aStack.PushUnary( "(" );
+ aStack.PushUnary( ")", false );
+ break;
+ case 0x16: // Missing Argument [314 266]
+ STARTTOKEN( "MissArg" );
+ aStack.PushOperand( "~", nOp );
+ break;
+ case 0x17: // ByteString Constant [314 266]
+ {
+ STARTTOKEN( "Str" );
+
+ UINT8 nLen;
+ *pIn >> nLen;
+
+ t += "string [len=";
+ __AddDec( t, nLen );
+ t += "] ";
+
+ aOperand += '"';
+ if( nLen )
+ aOperand += GETSTR( pIn->ReadUniString( nLen ) );
+ else
+ pIn->Ignore( 1 );
+ aOperand += '"';
+ t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x18:
+ {
+ STARTTOKEN( "Extended" );
+ UINT8 nEptg;
+ *pIn >> nEptg;
+
+#define D(name,size,ext,type) {t+="eptg ";__AddDec(t,(UINT16)nEptg);t+=": "; \
+ t+=name;t+=" [";__AddDec(t,(UINT16)size);t+="] ";t+=type; \
+ if(ext)t+=" + ext";PRINTTOKEN();ContDump(size);aStack.PushOperand(name,nOp);}
+ switch( nEptg )
+ { // name size ext type
+ case 0x00: // res
+ D( "res", 0, 0, "" );
+ break;
+ case 0x01: // Lel 4 - err
+ D( "Lel", 4, 0, "err" );
+ break;
+ case 0x02: // Rw 4 - ref
+ D( "Rw", 4, 0, "ref" );
+ break;
+ case 0x03: // Col 4 - ref
+ D( "Col", 4, 0, "ref" );
+ break;
+ case 0x04: // res
+ case 0x05: // res
+ D( "res", 0, 0, "" );
+ break;
+ case 0x06: // RwV 4 - val
+ D( "RwV", 4, 0, "val" );
+ break;
+ case 0x07: // ColV 4 - val
+ D( "ColV", 4, 0, "val" );
+ break;
+ case 0x08: // res
+ case 0x09: // res
+ D( "res", 0, 0, "" );
+ break;
+ case 0x0A: // Radical 13 - ref
+ D( "Radical", 13, 0, "ref" );
+ break;
+ case 0x0B: // RadicalS 13 x ref
+ D( "RadicalS", 13, 1, "ref" );
+ break;
+ case 0x0C: // RwS 4 x ref
+ D( "RwS", 4, 1, "ref" );
+ break;
+ case 0x0D: // ColS 4 x ref
+ D( "ColS", 4, 1, "ref" );
+ break;
+ case 0x0E: // RwSV 4 x val
+ D( "RwSV", 4, 1, "val" );
+ break;
+ case 0x0F: // ColSV 4 x val
+ D( "ColSV", 4, 1, "val" );
+ break;
+ case 0x10: // RadicalLel 4 - err
+ D( "RadicalLel", 4, 0, "err" );
+ break;
+ case 0x11: // res
+ case 0x12: // res
+ case 0x13: // res
+ case 0x14: // res
+ case 0x15: // res
+ case 0x16: // res
+ case 0x17: // res
+ case 0x18: // res
+ D( "res", 0, 0, "" );
+ break;
+ case 0x19: // invalid values
+ case 0x1A: // invalid values
+ D( "invalid vals", 0, 0, "" );
+ break;
+ case 0x1B: // res
+ case 0x1C: // res
+ D( "res", 0, 0, "" );
+ break;
+ case 0x1D: // SxName 4 - val
+ D( "SxName", 4, 0, "val" );
+ break;
+ case 0x1E: // res
+ D( "res", 0, 0, "" );
+ break;
+ default:
+ D( "!unknown!", 0, 0, "" );
+ }
+#undef D
+ }
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ STARTTOKEN( "Attr" );
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ *pIn >> nOpt >> nData;
+ nFakt = 2;
+
+ t += "flags="; __AddHex( t, nOpt );
+
+ if( nOpt & 0x01 ) t += " volatile";
+ if( nOpt & 0x02 ) t += " if";
+ if( nOpt & 0x04 ) t += " choose";
+ if( nOpt & 0x08 ) t += " skip";
+ if( nOpt & 0x10 ) t += " sum";
+ if( nOpt & 0x20 ) t += " assignment";
+ if( nOpt & 0x40 ) t += " space";
+ if( nOpt & 0x80 ) t += " unknown";
+
+ if( nOpt & 0x02 )
+ {
+ t += " skip-to-false=";
+ __AddHex( t, nData );
+ }
+ if( nOpt & 0x04 )
+ {
+ t += " count=";
+ __AddDec( t, nData );
+ t += " skip=";
+ for( sal_uInt16 nIdx = 0; nIdx <= nData; ++nIdx )
+ {
+ if( nIdx ) t += ',';
+ __AddDec( t, pIn->ReaduInt16() );
+ }
+ }
+ if( nOpt & 0x08 )
+ {
+ t += " skip=";
+ __AddHex( t, nData );
+ t += " (";
+ __AddDec( t, sal_uInt8( nData + 1 ) );
+ t += " bytes)";
+ }
+ if( nOpt & 0x10 )
+ aStack.PushFunction( "ATTRSUM", 1, nOp );
+ if( nOpt & 0x40 )
+ {
+ t += " type=";
+ __AddDec( t, static_cast< sal_uInt8 >( nData ) );
+ t += " count=";
+ __AddDec( t, static_cast< sal_uInt8 >( nData >> 8 ) );
+ }
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ STARTTOKEN( "Err" );
+ sal_uInt8 nErr = pIn->ReaduInt8();
+ t += "error value ("; __AddHex( t, nErr );
+ t += ") ";
+ t += lcl_GetErrorString( nErr );
+ aStack.PushOperand( lcl_GetErrorString( nErr ), nOp );
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ STARTTOKEN( "Bool" );
+ aOperand += pIn->ReaduInt8() ? "TRUE" : "FALSE";
+ t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ break;
+ case 0x1E: // Integer [315 266]
+ STARTTOKEN( "Int" );
+ __AddDec( aOperand, pIn->ReaduInt16() );
+ t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ break;
+ case 0x1F: // Number [315 266]
+ STARTTOKEN( "Num" );
+ __AddDouble( aOperand, pIn->ReadDouble() );
+ t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ break;
+ case 0x20: // Array Constant [317 268]
+ case 0x40:
+ case 0x60:
+ STARTTOKENCLASS( "Array" );
+ pIn->Ignore( 7 );
+ aStack.PushOperand( "{ConstArray}", nOp );
+ break;
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x41:
+ case 0x61:
+ {
+ STARTTOKENCLASS( "Func" );
+ UINT16 nInd = pIn->ReaduInt16();
+ const XclDumpFunc* pFunc = lcl_GetFuncData( nInd );
+ aOperand += pFunc ? pFunc->pName : "!unknown!";
+
+ t += "fix function: index="; __AddHex( t, nInd );
+ t += " ("; t += aOperand;
+ t += ')';
+ aStack.PushFunction( aOperand, pFunc ? pFunc->nParam : 0, nOp );
+ }
+ break;
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ case 0x42:
+ case 0x62:
+ {
+ STARTTOKENCLASS( "FuncVar" );
+ BYTE nAnz;
+ UINT16 nInd;
+ *pIn >> nAnz >> nInd;
+ const XclDumpFunc* pFunc = lcl_GetFuncData( nInd & 0x7FFF );
+ aOperand += pFunc ? pFunc->pName : "!unknown!";
+
+ t += "var function: index="; __AddHex( t, nInd );
+ t += " ("; t += aOperand;
+ t += ") param count="; __AddHex( t, nAnz );
+ t += " ("; __AddDec( t, (UINT8)(nAnz & 0x7F) );
+ t += ')';
+ if( nAnz & 0x8000 )
+ t += " cmd-equiv.";
+ aStack.PushFunction( aOperand, nAnz & 0x7F, nOp );
+ }
+ break;
+ case 0x23: // Name [318 269]
+ case 0x43:
+ case 0x63:
+ {
+ STARTTOKENCLASS( "Name" );
+ sal_uInt16 nNameIdx = pIn->ReaduInt16();
+ __AddDec( aOperand, nNameIdx );
+ t += "internal name: index=";
+ t += aOperand;
+ pIn->Ignore( 2 );
+ if( (0 < nNameIdx) && (nNameIdx <= maNames.size()) )
+ aOperand = maNames[ nNameIdx - 1 ];
+ else
+ aOperand.Insert( "NAME(", 0 ).Append( ')' );
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x24: // Cell Reference [319 270]
+ case 0x44:
+ case 0x64:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ case 0x4A:
+ case 0x6A:
+ {
+ if( (nOp & 0x1F) == 0x04 )
+ STARTTOKENCLASS( "Ref" );
+ else
+ STARTTOKENCLASS( "RefErr" );
+
+ UINT16 nCol, nRow;
+ *pIn >> nRow >> nCol;
+ AddRef( aOperand, nRow, nCol, bRangeName );
+ t += "2D cell ref C/R="; __AddHex( t, nCol );
+ t += '/'; __AddHex( t, nRow );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x25: // Area Reference [320 270]
+ case 0x45:
+ case 0x65:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ case 0x4B:
+ case 0x6B:
+ {
+ if( (nOp & 0x1F) == 0x05 )
+ STARTTOKENCLASS( "Area" );
+ else
+ STARTTOKENCLASS( "AreaErr" );
+
+ UINT16 nRowFirst, nRowLast, nColFirst, nColLast;
+ *pIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+ AddRangeRef( aOperand, nRowFirst, nColFirst, nRowLast, nColLast, bRangeName );
+ t += "2D area ref C/R:C/R="; __AddHex( t, nColFirst );
+ t += '/'; __AddHex( t, nRowFirst );
+ t += ':'; __AddHex( t, nColLast );
+ t += '/'; __AddHex( t, nRowLast );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x46:
+ case 0x66:
+ {
+ STARTTOKENCLASS( "MemArea" );
+ sal_uInt32 nRes;
+ sal_uInt16 nSize;
+ *pIn >> nRes >> nSize;
+ t += "reserved="; __AddHex( t, nRes );
+ t += " size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x47:
+ case 0x67:
+ {
+ STARTTOKENCLASS( "MemErr" );
+ sal_uInt32 nRes;
+ sal_uInt16 nSize;
+ *pIn >> nRes >> nSize;
+ t += "reserved="; __AddHex( t, nRes );
+ t += " size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x48:
+ case 0x68:
+ {
+ STARTTOKENCLASS( "MemNoMem" );
+ sal_uInt32 nRes;
+ sal_uInt16 nSize;
+ *pIn >> nRes >> nSize;
+ t += "reserved="; __AddHex( t, nRes );
+ t += " size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x49:
+ case 0x69:
+ {
+ STARTTOKENCLASS( "MemFunc" );
+ sal_uInt16 nSize;
+ *pIn >> nSize;
+ t += "size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x2C: // Cell Reference Within a Name/ShrdFmla [323 273]
+ case 0x4C:
+ case 0x6C:
+ {
+ STARTTOKENCLASS( "RefN" );
+ UINT16 nRow, nCol;
+ *pIn >> nRow >> nCol;
+ AddRef( aOperand, nRow, nCol, bRNorSF );
+ t += "2D cell ref in name C/R="; __AddHex( t, nCol );
+ t += '/'; __AddHex( t, nRow );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x2D: // Area Reference Within a Name/ShrdFmla [324 274]
+ case 0x4D:
+ case 0x6D:
+ {
+ STARTTOKENCLASS( "AreaN" );
+ UINT16 nRowFirst, nRowLast, nColFirst, nColLast;
+ *pIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+ AddRangeRef( aOperand, nRowFirst, nColFirst, nRowLast, nColLast, bRNorSF );
+ t += "2D area ref in name C/R:C/R"; __AddHex( t, nColFirst );
+ t += '/'; __AddHex( t, nRowFirst );
+ t += ':'; __AddHex( t, nColLast );
+ t += '/'; __AddHex( t, nRowLast );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4E:
+ case 0x6E:
+ {
+ STARTTOKENCLASS( "MemAreaN" );
+ sal_uInt16 nSize;
+ *pIn >> nSize;
+ t += "size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x4F:
+ case 0x6F:
+ {
+ STARTTOKENCLASS( "MemNoMemN" );
+ sal_uInt16 nSize;
+ *pIn >> nSize;
+ t += "size="; __AddDec( t, nSize );
+ }
+ break;
+ case 0x39: // Name or External Name [ 275]
+ case 0x59:
+ case 0x79:
+ {
+ STARTTOKENCLASS( "NameX" );
+ UINT16 nXti, nName;
+ *pIn >> nXti >> nName;
+ pIn->Ignore( 2 );
+ t += "external name: XTI="; __AddDec( t, nXti );
+ t += " name index="; __AddDec( t, nName );
+ aOperand += "EXTNAME(XTI(";
+ __AddDec( aOperand, nXti );
+ aOperand += "),";
+ __AddDec( aOperand, nName );
+ aOperand += ')';
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5A:
+ case 0x7A:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ case 0x5C:
+ case 0x7C:
+ {
+ if( (nOp & 0x1F) == 0x1A )
+ STARTTOKENCLASS( "Ref3d" );
+ else
+ STARTTOKENCLASS( "Ref3dErr" );
+
+ UINT16 nXti, nRow, nCol;
+ *pIn >> nXti >> nRow >> nCol;
+ AddRef( aOperand, nRow, nCol, bRangeName, nXti );
+ t += "3D cell ref Xti!C/R="; __AddHex( t, nXti );
+ t += '!'; __AddHex( t, nCol );
+ t += '/'; __AddHex( t, nRow );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5B:
+ case 0x7B:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ case 0x5D:
+ case 0x7D:
+ {
+ if( (nOp & 0x1F) == 0x1B )
+ STARTTOKENCLASS( "Area3d" );
+ else
+ STARTTOKENCLASS( "Area3dErr" );
+
+ UINT16 nXti, nRow1, nCol1, nRow2, nCol2;
+ *pIn >> nXti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ AddRangeRef( aOperand, nRow1, nCol1, nRow2, nCol2, bRangeName, nXti );
+ t += "3D area ref Xti!C/R:C/R="; __AddHex( t, nXti );
+ t += '!'; __AddHex( t, nCol1 );
+ t += '/'; __AddHex( t, nRow1 );
+ t += ':'; __AddHex( t, nCol2 );
+ t += '/'; __AddHex( t, nRow2 );
+ t += ' '; t += aOperand;
+ aStack.PushOperand( aOperand, nOp );
+ }
+ break;
+ default:
+ STARTTOKEN( "unknown" );
+ bError = TRUE;
+ }
+ PRINTTOKEN();
+ }
+ t.Assign( " Formula = " );
+ if( aStack.GetFormula().Len() ) t += aStack.GetFormula(); else t += "ERROR IN STACK";
+ Print( t );
+ t.Assign( " Tokencl = " ).Append( aStack.GetTokenClasses() );
+ Print( t );
+ pIn->Seek( nAfterPos );
+}
+
+
+// ============================================================================
+//
+// S T R E A M C O N T E N T S
+//
+// ============================================================================
+
+void Biff8RecDumper::DumpBinary( SvStream& rInStrm, ULONG nSize )
+{
+ ULONG nStrmPos = rInStrm.Tell();
+ rInStrm.Seek( STREAM_SEEK_TO_END );
+ ULONG nStrmLen = rInStrm.Tell();
+ rInStrm.Seek( nStrmPos );
+ ULONG nDumpEnd = (nSize == STREAM_SEEK_TO_END) ? nStrmLen : ::std::min( nStrmPos + nSize, nStrmLen );
+
+ const ULONG LINE_SIZE = 16;
+ sal_uInt8 pnData[ LINE_SIZE ];
+
+ while( rInStrm.Tell() < nDumpEnd )
+ {
+ ByteString aBinLine;
+ ByteString aTextLine;
+
+ ULONG nLineLen = ::std::min( nDumpEnd - rInStrm.Tell(), LINE_SIZE );
+ rInStrm.Read( pnData, nLineLen );
+
+ for( sal_uInt8 *pnByte = pnData, *pnEnd = pnData + nLineLen; pnByte != pnEnd; ++pnByte )
+ {
+ if( pnByte - pnData == LINE_SIZE / 2 )
+ {
+ aBinLine.Append( ' ' );
+ aTextLine.Append( ' ' );
+ }
+ __AddPureHex( aBinLine, *pnByte );
+ aBinLine.Append( ' ' );
+ aTextLine.Append( static_cast< sal_Char >( IsPrintable( *pnByte ) ? *pnByte : '.' ) );
+ }
+
+ aBinLine.Expand( LINE_SIZE * 3 + 3, ' ' );
+ (*pDumpStream) << aBinLine.GetBuffer() << aTextLine.GetBuffer() << "\n";
+ }
+}
+
+// ============================================================================
+//
+// F O R M C O N T R O L S
+//
+// ============================================================================
+
+namespace {
+
+// little helpers -------------------------------------------------------------
+
+/** Import from bytestream. */
+SvStream& operator>>( SvStream& rStrm, XclGuid& rGuid )
+{
+ rStrm.Read( rGuid.mpnData, 16 );
+ return rStrm;
+}
+
+/** Output guid into text stream. */
+SvStream& operator<<( SvStream& rStrm, const XclGuid& rGuid )
+{
+ ByteString aOut;
+ lclAppendGuid( aOut, rGuid );
+ return rStrm << aOut.GetBuffer();
+}
+
+void lclAlignStream( SvStream& rInStrm, ULONG nStartPos, ULONG nDataWidth )
+{
+ rInStrm.SeekRel( nDataWidth - 1 - (rInStrm.Tell() - nStartPos + nDataWidth - 1) % nDataWidth );
+}
+
+// control types --------------------------------------------------------------
+
+const sal_uInt16 EXC_CTRL_PAGE = 0x0007;
+const sal_uInt16 EXC_CTRL_IMAGE = 0x000C;
+const sal_uInt16 EXC_CTRL_FRAME = 0x000E;
+const sal_uInt16 EXC_CTRL_SPINBUTTON = 0x0010;
+const sal_uInt16 EXC_CTRL_PUSHBUTTON = 0x0011;
+const sal_uInt16 EXC_CTRL_TABSTRIP = 0x0012;
+const sal_uInt16 EXC_CTRL_LABEL = 0x0015;
+const sal_uInt16 EXC_CTRL_TEXTBOX = 0x0017;
+const sal_uInt16 EXC_CTRL_LISTBOX = 0x0018;
+const sal_uInt16 EXC_CTRL_COMBOBOX = 0x0019;
+const sal_uInt16 EXC_CTRL_CHECKBOX = 0x001A;
+const sal_uInt16 EXC_CTRL_OPTIONBUTTON = 0x001B;
+const sal_uInt16 EXC_CTRL_TOGGLEBUTTON = 0x001C;
+const sal_uInt16 EXC_CTRL_SCROLLBAR = 0x002F;
+const sal_uInt16 EXC_CTRL_MULTIPAGE = 0x0039;
+const sal_uInt16 EXC_CTRL_REFEDIT = 0x8000;
+const sal_uInt16 EXC_CTRL_FONTDATA = 0xFFF0; // internal use only
+const sal_uInt16 EXC_CTRL_USERFORM = 0xFFF1; // internal use only
+const sal_uInt16 EXC_CTRL_ADDDATA = 0xFFF2; // internal use only
+const sal_uInt16 EXC_CTRL_FRAMECHILD = 0xFFF3; // internal use only
+const sal_uInt16 EXC_CTRL_PROGRESSBAR = 0xFFF4; // internal use only
+const sal_uInt16 EXC_CTRL_UNKNOWN = 0xFFFF; // internal use only
+
+const sal_uInt16 EXC_CTRL_RECORD_ID = 0x0000;
+const sal_uInt16 EXC_CTRL_CLIENT_ID = 0x0200;
+const sal_uInt16 EXC_CTRL_CONTAINER_ID = 0x0400;
+
+// control names --------------------------------------------------------------
+
+struct XclDumpControlInfo
+{
+ sal_uInt16 mnType;
+ const sal_Char* mpcName;
+ sal_uInt16 mnId;
+};
+
+static const XclDumpControlInfo spControlInfos[] =
+{
+ { EXC_CTRL_PAGE, "Page", EXC_CTRL_CONTAINER_ID },
+ { EXC_CTRL_IMAGE, "Image", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_FRAME, "Frame", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_SPINBUTTON, "Spin", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_PUSHBUTTON, "PushButton", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_TABSTRIP, "TabStrip", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_LABEL, "Label", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_TEXTBOX, "TextBox", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_LISTBOX, "ListBox", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_COMBOBOX, "ComboBox", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_CHECKBOX, "CheckBox", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_OPTIONBUTTON, "OptionButton", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_TOGGLEBUTTON, "ToggleButton", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_SCROLLBAR, "ScrollBar", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_MULTIPAGE, "MultiPage", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_REFEDIT, "RefEdit", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_FONTDATA, "FontData", EXC_CTRL_CLIENT_ID },
+ { EXC_CTRL_USERFORM, "UserForm", EXC_CTRL_CONTAINER_ID },
+ { EXC_CTRL_ADDDATA, "AddData", EXC_CTRL_RECORD_ID },
+ { EXC_CTRL_FRAMECHILD, "FrameChild", EXC_CTRL_RECORD_ID },
+ { EXC_CTRL_PROGRESSBAR, "ProgressBar", EXC_CTRL_RECORD_ID }
+};
+
+typedef ::std::map< sal_uInt16, const XclDumpControlInfo* > XclDumpControlInfoMap;
+typedef ScfRef< XclDumpControlInfoMap > XclDumpControlInfoMapRef;
+
+XclDumpControlInfoMapRef lclCreateControlInfoMap()
+{
+ XclDumpControlInfoMapRef xMap( new XclDumpControlInfoMap );
+ for( const XclDumpControlInfo *pIt = spControlInfos, *pEnd = STATIC_TABLE_END( spControlInfos ); pIt != pEnd; ++pIt )
+ (*xMap)[ pIt->mnType ] = pIt;
+ return xMap;
+}
+
+const XclDumpControlInfoMap& lclGetControlInfoMap()
+{
+ static const XclDumpControlInfoMapRef sxMap = lclCreateControlInfoMap();
+ return *sxMap;
+}
+
+void lclAppendControlType( ByteString& rStr, sal_uInt16 nCtrlType )
+{
+ const XclDumpControlInfoMap& rMap = lclGetControlInfoMap();
+ XclDumpControlInfoMap::const_iterator aIt = rMap.find( nCtrlType );
+ rStr.Append( (aIt == rMap.end()) ? "*UNKNOWN*" : aIt->second->mpcName );
+}
+
+void lclDumpControlType( SvStream& rOutStrm, sal_uInt16 nCtrlType )
+{
+ ByteString aTitle( "type=" );
+ lclAppendHex( aTitle, nCtrlType );
+ aTitle.Append( " (" );
+ lclAppendControlType( aTitle, nCtrlType );
+ aTitle.Append( ')' );
+ rOutStrm << aTitle.GetBuffer();
+}
+
+sal_uInt16 lclDumpControlHeader( SvStream& rInStrm, SvStream& rOutStrm, sal_uInt16 nCtrlType )
+{
+ lclDumpControlType( rOutStrm, nCtrlType );
+ sal_uInt16 nId, nSize;
+ rInStrm >> nId >> nSize;
+ ByteString aLine( " id=" ); lclAppendHex( aLine, nId );
+ const XclDumpControlInfoMap& rMap = lclGetControlInfoMap();
+ XclDumpControlInfoMap::const_iterator aIt = rMap.find( nCtrlType );
+ bool bValid = (aIt != rMap.end()) && (aIt->second->mnId == nId);
+ aLine.Append( bValid ? " (valid)" : " (invalid)" );
+ aLine.Append( " size=" ); lclAppendHex( aLine, nSize );
+ rOutStrm << aLine.GetBuffer() << "\n";
+ return nSize;
+}
+
+// control GUIDs --------------------------------------------------------------
+
+struct XclDumpControlGuid
+{
+ sal_uInt16 mnType;
+ sal_uInt32 mnGuidData1;
+ sal_uInt16 mnGuidData2;
+ sal_uInt16 mnGuidData3;
+ sal_uInt8 mnGuidData41;
+ sal_uInt8 mnGuidData42;
+ sal_uInt8 mnGuidData43;
+ sal_uInt8 mnGuidData44;
+ sal_uInt8 mnGuidData45;
+ sal_uInt8 mnGuidData46;
+ sal_uInt8 mnGuidData47;
+ sal_uInt8 mnGuidData48;
+};
+
+static const XclDumpControlGuid spControlGuids[] =
+{
+ { EXC_CTRL_PUSHBUTTON, 0xD7053240, 0xCE69, 0x11CD, 0xA7, 0x77, 0x00, 0xDD, 0x01, 0x14, 0x3C, 0x57 },
+ { EXC_CTRL_TOGGLEBUTTON, 0x8BD21D60, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_CHECKBOX, 0x8BD21D40, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_OPTIONBUTTON, 0x8BD21D50, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_LABEL, 0x978C9E23, 0xD4B0, 0x11CE, 0xBF, 0x2D, 0x00, 0xAA, 0x00, 0x3F, 0x40, 0xD0 },
+ { EXC_CTRL_TEXTBOX, 0x8BD21D10, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_LISTBOX, 0x8BD21D20, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_COMBOBOX, 0x8BD21D30, 0xEC42, 0x11CE, 0x9E, 0x0D, 0x00, 0xAA, 0x00, 0x60, 0x02, 0xF3 },
+ { EXC_CTRL_SPINBUTTON, 0x79176FB0, 0xB7F2, 0x11CE, 0x97, 0xEF, 0x00, 0xAA, 0x00, 0x6D, 0x27, 0x76 },
+ { EXC_CTRL_SCROLLBAR, 0xDFD181E0, 0x5E2F, 0x11CE, 0xA4, 0x49, 0x00, 0xAA, 0x00, 0x4A, 0x80, 0x3D },
+ { EXC_CTRL_IMAGE, 0x4C599241, 0x6926, 0x101B, 0x99, 0x92, 0x00, 0x00, 0x0B, 0x65, 0xC6, 0xF9 },
+ { EXC_CTRL_PROGRESSBAR, 0x35053A22, 0x8589, 0x11D1, 0xB1, 0x6A, 0x00, 0xC0, 0xF0, 0x28, 0x36, 0x28 }
+};
+
+typedef ::std::map< XclGuid, sal_uInt16 > XclDumpControlGuidMap;
+typedef ScfRef< XclDumpControlGuidMap > XclDumpControlGuidMapRef;
+
+XclDumpControlGuidMapRef lclCreateControlGuidMap()
+{
+ XclDumpControlGuidMapRef xMap( new XclDumpControlGuidMap );
+ for( const XclDumpControlGuid *pIt = spControlGuids, *pEnd = STATIC_TABLE_END( spControlGuids ); pIt != pEnd; ++pIt )
+ {
+ XclGuid aGuid( pIt->mnGuidData1, pIt->mnGuidData2, pIt->mnGuidData3,
+ pIt->mnGuidData41, pIt->mnGuidData42, pIt->mnGuidData43, pIt->mnGuidData44,
+ pIt->mnGuidData45, pIt->mnGuidData46, pIt->mnGuidData47, pIt->mnGuidData48 );
+ (*xMap)[ aGuid ] = pIt->mnType;
+ }
+ return xMap;
+}
+
+const XclDumpControlGuidMap& lclGetControlGuidMap()
+{
+ static const XclDumpControlGuidMapRef sxMap = lclCreateControlGuidMap();
+ return *sxMap;
+}
+
+sal_uInt16 lclDumpControlGuid( SvStream& rInStrm, SvStream& rOutStrm )
+{
+ XclGuid aGuid;
+ rInStrm >> aGuid;
+ const XclDumpControlGuidMap& rMap = lclGetControlGuidMap();
+ XclDumpControlGuidMap::const_iterator aIt = rMap.find( aGuid );
+ sal_uInt16 nCtrlType = (aIt == rMap.end()) ? EXC_CTRL_UNKNOWN : aIt->second;
+ rOutStrm << "guid=" << aGuid;
+ return nCtrlType;
+};
+
+// other guids ----------------------------------------------------------------
+
+static const XclGuid saStdFontGuid( 0x0BE35203, 0x8F91, 0x11CE, 0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51 );
+static const XclGuid saStdPicGuid( 0x0BE35204, 0x8F91, 0x11CE, 0x9D, 0xE3, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51 );\
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// *** yet some other ugly macros for the specials of form control dumping ***
+
+// align the instream
+#define EXC_CTRLDUMP_ALIGN_INSTRM( val ) lclAlignStream( rInStrm, nStartPos, val )
+// push the string to outstream
+#define EXC_CTRLDUMP_PRINT() { if( t.Len() ) { rOutStrm << t.GetBuffer() << '\n'; t.Erase(); } }
+
+// implementation, don't use
+#define IMPL_EXC_CTRLDUMP_PLAIN_VALUE( type, func, text ) { type n; rInStrm >> n; t.Append( " " text "=" ); func( t, n ); EXC_CTRLDUMP_PRINT(); }
+#define IMPL_EXC_CTRLDUMP_VALUE( type, func, text ) { EXC_CTRLDUMP_ALIGN_INSTRM( sizeof( type ) ); IMPL_EXC_CTRLDUMP_PLAIN_VALUE( type, func, text ); }
+#define IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, mask, func, text ) { rInStrm >> var; var &= (mask); t.Append( " " text "=" ); func( t, var ); EXC_CTRLDUMP_PRINT(); }
+#define IMPL_EXC_CTRLDUMP_VAR( var, mask, func, text ) { EXC_CTRLDUMP_ALIGN_INSTRM( sizeof( var ) ); IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, mask, func, text ); }
+
+// read a value from stream (no stream alignment)
+#define EXC_CTRLDUMP_PLAIN_HEX4( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_uInt32, lclAppendHex, text )
+#define EXC_CTRLDUMP_PLAIN_DEC4( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_Int32, lclAppendDec, text )
+#define EXC_CTRLDUMP_PLAIN_HEX2( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_uInt16, lclAppendHex, text )
+#define EXC_CTRLDUMP_PLAIN_DEC2( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_Int16, lclAppendDec, text )
+#define EXC_CTRLDUMP_PLAIN_HEX1( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_uInt8, lclAppendHex, text )
+#define EXC_CTRLDUMP_PLAIN_DEC1( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( sal_Int8, lclAppendDec, text )
+#define EXC_CTRLDUMP_PLAIN_DECF( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( float, lclAppendDec, text )
+// read a value from stream (with stream alignment)
+#define EXC_CTRLDUMP_HEX4( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_uInt32, lclAppendHex, text )
+#define EXC_CTRLDUMP_DEC4( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_Int32, lclAppendDec, text )
+#define EXC_CTRLDUMP_HEX2( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_uInt16, lclAppendHex, text )
+#define EXC_CTRLDUMP_DEC2( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_Int16, lclAppendDec, text )
+#define EXC_CTRLDUMP_HEX1( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_uInt8, lclAppendHex, text )
+#define EXC_CTRLDUMP_DEC1( text ) IMPL_EXC_CTRLDUMP_VALUE( sal_Int8, lclAppendDec, text )
+// read a value from stream into existing variable (no stream alignment)
+#define EXC_CTRLDUMP_PLAIN_HEXVAR( var, text ) IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, ~0, lclAppendHex, text )
+#define EXC_CTRLDUMP_PLAIN_DECVAR( var, text ) IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, ~0, lclAppendDec, text )
+#define EXC_CTRLDUMP_PLAIN_HEXVARMASK( var, mask, text ) IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, mask, lclAppendHex, text )
+#define EXC_CTRLDUMP_PLAIN_DECVARMASK( var, mask, text ) IMPL_EXC_CTRLDUMP_PLAIN_VAR( var, mask, lclAppendDec, text )
+// read a value from stream into existing variable (with stream alignment)
+#define EXC_CTRLDUMP_HEXVAR( var, text ) IMPL_EXC_CTRLDUMP_VAR( var, ~0, lclAppendHex, text )
+#define EXC_CTRLDUMP_DECVAR( var, text ) IMPL_EXC_CTRLDUMP_VAR( var, ~0, lclAppendDec, text )
+#define EXC_CTRLDUMP_HEXVARMASK( var, mask, text ) IMPL_EXC_CTRLDUMP_VAR( var, mask, lclAppendHex, text )
+#define EXC_CTRLDUMP_DECVARMASK( var, mask, text ) IMPL_EXC_CTRLDUMP_VAR( var, mask, lclAppendDec, text )
+// read flag fields
+#define EXC_CTRLDUMP_PLAIN_STARTOPTFLAG( text, doread, defaults )\
+{ \
+ nFlags = defaults; \
+ t.Append( " " text ); \
+ if( doread ) \
+ rInStrm >> nFlags; \
+ else \
+ t.Append( "-defaulted" ); \
+ t.Append( '=' ); \
+ lclAppendHex( t, nFlags ); \
+}
+#define EXC_CTRLDUMP_STARTOPTFLAG( text, doread, defaults ) { if( doread ) { EXC_CTRLDUMP_ALIGN_INSTRM( sizeof( nFlags ) ); } EXC_CTRLDUMP_PLAIN_STARTOPTFLAG( text, doread, defaults ) }
+#define EXC_CTRLDUMP_PLAIN_STARTFLAG( text ) EXC_CTRLDUMP_PLAIN_STARTOPTFLAG( text, true, 0 )
+#define EXC_CTRLDUMP_STARTFLAG( text ) EXC_CTRLDUMP_STARTOPTFLAG( text, true, 0 )
+#define EXC_CTRLDUMP_ADDFLAG( flag, text ) { if( nFlags & (flag) ) t.Append( " " text ); }
+#define EXC_CTRLDUMP_ADDFLAGVALUE( start, width, text ) { sal_uInt32 nValue; ::extract_value( nValue, nFlags, start, width ); t.Append( " " text "=" ); lclAppendDec( t, nValue ); }
+#define EXC_CTRLDUMP_ENDFLAG( reserved ) { if( nFlags & (reserved) ) { t.Append( " ?" ); lclAppendHex( t, static_cast< sal_uInt32 >( nFlags & (reserved) ) ); } EXC_CTRLDUMP_PRINT(); }
+// read coordinates
+#define EXC_CTRLDUMP_COORD2( text ) { EXC_CTRLDUMP_ALIGN_INSTRM( 4 ); EXC_CTRLDUMP_DEC2( text "-x" ); EXC_CTRLDUMP_DEC2( text "-y" ); }
+#define EXC_CTRLDUMP_COORD4( text ) { EXC_CTRLDUMP_DEC4( text "-x" ); EXC_CTRLDUMP_DEC4( text "-y" ); }
+#define EXC_CTRLDUMP_SIZE4( text ) { EXC_CTRLDUMP_DEC4( text "-width" ); EXC_CTRLDUMP_DEC4( text "-height" ); }
+// read guid
+#define EXC_CTRLDUMP_PLAIN_GUID( text ) IMPL_EXC_CTRLDUMP_PLAIN_VALUE( XclGuid, lclAppendGuid, text )
+#define EXC_CTRLDUMP_GUID( text ) { EXC_CTRLDUMP_ALIGN_INSTRM( 4 ); EXC_CTRLDUMP_PLAIN_GUID( text ); }
+// read control type
+#define EXC_CTRLDUMP_CTRLTYPE( var, text ) \
+{ \
+ EXC_CTRLDUMP_ALIGN_INSTRM( 2 ); \
+ rInStrm >> var; \
+ t.Assign( " " text "=" ); lclAppendHex( t, var ); \
+ t.Append( " (" ); lclAppendControlType( t, var ); \
+ t.Append( ')' ); \
+ EXC_CTRLDUMP_PRINT(); \
+}
+// read character array, add to string, but do not print
+#define EXC_CTRLDUMP_RAWSTRING( var ) \
+{ \
+ t.Append( "='" ); \
+ if( var ) \
+ { \
+ EXC_CTRLDUMP_ALIGN_INSTRM( 4 ); \
+ ULONG nNextPos = rInStrm.Tell() + (var); \
+ if( var > 128 ) var = 128; \
+ sal_Char pc[ 129 ]; \
+ rInStrm.Read( pc, var ); pc[ var ] = '\0'; \
+ t.Append( pc ); \
+ rInStrm.Seek( nNextPos ); \
+ } \
+ t.Append( '\'' ); \
+}
+// read a string
+#define EXC_CTRLDUMP_STRING( var, text ) \
+{ \
+ t.Append( " " text ); \
+ EXC_CTRLDUMP_RAWSTRING( var ); \
+ EXC_CTRLDUMP_PRINT(); \
+}
+// read an array of strings
+#define EXC_CTRLDUMP_STRINGARRAY( total, count, text ) \
+{ \
+ ULONG nNextPos = rInStrm.Tell() + (total); \
+ for( sal_uInt32 nIdx = 0; (nIdx < (count)) && (rInStrm.Tell() < nNextPos); ++nIdx )\
+ { \
+ EXC_CTRLDUMP_ALIGN_INSTRM( 4 ); \
+ sal_uInt32 nLen; \
+ rInStrm >> nLen; \
+ nLen &= 0x7FFFFFFF; \
+ t.Append( " " text "[" ); \
+ lclAppendDec( t, nIdx + 1 ); \
+ t.Append( ']' ); \
+ EXC_CTRLDUMP_RAWSTRING( nLen ); \
+ } \
+ EXC_CTRLDUMP_PRINT(); \
+ rInStrm.Seek( nNextPos ); \
+}
+// read embedded font data
+#define EXC_CTRLDUMP_FONT( var, text ) \
+if( var ) \
+{ \
+ EXC_CTRLDUMP_PRINT(); \
+ XclGuid aGuid; rInStrm >> aGuid; \
+ rOutStrm << "embedded-font-guid=" << aGuid; \
+ if( aGuid == saStdFontGuid ) \
+ { \
+ rOutStrm << " (StdFont)\n"; \
+ EXC_CTRLDUMP_PLAIN_HEX1( "unknown1" ); \
+ EXC_CTRLDUMP_PLAIN_DEC1( "script-type" ); \
+ EXC_CTRLDUMP_PLAIN_HEX1( "unknown2" ); \
+ sal_uInt8 nFlags; \
+ EXC_CTRLDUMP_PLAIN_STARTFLAG( "font-style-flags" ); \
+ EXC_CTRLDUMP_ADDFLAG( 0x02, "italic" ); \
+ EXC_CTRLDUMP_ADDFLAG( 0x04, "underline" ); \
+ EXC_CTRLDUMP_ADDFLAG( 0x08, "strikeout" ); \
+ EXC_CTRLDUMP_ENDFLAG( 0xF1 ); \
+ EXC_CTRLDUMP_PLAIN_DEC2( "font-weight" ); \
+ EXC_CTRLDUMP_PLAIN_DEC4( "font-size" ); \
+/* font-size := pt*10000 + (1-((pt+1)%3))*2500 */ \
+ sal_uInt8 nLen; \
+ EXC_CTRLDUMP_PLAIN_DECVAR( nLen, "font-name-len" ); \
+ sal_Char* p = new sal_Char[ nLen + 1 ]; \
+ rInStrm.Read( p, nLen ); p[ nLen ] = '\0'; \
+ t.Append( " font-name='" ).Append( p ).Append( '\'' );\
+ delete [] p; \
+ EXC_CTRLDUMP_PRINT(); \
+ } \
+ else \
+ rOutStrm << " (*UNKNOWN*)\n"; \
+}
+// read image data
+#define EXC_CTRLDUMP_IMAGE( var, text ) \
+if( var ) \
+{ \
+ EXC_CTRLDUMP_PRINT(); \
+ XclGuid aGuid; rInStrm >> aGuid; \
+ rOutStrm << "embedded-" text "-guid=" << aGuid; \
+ if( aGuid == saStdPicGuid ) \
+ { \
+ rOutStrm << " (StdPict)\n"; \
+ EXC_CTRLDUMP_PLAIN_HEX2( "u1" ); \
+ EXC_CTRLDUMP_PLAIN_HEX2( "u2" ); \
+ sal_uInt32 nLen; \
+ EXC_CTRLDUMP_PLAIN_DECVAR( nLen, text "-len" ); \
+ rInStrm.SeekRel( nLen ); \
+ } \
+ else \
+ rOutStrm << " (*UNKNOWN*)\n"; \
+}
+// hex dump remaining or unknown data
+#define EXC_CTRLDUMP_REMAINING( nextpos ) \
+{ \
+ EXC_CTRLDUMP_ALIGN_INSTRM( 4 ); \
+ if( rInStrm.Tell() < (nextpos) ) \
+ { \
+ rOutStrm << " unknown-data=\n"; \
+ DumpBinary( rInStrm, ::std::min< ULONG >( (nextpos) - rInStrm.Tell(), 1024 ) );\
+ } \
+ rInStrm.Seek( nextpos ); \
+}
+
+// *** macros end ***
+
+void Biff8RecDumper::DumpControlContents( SvStream& rInStrm, sal_uInt16 nCtrlType )
+{
+ SvStream& rOutStrm = *pDumpStream;
+
+ if( nCtrlType == EXC_CTRL_PROGRESSBAR )
+ {
+ lclDumpControlType( rOutStrm, nCtrlType );
+ rOutStrm << '\n';
+
+ ByteString t; // "t" needed for macros
+ sal_uInt32 nFlags = 0; // "nFlags" needed for macros
+
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_DEC4( "width" );
+ EXC_CTRLDUMP_PLAIN_DEC4( "height" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_DECF( "min" );
+ EXC_CTRLDUMP_PLAIN_DECF( "max" );
+ EXC_CTRLDUMP_PLAIN_STARTFLAG( "flags1" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "vertical" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00010000, "smooth-scroll" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFEFFFE );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_HEX4( "unknown" );
+ EXC_CTRLDUMP_PLAIN_STARTFLAG( "flags2" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "border-single" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "3d-style" );
+ EXC_CTRLDUMP_ADDFLAGVALUE( 3, 8, "mouse-icon" );
+ EXC_CTRLDUMP_ADDFLAG( 0x2000, "ole-drop-manual" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFD800 );
+ return;
+ }
+
+ sal_uInt16 nSize = lclDumpControlHeader( rInStrm, rOutStrm, nCtrlType );
+ if( nSize > 0 )
+ {
+ ULONG nStartPos = rInStrm.Tell(); // for stream alignment macro
+ ByteString t; // "t" needed for macros
+ sal_uInt32 nFlags = 0; // "nFlags" needed for macros
+
+ bool bHasFontData = false;
+ sal_uInt32 nNameLen = 0;
+ sal_uInt32 nCaptionLen = 0;
+ sal_uInt32 nValueLen = 0;
+ sal_uInt32 nGroupNameLen = 0;
+ sal_uInt32 nTagLen = 0;
+ sal_uInt32 nTipLen = 0;
+ sal_uInt32 nCtrlIdLen = 0;
+ sal_uInt32 nCtrlSrcLen = 0;
+ sal_uInt32 nRowSrcLen = 0;
+ sal_uInt16 nPic = 0;
+ sal_uInt16 nIcon = 0;
+ sal_uInt16 nFont = 0;
+
+ switch( nCtrlType )
+ {
+ case EXC_CTRL_PUSHBUTTON:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "caption" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0010, "picpos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0020, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0040, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0080, "pic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0100, "accel" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0200, "notakefocus" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0400, "icon" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFF800 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x0002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x0004, 0x0000001B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "locked" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "opaque" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "wordwrap" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10000000, "autosize" );
+ EXC_CTRLDUMP_ENDFLAG( 0xEF7FFFF1 );
+
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_DECVARMASK( nCaptionLen, 0x7FFFFFFF, "caption-len" );
+ if( nCtrlFlags & 0x0010 ) EXC_CTRLDUMP_COORD2( "picpos" );
+ if( nCtrlFlags & 0x0040 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x0080 ) EXC_CTRLDUMP_HEXVAR( nPic, "pic" );
+ if( nCtrlFlags & 0x0100 ) EXC_CTRLDUMP_HEX2( "accel" );
+ if( nCtrlFlags & 0x0400 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_STRING( nCaptionLen, "caption" );
+ if( nCtrlFlags & 0x0020 ) EXC_CTRLDUMP_SIZE4( "size" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nPic, "pic" );
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ bHasFontData = true;
+ }
+ break;
+
+ case EXC_CTRL_TOGGLEBUTTON:
+ case EXC_CTRL_CHECKBOX:
+ case EXC_CTRL_OPTIONBUTTON:
+ case EXC_CTRL_TEXTBOX:
+ case EXC_CTRL_LISTBOX:
+ case EXC_CTRL_COMBOBOX:
+ case EXC_CTRL_REFEDIT:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "maxlen" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000010, "borderstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000020, "scrollbars" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000040, "style" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000080, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000100, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000200, "passwordchar" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000400, "listwidth" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000800, "boundcol" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00001000, "textcol" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00002000, "colcount" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00004000, "listrows" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00008000, "colwidth?" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00010000, "matchentry" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00020000, "liststyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00040000, "showdropbtn" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00100000, "dropbtnstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00200000, "multistate" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00400000, "value" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "caption" );
+ EXC_CTRLDUMP_ADDFLAG( 0x01000000, "picpos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x02000000, "bordercolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x04000000, "specialeff" );
+ EXC_CTRLDUMP_ADDFLAG( 0x08000000, "icon" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10000000, "pic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x20000000, "accel" );
+ EXC_CTRLDUMP_ENDFLAG( 0x40080000 ); // 0x80000000 always set?
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ EXC_CTRLDUMP_STARTFLAG( "2nd-content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "groupname" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFFFE );
+ sal_uInt32 nCtrlFlags2 = nFlags;
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x00000001, 0x2C80081B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "locked" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "opaque" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000400, "colheads" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000800, "intheight" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00001000, "matchreq" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00002000, "align" );
+ EXC_CTRLDUMP_ADDFLAGVALUE( 15, 4, "ime-mode" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00080000, "dragbehav" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00100000, "enterkeybehav" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00200000, "enterfieldbehav" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00400000, "tabkeybehav" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "wordwrap" );
+ EXC_CTRLDUMP_ADDFLAG( 0x04000000, "selmargin" );
+ EXC_CTRLDUMP_ADDFLAG( 0x08000000, "autowordsel" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10000000, "autosize" );
+ EXC_CTRLDUMP_ADDFLAG( 0x20000000, "hidesel" );
+ EXC_CTRLDUMP_ADDFLAG( 0x40000000, "autotab" );
+ EXC_CTRLDUMP_ADDFLAG( 0x80000000, "multiline" );
+ EXC_CTRLDUMP_ENDFLAG( 0x030043F1 );
+
+ if( nCtrlFlags & 0x00000002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+ if( nCtrlFlags & 0x00000004 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x00000008 ) EXC_CTRLDUMP_DEC4( "maxlen" );
+ if( nCtrlFlags & 0x00000010 ) EXC_CTRLDUMP_DEC1( "borderstyle" );
+ if( nCtrlFlags & 0x00000020 ) EXC_CTRLDUMP_DEC1( "scrollbars" );
+ if( nCtrlFlags & 0x00000040 ) EXC_CTRLDUMP_DEC1( "style" );
+ if( nCtrlFlags & 0x00000080 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x00000200 ) EXC_CTRLDUMP_HEX2( "passwordchar" );
+ if( nCtrlFlags & 0x00000400 ) EXC_CTRLDUMP_DEC4( "listwidth" );
+ if( nCtrlFlags & 0x00000800 ) EXC_CTRLDUMP_DEC2( "boundcol" );
+ if( nCtrlFlags & 0x00001000 ) EXC_CTRLDUMP_DEC2( "textcol" );
+ if( nCtrlFlags & 0x00002000 ) EXC_CTRLDUMP_DEC2( "colcount" );
+ if( nCtrlFlags & 0x00004000 ) EXC_CTRLDUMP_DEC2( "listrows" );
+ if( nCtrlFlags & 0x00008000 ) EXC_CTRLDUMP_DEC2( "colwidth?" );
+ if( nCtrlFlags & 0x00010000 ) EXC_CTRLDUMP_DEC1( "matchentry" );
+ if( nCtrlFlags & 0x00020000 ) EXC_CTRLDUMP_DEC1( "liststyle" );
+ if( nCtrlFlags & 0x00040000 ) EXC_CTRLDUMP_DEC1( "showdropbtn" );
+ if( nCtrlFlags & 0x00100000 ) EXC_CTRLDUMP_DEC1( "dropbtnstyle" );
+ if( nCtrlFlags & 0x00200000 ) EXC_CTRLDUMP_DEC1( "multistate" );
+ if( nCtrlFlags & 0x00400000 ) EXC_CTRLDUMP_DECVARMASK( nValueLen, 0x7FFFFFFF, "value-len" );
+ if( nCtrlFlags & 0x00800000 ) EXC_CTRLDUMP_DECVARMASK( nCaptionLen, 0x7FFFFFFF, "caption-len" );
+ if( nCtrlFlags & 0x01000000 ) EXC_CTRLDUMP_COORD2( "picpos" );
+ if( nCtrlFlags & 0x02000000 ) EXC_CTRLDUMP_HEX4( "bordercolor" );
+ if( nCtrlFlags & 0x04000000 ) EXC_CTRLDUMP_DEC4( "specialeff" );
+ if( nCtrlFlags & 0x08000000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+ if( nCtrlFlags & 0x10000000 ) EXC_CTRLDUMP_HEXVAR( nPic, "pic" );
+ if( nCtrlFlags & 0x20000000 ) EXC_CTRLDUMP_HEX1( "accel" );
+ if( nCtrlFlags2 & 0x00000001 ) EXC_CTRLDUMP_DECVARMASK( nGroupNameLen, 0x7FFFFFFF, "groupname-len" );
+
+ if( nCtrlFlags & 0x00000100 ) EXC_CTRLDUMP_SIZE4( "size" );
+ if( nCtrlFlags & 0x00400000 ) EXC_CTRLDUMP_STRING( nValueLen, "value" );
+ if( nCtrlFlags & 0x00800000 ) EXC_CTRLDUMP_STRING( nCaptionLen, "caption" );
+ if( nCtrlFlags2 & 0x00000001 ) EXC_CTRLDUMP_STRING( nGroupNameLen, "groupname" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ EXC_CTRLDUMP_IMAGE( nPic, "pic" );
+ bHasFontData = true;
+ }
+ break;
+
+ case EXC_CTRL_LABEL:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "caption" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0010, "picpos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0020, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0040, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0080, "bordercolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0100, "borderstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0200, "specialeff" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0400, "pic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0800, "accel" );
+ EXC_CTRLDUMP_ADDFLAG( 0x1000, "icon" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFE000 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x0002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x0004, 0x0080001B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "locked" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "opaque" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "wordwrap" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10000000, "autosize" );
+ EXC_CTRLDUMP_ENDFLAG( 0xEF7FFFF0 ); // 0x00000001 always set?
+
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_DECVARMASK( nCaptionLen, 0x7FFFFFFF, "caption-len" );
+ if( nCtrlFlags & 0x0010 ) EXC_CTRLDUMP_COORD2( "picpos" );
+ if( nCtrlFlags & 0x0040 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x0080 ) EXC_CTRLDUMP_HEX4( "bordercolor" );
+ if( nCtrlFlags & 0x0100 ) EXC_CTRLDUMP_HEX2( "borderstyle" );
+ if( nCtrlFlags & 0x0200 ) EXC_CTRLDUMP_HEX2( "specialeff" );
+ if( nCtrlFlags & 0x0400 ) EXC_CTRLDUMP_HEXVAR( nPic, "pic" );
+ if( nCtrlFlags & 0x0800 ) EXC_CTRLDUMP_HEX2( "accel" );
+ if( nCtrlFlags & 0x1000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_STRING( nCaptionLen, "caption" );
+ if( nCtrlFlags & 0x0020 ) EXC_CTRLDUMP_SIZE4( "size" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nPic, "pic" );
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ bHasFontData = true;
+ }
+ break;
+
+ case EXC_CTRL_SPINBUTTON:
+ case EXC_CTRL_SCROLLBAR:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000010, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000100, "unknown1" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000200, "unknown2" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000400, "unknown3" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000020, "min" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000040, "max" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000080, "value" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000800, "step" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00001000, "page-step" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00002000, "orient" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00004000, "prop-thumb" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00008000, "delay" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00010000, "icon" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFE0000 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x00000001 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x00000002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x00000004, 0x0000001B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "locked" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "opaque" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10000000, "autosize" );
+ EXC_CTRLDUMP_ENDFLAG( 0xEFFFFFF1 );
+
+ if( nCtrlFlags & 0x00000010 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x00000020 ) EXC_CTRLDUMP_DEC4( "min" );
+ if( nCtrlFlags & 0x00000040 ) EXC_CTRLDUMP_DEC4( "max" );
+ if( nCtrlFlags & 0x00000080 ) EXC_CTRLDUMP_DEC4( "value" );
+ if( nCtrlFlags & 0x00000100 ) EXC_CTRLDUMP_HEX4( "unknown1" );
+ if( nCtrlFlags & 0x00000200 ) EXC_CTRLDUMP_HEX4( "unknown2" );
+ if( nCtrlFlags & 0x00000400 ) EXC_CTRLDUMP_HEX4( "unknown3" );
+ if( nCtrlFlags & 0x00000800 ) EXC_CTRLDUMP_DEC4( "step" );
+ if( nCtrlFlags & 0x00001000 ) EXC_CTRLDUMP_DEC4( "page-step" );
+ if( nCtrlFlags & 0x00002000 ) EXC_CTRLDUMP_DEC4( "orient" );
+ if( nCtrlFlags & 0x00004000 ) EXC_CTRLDUMP_DEC4( "prop-thumb" );
+ if( nCtrlFlags & 0x00008000 ) EXC_CTRLDUMP_DEC4( "delay" );
+ if( nCtrlFlags & 0x00010000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+
+ if( nCtrlFlags & 0x00000008 ) EXC_CTRLDUMP_SIZE4( "size" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ }
+ break;
+
+ case EXC_CTRL_IMAGE:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "autosize" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "bordercolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0010, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0020, "borderstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0040, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0080, "picsizemode" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0100, "speceffect" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0200, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0400, "pic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0800, "picalign" );
+ EXC_CTRLDUMP_ADDFLAG( 0x1000, "pictiling" );
+ EXC_CTRLDUMP_ADDFLAG( 0x2000, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x4000, "icon" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFF8003 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_HEX4( "bordercolor" );
+ if( nCtrlFlags & 0x0010 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+ if( nCtrlFlags & 0x0020 ) EXC_CTRLDUMP_HEX1( "borderstyle" );
+ if( nCtrlFlags & 0x0040 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x0080 ) EXC_CTRLDUMP_DEC1( "picsizemode" );
+ if( nCtrlFlags & 0x0100 ) EXC_CTRLDUMP_HEX1( "speceffect" );
+ if( nCtrlFlags & 0x0400 ) EXC_CTRLDUMP_HEXVAR( nPic, "pic" );
+ if( nCtrlFlags & 0x0800 ) EXC_CTRLDUMP_HEX1( "picalign" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x2000, 0x0000001B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "opaque" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFFF5 );
+
+ if( nCtrlFlags & 0x4000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+
+ if( nCtrlFlags & 0x0200 ) EXC_CTRLDUMP_SIZE4( "size" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nPic, "pic" );
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ }
+ break;
+
+ case EXC_CTRL_TABSTRIP:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "selected-tab" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000010, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000020, "caption-arr-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000040, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000100, "taborientation" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000200, "tabstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000400, "multirow" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000800, "fixed-width" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00001000, "fixed-height" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00008000, "infotip-arr-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00020000, "id-arr-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00040000, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00080000, "last-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00200000, "unknown-arr-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00400000, "tab-count" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "shortcut-arr-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x01000000, "icon" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFE116088 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ sal_uInt32 nTabCount = 0;
+ sal_uInt32 nIdArrLen = 0;
+ sal_uInt32 nUnknownArrLen = 0;
+ sal_uInt32 nShortArrLen = 0;
+
+ if( nCtrlFlags & 0x00000001 ) EXC_CTRLDUMP_DEC4( "selected-tab" ); // size ok?
+ if( nCtrlFlags & 0x00000002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+ if( nCtrlFlags & 0x00000004 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x00000020 ) EXC_CTRLDUMP_HEXVAR( nCaptionLen, "caption-arr-len" );
+ if( nCtrlFlags & 0x00000040 ) EXC_CTRLDUMP_DEC1( "mouseptr" ); // size ok?
+ if( nCtrlFlags & 0x00000100 ) EXC_CTRLDUMP_DEC4( "taborientation" ); // size ok?
+ if( nCtrlFlags & 0x00000200 ) EXC_CTRLDUMP_DEC4( "tabstyle" ); // size ok?
+ if( nCtrlFlags & 0x00000800 ) EXC_CTRLDUMP_DEC4( "fixed-width" );
+ if( nCtrlFlags & 0x00001000 ) EXC_CTRLDUMP_DEC4( "fixed-height" );
+ if( nCtrlFlags & 0x00008000 ) EXC_CTRLDUMP_HEXVAR( nTipLen, "infotip-arr-len" );
+ if( nCtrlFlags & 0x00020000 ) EXC_CTRLDUMP_HEXVAR( nIdArrLen, "id-arr-len" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x00040000, 0x0000001B );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFFFD );
+
+ if( nCtrlFlags & 0x00080000 ) EXC_CTRLDUMP_DEC4( "last-id" );
+ if( nCtrlFlags & 0x00200000 ) EXC_CTRLDUMP_HEXVAR( nUnknownArrLen, "unknown-arr-len" );
+ if( nCtrlFlags & 0x00400000 ) EXC_CTRLDUMP_DECVAR( nTabCount, "tab-count" );
+ if( nCtrlFlags & 0x00800000 ) EXC_CTRLDUMP_HEXVAR( nShortArrLen, "shortcut-arr-len" );
+ if( nCtrlFlags & 0x01000000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+
+ if( nCtrlFlags & 0x00000010 ) EXC_CTRLDUMP_SIZE4( "size" );
+ if( nCtrlFlags & 0x00000020 ) EXC_CTRLDUMP_STRINGARRAY( nCaptionLen, nTabCount, "caption" );
+ if( nCtrlFlags & 0x00008000 ) EXC_CTRLDUMP_STRINGARRAY( nTipLen, nTabCount, "infotip" );
+ if( nCtrlFlags & 0x00020000 ) EXC_CTRLDUMP_STRINGARRAY( nIdArrLen, nTabCount, "id" );
+ if( nCtrlFlags & 0x00200000 ) EXC_CTRLDUMP_STRINGARRAY( nUnknownArrLen, nTabCount, "unknown" );
+ if( nCtrlFlags & 0x00800000 ) EXC_CTRLDUMP_STRINGARRAY( nShortArrLen, nTabCount, "shortcut" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ bHasFontData = true;
+ }
+ break;
+
+ case EXC_CTRL_USERFORM:
+ case EXC_CTRL_FRAME:
+ case EXC_CTRL_MULTIPAGE:
+ case EXC_CTRL_PAGE:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "backcolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000004, "forecolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000008, "last-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000040, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000080, "borderstyle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000100, "mouseptr" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000200, "scrollbars" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000400, "size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000800, "scrollsize" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00001000, "scrollpos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00008000, "icon" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00010000, "cycle" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00020000, "speceffect" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00040000, "bordercolor" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00080000, "caption" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00100000, "font" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00200000, "pic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00400000, "zoom" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00800000, "picalign" );
+ EXC_CTRLDUMP_ADDFLAG( 0x01000000, "pictiling" );
+ EXC_CTRLDUMP_ADDFLAG( 0x02000000, "picsizemode" );
+ EXC_CTRLDUMP_ADDFLAG( 0x04000000, "typeinfover" );
+ EXC_CTRLDUMP_ADDFLAG( 0x08000000, "drawbuffer" );
+ EXC_CTRLDUMP_ENDFLAG( 0xF0006031 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x00000002 ) EXC_CTRLDUMP_HEX4( "backcolor" );
+ if( nCtrlFlags & 0x00000004 ) EXC_CTRLDUMP_HEX4( "forecolor" );
+ if( nCtrlFlags & 0x00000008 ) EXC_CTRLDUMP_DEC4( "last-id" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x00000040, 0x00000002 );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "enabled" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFFFD );
+
+ if( nCtrlFlags & 0x00000080 ) EXC_CTRLDUMP_HEX1( "borderstyle" );
+ if( nCtrlFlags & 0x00000100 ) EXC_CTRLDUMP_DEC1( "mouseptr" );
+ if( nCtrlFlags & 0x00000200 ) EXC_CTRLDUMP_HEX1( "scrollbars" );
+ if( nCtrlFlags & 0x00008000 ) EXC_CTRLDUMP_HEXVAR( nIcon, "icon" );
+ if( nCtrlFlags & 0x00010000 ) EXC_CTRLDUMP_DEC1( "cycle" );
+ if( nCtrlFlags & 0x00020000 ) EXC_CTRLDUMP_HEX1( "speceffect" );
+ if( nCtrlFlags & 0x00040000 ) EXC_CTRLDUMP_HEX4( "bordercolor" );
+ if( nCtrlFlags & 0x00080000 ) EXC_CTRLDUMP_DECVARMASK( nCaptionLen, 0x7FFFFFFF, "caption-len" );
+ if( nCtrlFlags & 0x00100000 ) EXC_CTRLDUMP_HEXVAR( nFont, "font" );
+ if( nCtrlFlags & 0x00200000 ) EXC_CTRLDUMP_HEXVAR( nPic, "pic" );
+ if( nCtrlFlags & 0x00400000 ) EXC_CTRLDUMP_DEC4( "zoom" );
+ if( nCtrlFlags & 0x00800000 ) EXC_CTRLDUMP_HEX1( "picalign" );
+ if( nCtrlFlags & 0x02000000 ) EXC_CTRLDUMP_DEC1( "picsizemode" );
+ if( nCtrlFlags & 0x04000000 ) EXC_CTRLDUMP_DEC4( "typeinfover" );
+ if( nCtrlFlags & 0x08000000 ) EXC_CTRLDUMP_DEC4( "drawbuffer" );
+
+ if( nCtrlFlags & 0x00000400 ) EXC_CTRLDUMP_SIZE4( "size" );
+ if( nCtrlFlags & 0x00000800 ) EXC_CTRLDUMP_SIZE4( "scrollsize" );
+ if( nCtrlFlags & 0x00001000 ) EXC_CTRLDUMP_COORD4( "scrollpos" );
+ if( nCtrlFlags & 0x00080000 ) EXC_CTRLDUMP_STRING( nCaptionLen, "caption" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ EXC_CTRLDUMP_FONT( nFont, "font" );
+ EXC_CTRLDUMP_IMAGE( nIcon, "icon" );
+ EXC_CTRLDUMP_IMAGE( nPic, "pic" );
+ }
+ break;
+
+ case EXC_CTRL_FONTDATA:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x01, "font-name" );
+ EXC_CTRLDUMP_ADDFLAG( 0x02, "font-style" );
+ EXC_CTRLDUMP_ADDFLAG( 0x04, "font-size" );
+ EXC_CTRLDUMP_ADDFLAG( 0x10, "language-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x40, "align" );
+ EXC_CTRLDUMP_ADDFLAG( 0x80, "font-weight" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFF08 ); // 0x20 always set?
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_DECVARMASK( nNameLen, 0x7FFFFFFF, "font-name-len" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "font-style-flags", nCtrlFlags & 0x0002, 0x40000000 );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "bold" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "italic" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "underline" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "strikeout" );
+ EXC_CTRLDUMP_ADDFLAG( 0x2000, "sunken" );
+ EXC_CTRLDUMP_ENDFLAG( 0xBFFFDFF0 ); // 0x40000000 always set?
+
+ if( nCtrlFlags & 0x0004 ) EXC_CTRLDUMP_DEC4( "font-size" );
+ if( nCtrlFlags & 0x0010 ) EXC_CTRLDUMP_HEX2( "language-id" );
+ if( nCtrlFlags & 0x0040 )
+ {
+ EXC_CTRLDUMP_ALIGN_INSTRM( 2 );
+ sal_uInt16 nAlign; rInStrm >> nAlign;
+ t += " align="; lclAppendDec( t, nAlign );
+ switch( nAlign )
+ {
+ case 1: t += "=left"; break;
+ case 2: t += "=right"; break;
+ case 3: t += "=center"; break;
+ default: t += "=!unknown!";
+ }
+ EXC_CTRLDUMP_PRINT();
+ }
+ if( nCtrlFlags & 0x0080 ) EXC_CTRLDUMP_DEC2( "font-weight" );
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_STRING( nNameLen, "font-name" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+ }
+ break;
+
+ case EXC_CTRL_ADDDATA:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "guid1" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "guid2" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "guid4" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0040, "unknown1" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFFFFB4 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ if( nCtrlFlags & 0x0040 ) EXC_CTRLDUMP_HEX4( "unknown1" );
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_GUID( "guid1" );
+ if( nCtrlFlags & 0x0002 ) EXC_CTRLDUMP_GUID( "guid2" );
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_GUID( "guid4" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+ }
+ break;
+
+ case EXC_CTRL_FRAMECHILD:
+ {
+ EXC_CTRLDUMP_STARTFLAG( "content-flags" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0001, "name-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0002, "tag-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0004, "storage-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0008, "helpcontext-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0010, "option" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0020, "substream-len" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0040, "tabpos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0080, "type" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0100, "pos" );
+ EXC_CTRLDUMP_ADDFLAG( 0x0800, "tiptext" );
+ EXC_CTRLDUMP_ADDFLAG( 0x1000, "ctrl-id" );
+ EXC_CTRLDUMP_ADDFLAG( 0x2000, "ctrl-source" );
+ EXC_CTRLDUMP_ADDFLAG( 0x4000, "row-source" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFF8600 );
+ sal_uInt32 nCtrlFlags = nFlags;
+
+ sal_uInt32 nStorageId = 0;
+ sal_uInt32 nSubStrmLen = 0;
+ sal_uInt16 nChildType = EXC_CTRL_UNKNOWN;
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_DECVARMASK( nNameLen, 0x7FFFFFFF, "name-len" );
+ if( nCtrlFlags & 0x0002 ) EXC_CTRLDUMP_DECVARMASK( nTagLen, 0x7FFFFFFF, "tag-len" );
+ if( nCtrlFlags & 0x0004 ) EXC_CTRLDUMP_PLAIN_DECVAR( nStorageId, "storage-id" );
+ if( nCtrlFlags & 0x0008 ) EXC_CTRLDUMP_PLAIN_DEC4( "helpcontext-id" );
+
+ EXC_CTRLDUMP_STARTOPTFLAG( "option-flags", nCtrlFlags & 0x0010, 0x00000033 );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000001, "tabstop" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00000002, "visible" );
+ EXC_CTRLDUMP_ADDFLAG( 0x00040000, "container" );
+ EXC_CTRLDUMP_ENDFLAG( 0xFFFBFFFC );
+
+ if( nCtrlFlags & 0x0020 ) EXC_CTRLDUMP_HEXVAR( nSubStrmLen, "substream-len" );
+ if( nCtrlFlags & 0x0040 ) EXC_CTRLDUMP_DEC2( "tabpos" );
+ if( nCtrlFlags & 0x0080 ) EXC_CTRLDUMP_CTRLTYPE( nChildType, "type" );
+ if( nCtrlFlags & 0x0800 ) EXC_CTRLDUMP_DECVARMASK( nTipLen, 0x7FFFFFFF, "infotip-len" );
+ if( nCtrlFlags & 0x1000 ) EXC_CTRLDUMP_DECVARMASK( nCtrlIdLen, 0x7FFFFFFF, "ctrl-id-len" );
+ if( nCtrlFlags & 0x2000 ) EXC_CTRLDUMP_DECVARMASK( nCtrlSrcLen, 0x7FFFFFFF, "ctrl-source-len" );
+ if( nCtrlFlags & 0x4000 ) EXC_CTRLDUMP_DECVARMASK( nRowSrcLen, 0x7FFFFFFF, "row-source-len" );
+
+ if( nCtrlFlags & 0x0001 ) EXC_CTRLDUMP_STRING( nNameLen, "name" );
+ if( nCtrlFlags & 0x0002 ) EXC_CTRLDUMP_STRING( nTagLen, "tag" );
+ if( nCtrlFlags & 0x0100 ) EXC_CTRLDUMP_COORD4( "pos" );
+ if( nCtrlFlags & 0x0800 ) EXC_CTRLDUMP_STRING( nTipLen, "infotip" );
+ if( nCtrlFlags & 0x1000 ) EXC_CTRLDUMP_STRING( nCtrlIdLen, "ctrl-id" );
+ if( nCtrlFlags & 0x2000 ) EXC_CTRLDUMP_STRING( nCtrlSrcLen, "ctrl-source" );
+ if( nCtrlFlags & 0x4000 ) EXC_CTRLDUMP_STRING( nRowSrcLen, "row-source" );
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+
+ if( (nCtrlFlags & 0x0080) && (nChildType != EXC_CTRL_UNKNOWN) )
+ {
+ if( (nFlags & 0x00040000) && (nStorageId > 0) )
+ maCtrlStorages.push_back( XclDumpCtrlPortion( nStorageId, nChildType ) );
+ if( (nCtrlFlags & 0x0020) && (nSubStrmLen > 0) )
+ maCtrlPortions.push_back( XclDumpCtrlPortion( nSubStrmLen, nChildType ) );
+ }
+ }
+ break;
+
+ default:
+ EXC_CTRLDUMP_REMAINING( nStartPos + nSize );
+ }
+
+ // font data
+ if( bHasFontData )
+ DumpControlContents( rInStrm, EXC_CTRL_FONTDATA );
+ }
+}
+
+// ============================================================================
+//
+// S T R E A M S
+//
+// ============================================================================
+
+void Biff8RecDumper::DumpBinaryStream( SotStorageRef xStrg, const String& rStrmName, const String& rStrgPath )
+{
+ SotStorageStreamRef xInStrm = OpenStream( xStrg, rStrmName );
+ if( !xInStrm || !pDumpStream ) return;
+
+ XclDumpStreamHeader aStrmHeader( *xInStrm, *pDumpStream, rStrmName, rStrgPath );
+ DumpBinary( *xInStrm );
+ (*pDumpStream) << "\n";
+}
+
+void Biff8RecDumper::DumpTextStream( SotStorageRef xStrg, const String& rStrmName, const String& rStrgPath )
+{
+ SotStorageStreamRef xInStrm = OpenStream( xStrg, rStrmName );
+ if( !xInStrm || !pDumpStream ) return;
+
+ XclDumpStreamHeader aStrmHeader( *xInStrm, *pDumpStream, rStrmName, rStrgPath );
+ while( xInStrm->Tell() < aStrmHeader.GetStreamLen() )
+ {
+ ByteString aLine;
+ xInStrm->ReadLine( aLine );
+ lclDumpString( *pDumpStream, aLine );
+ (*pDumpStream) << "\n";
+ }
+ (*pDumpStream) << "\n";
+}
+
+void Biff8RecDumper::DumpRecordStream( SotStorageRef xStrg, const String& rStrmName, const String& rStrgPath )
+{
+ SotStorageStreamRef xInStrm = OpenStream( xStrg, rStrmName );
+ if( !xInStrm || !pDumpStream ) return;
+
+ XclDumpStreamHeader aStrmHeader( *xInStrm, *pDumpStream, rStrmName, rStrgPath );
+
+ XclImpStream* pOldStream = pIn;
+ pIn = new XclImpStream( *xInStrm, GetRoot() );
+ XclImpStream& rIn = *pIn;
+ if( pOldStream )
+ rIn.CopyDecrypterFrom( *pOldStream );
+
+ // -- dump from here --
+ UINT16 nId;
+ BOOL bLoop = TRUE;
+
+ while( bLoop && rIn.StartNextRecord() )
+ {
+ nId = rIn.GetRecId();
+ if( HasModeDump( nId ) )
+ RecDump( TRUE );
+
+ bLoop = (nId != 0x000A);
+ }
+
+ delete pIn;
+ pIn = pOldStream;
+}
+
+void Biff8RecDumper::DumpCtlsStream()
+{
+ SotStorageStreamRef xInStrm = OpenStream( EXC_STREAM_CTLS );
+ if( !xInStrm || !pDumpStream ) return;
+
+ SvStream& rInStrm = *xInStrm;
+ SvStream& rOutStrm = *pDumpStream;
+ XclDumpStreamHeader aStrmHeader( rInStrm, rOutStrm, EXC_STREAM_CTLS, EMPTY_STRING );
+
+ for( StrmPortionMap::const_iterator aIt = maCtlsPosMap.begin(), aEnd = maCtlsPosMap.end(); aIt != aEnd; ++aIt )
+ {
+ ULONG nCtrlPos = static_cast< ULONG >( aIt->first );
+ ULONG nCtrlEnd = nCtrlPos + static_cast< ULONG >( aIt->second );
+ if( nCtrlEnd <= aStrmHeader.GetStreamLen() )
+ {
+ // stream position
+ ULONG nStartPos = nCtrlPos; // for stream alignment macro
+ rInStrm.Seek( nStartPos );
+
+ ByteString t( "\npos=" ); __AddHex( t, aIt->first );
+ t.Append( " len=" ); __AddHex( t, aIt->second );
+ rOutStrm << t.GetBuffer() << " ";
+
+ // control type
+ sal_uInt16 nCtrlType = lclDumpControlGuid( rInStrm, rOutStrm );
+ rOutStrm << "\n";
+
+ // control contents
+ if( nCtrlType != EXC_CTRL_UNKNOWN )
+ DumpControlContents( rInStrm, nCtrlType );
+
+ // remaining unknown data
+ EXC_CTRLDUMP_REMAINING( nCtrlEnd );
+ rOutStrm << "\n";
+ }
+ }
+}
+
+void Biff8RecDumper::DumpControlFrameStream( SotStorageRef xInStrg, sal_uInt16 nCtrlType, const String& rStrgPath )
+{
+ static const String saStrmName( sal_Unicode( 'f' ) );
+
+ SotStorageStreamRef xInStrm = OpenStream( xInStrg, saStrmName );
+ if( !xInStrm || !pDumpStream ) return;
+
+ SvStream& rInStrm = *xInStrm;
+ SvStream& rOutStrm = *pDumpStream;
+ XclDumpStreamHeader aStrmHeader( rInStrm, rOutStrm, saStrmName, rStrgPath );
+
+ if( aStrmHeader.GetStreamLen() > 0 )
+ {
+ ByteString t; // "t" needed for macros
+
+ rOutStrm << "header-record\n";
+ DumpControlContents( rInStrm, nCtrlType );
+ rOutStrm << "\n";
+
+ if( nCtrlType == EXC_CTRL_USERFORM )
+ {
+ rOutStrm << "add-records\n";
+ sal_uInt16 nAddCount;
+ EXC_CTRLDUMP_PLAIN_DECVAR( nAddCount, "count" );
+ EXC_CTRLDUMP_PRINT();
+ rOutStrm << "\n";
+
+ for( sal_uInt16 nAdd = 0; (nAdd < nAddCount) && (rInStrm.Tell() < aStrmHeader.GetStreamLen()); ++nAdd )
+ {
+ DumpControlContents( rInStrm, EXC_CTRL_ADDDATA );
+ rOutStrm << "\n";
+ }
+ }
+
+ rOutStrm << "children-records\n";
+ sal_uInt32 nRecCount, nTotalSize;
+ EXC_CTRLDUMP_PLAIN_DECVAR( nRecCount, "count" );
+ EXC_CTRLDUMP_PLAIN_HEXVAR( nTotalSize, "total-size" );
+ if( nTotalSize > 0 )
+ {
+ EXC_CTRLDUMP_PLAIN_HEX4( "header-unknown" );
+ rOutStrm << "\n";
+
+ for( sal_uInt32 nRec = 0; (nRec < nRecCount) && (rInStrm.Tell() < aStrmHeader.GetStreamLen()); ++nRec )
+ {
+ DumpControlContents( rInStrm, EXC_CTRL_FRAMECHILD );
+ rOutStrm << "\n";
+ }
+ }
+ else
+ rOutStrm << "\n";
+
+ if( rInStrm.Tell() < aStrmHeader.GetStreamLen() )
+ {
+ rOutStrm << "remaining=\n";
+ DumpBinary( rInStrm );
+ rOutStrm << "\n";
+ }
+ }
+}
+
+void Biff8RecDumper::DumpControlObjectsStream( SotStorageRef xInStrg, const String& rStrgPath )
+{
+ static const String saStrmName( sal_Unicode( 'o' ) );
+
+ SotStorageStreamRef xInStrm = OpenStream( xInStrg, saStrmName );
+ if( !xInStrm || !pDumpStream ) return;
+
+ SvStream& rInStrm = *xInStrm;
+ SvStream& rOutStrm = *pDumpStream;
+ XclDumpStreamHeader aStrmHeader( rInStrm, rOutStrm, saStrmName, rStrgPath );
+
+ if( aStrmHeader.GetStreamLen() > 0 )
+ {
+ ULONG nStrmPos = 0;
+ for( XclDumpCtrlPortionVec::const_iterator aIt = maCtrlPortions.begin(), aEnd = maCtrlPortions.end(); aIt != aEnd; ++aIt )
+ {
+ rInStrm.Seek( nStrmPos );
+ DumpControlContents( rInStrm, aIt->second );
+ rOutStrm << "\n";
+ nStrmPos += aIt->first;
+ }
+
+ if( rInStrm.Tell() < aStrmHeader.GetStreamLen() )
+ {
+ rOutStrm << "remaining=\n";
+ DumpBinary( rInStrm );
+ rOutStrm << "\n";
+ }
+ }
+}
+
+// ============================================================================
+//
+// S T O R A G E S
+//
+// ============================================================================
+
+void Biff8RecDumper::DumpAnyStorage( SotStorageRef xParentStrg, const String& rStrgName, const String& rStrgPath )
+{
+ SotStorageRef xInStrg = OpenStorage( xParentStrg, rStrgName );
+ if( !xInStrg || !pDumpStream ) return;
+
+ XclDumpStorageHeader aStrgHeader( *xInStrg, *pDumpStream, rStrgPath );
+}
+
+void Biff8RecDumper::DumpUserFormStorage( SotStorageRef xParentStrg, const String& rStrgName, sal_uInt16 nCtrlType, const String& rStrgPath )
+{
+ SotStorageRef xInStrg = OpenStorage( xParentStrg, rStrgName );
+ if( !xInStrg || !pDumpStream ) return;
+
+ XclDumpStorageHeader aStrgHeader( *xInStrg, *pDumpStream, rStrgPath );
+
+ // streams
+ maCtrlStorages.clear();
+ maCtrlPortions.clear();
+ DumpControlFrameStream( xInStrg, nCtrlType, rStrgPath );
+ DumpControlObjectsStream( xInStrg, rStrgPath );
+ DumpTextStream( xInStrg, CREATE_STRING( "\003VBFrame" ), rStrgPath );
+
+ // frame substorages
+ XclDumpCtrlPortionVec aCtrlStorages( maCtrlStorages ); // make local copy, maCtrlStorages is reused in loop
+ for( XclDumpCtrlPortionVec::const_iterator aIt = aCtrlStorages.begin(), aEnd = aCtrlStorages.end(); aIt != aEnd; ++aIt )
+ {
+ sal_uInt32 nStorageId = aIt->first;
+ String aSubName( sal_Unicode( 'i' ) );
+ if( nStorageId < 10 )
+ aSubName.Append( sal_Unicode( '0' ) );
+ aSubName.Append( String::CreateFromInt32( static_cast< sal_Int32 >( nStorageId ) ) );
+
+ String aPath( rStrgPath );
+ aPath.Append( sal_Unicode( '/' ) ).Append( rStrgName );
+
+ DumpUserFormStorage( xInStrg, aSubName, aIt->second, aPath );
+ }
+}
+
+void Biff8RecDumper::DumpVbaProjectStorage()
+{
+ SotStorageRef xInStrg = OpenStorage( EXC_STORAGE_VBA_PROJECT );
+ if( !xInStrg || !pDumpStream ) return;
+
+ XclDumpStorageHeader aStrgHeader( *xInStrg, *pDumpStream, EMPTY_STRING );
+ // PROJECT substream
+ DumpTextStream( xInStrg, CREATE_STRING( "PROJECT" ), EXC_STORAGE_VBA_PROJECT );
+ // VBA storage
+ DumpAnyStorage( xInStrg, EXC_STORAGE_VBA, EXC_STORAGE_VBA_PROJECT );
+ // user forms
+ SvStorageInfoList aInfoList;
+ xInStrg->FillInfoList( &aInfoList );
+ for( ULONG nInfo = 0; nInfo < aInfoList.Count(); ++nInfo )
+ {
+ SvStorageInfo& rInfo = aInfoList.GetObject( nInfo );
+ if( rInfo.IsStorage() && (rInfo.GetName() != EXC_STORAGE_VBA) )
+ DumpUserFormStorage( xInStrg, rInfo.GetName(), EXC_CTRL_USERFORM, EXC_STORAGE_VBA_PROJECT );
+ }
+}
+
+// ============================================================================
+//
+// ============================================================================
+
+const sal_Char* Biff8RecDumper::GetBlanks( const UINT16 nNumOfBlanks )
+{
+ DBG_ASSERT( pBlankLine, "-Biff8RecDumper::GetBlanks(): nicht so schnell mein Freund!" );
+ DBG_ASSERT( nNumOfBlanks <= nLenBlankLine,
+ "+Biff8RecDumper::GetBlanks(): So viel kannst Du nicht von mir verlangen!" );
+
+ return pBlankLine + ( ( nNumOfBlanks <= nLenBlankLine )? ( nLenBlankLine - nNumOfBlanks ) : 0 );
+}
+
+
+BOOL Biff8RecDumper::IsLineEnd( const sal_Char c, sal_Char& rNext, SvStream& rIn, INT32& rLeft )
+{
+ static const sal_Char cNL = '\n';
+ static const sal_Char cRET = '\r';
+
+ if( IsEndOfLine( c ) )
+ {
+ sal_Char cDouble = ( c == cNL )? cRET : cNL;
+
+ if( rNext == cDouble )
+ {
+ rIn >> rNext;
+ rLeft--;
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+_KEYWORD Biff8RecDumper::GetKeyType( const ByteString& r )
+{
+ ByteString t( r );
+ _KEYWORD e;
+
+ t.ToUpperAscii();
+
+ if( t == "SKIPDUMP" )
+ e = Skipdump;
+ else if( t == "SKIPOFFSET" )
+ e = SkipOffset;
+ else if( t == "READCONTRECS" )
+ e = ReadContRecs;
+ else if( t == "NOWARNINGS" )
+ e = NoWarnings;
+ else if( t == "CONTLOAD" )
+ e = Contload;
+ else if( t == "BLANKLINE" )
+ e = BlankLine;
+ else if( t == "EXPORTBOOKSTREAM" )
+ e = ExportBookStream;
+ else if( t == "PARSEP" )
+ e = Parsep;
+ else if( t == "MAXBODYLINES" )
+ e = Maxbodylines;
+ else if( t == "INCLUDE" || t == "+" )
+ e = Include;
+ else if( t == "EXCLUDE" || t == "-" )
+ e = Exclude;
+ else if( t == "HEX" || t == "H" )
+ e = Hex;
+ else if( t == "BODY" || t == "B" )
+ e = Body;
+ else if( t == "NAMEONLY" || t =="N" )
+ e = NameOnly;
+ else if( t == "COMMENT" )
+ e = Comment;
+ else if( t == "OUTPUT" )
+ e = Output;
+ else if( t == "TITLE" )
+ e = Title;
+ else if( t == "CLEARFILE" )
+ e = ClearFile;
+ else
+ e = KW_Unknown;
+
+ return e;
+}
+
+
+void Biff8RecDumper::Init( void )
+{
+ bClearFile = FALSE;
+
+ if( pDumpModes || ppRecNames )
+ return;
+
+ const sal_Char* pDefName = "biffrecdumper.ini";
+ const sal_Char* pIniKey = "BIFFRECDUMPERINI";
+ const sal_Char pPathSep[] = { SAL_PATHDELIMITER, '\0' };
+ ByteString aIniName;
+
+ SvFileStream* pIn = NULL;
+
+ // first try: search for biffrecdumper.ini in dir, specified in %HOME%
+ const sal_Char* pHome = getenv( "HOME" );
+ if( pHome )
+ {
+ aIniName = pHome;
+ aIniName.EraseTrailingChars( *pPathSep );
+ aIniName += pPathSep;
+ aIniName += pDefName;
+
+ pIn = CreateInStream( aIniName.GetBuffer() );
+ }
+
+ if( !pIn )
+ { // %HOME% not set or %HOME%\biffrecdumper.ini could not be opened
+ const sal_Char* pIni = getenv( pIniKey );
+ if( pIni )
+ {
+ pIn = CreateInStream( pIni );
+ if( !pIn )
+ {
+ AddError( 0, "Could not open ini file", ByteString( pIni ) );
+ bEndLoading = TRUE; // zur Sicherheit....
+ }
+ }
+ }
+
+ if( pIn )
+ {
+ pIn->Seek( STREAM_SEEK_TO_END );
+
+ const UINT32 nStreamLen = pIn->Tell();
+
+ if( nStreamLen <= 1 )
+ {
+ pIn->Close();
+ delete pIn;
+ return;
+ }
+
+ pIn->Seek( STREAM_SEEK_TO_BEGIN );
+
+ pDumpModes = new UINT16[ nRecCnt ];
+ ppRecNames = new ByteString*[ nRecCnt ];
+
+ memset( pDumpModes, 0x00, sizeof( UINT16 ) * nRecCnt );
+ memset( ppRecNames, 0x00, sizeof( ByteString* )* nRecCnt );
+
+ enum STATE { PreLine, InCommand, PostCommand, InId, PostEqu,
+ InVal, InName, InInExClude, InBodyMode, PostSepIEC,
+ PostSepBM, InComment };
+
+ STATE eAct = PreLine;
+ sal_Char c;
+ sal_Char cNext;
+ INT32 n = ( INT32 ) nStreamLen;
+ ByteString aCommand;
+ ByteString aVal;
+ ByteString aInExClude;
+ ByteString aHexBody;
+ UINT32 nLine = 1;
+ BOOL bCommand = FALSE;
+
+ *pIn >> c >> cNext;
+
+ while( n > 0 )
+ {
+ n--;
+
+ switch( eAct )
+ {
+ case PreLine:
+ if( IsAlphaNum( c ) )
+ {
+ if( IsNum( c ) )
+ {
+ eAct = InId;
+ bCommand = FALSE;
+ }
+ else
+ {
+ eAct = InCommand;
+ bCommand = TRUE;
+ }
+ aCommand.Erase();
+ aCommand += c;
+ }
+ else if( c == cComm1 && cNext == cComm2 )
+ eAct = InComment;
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ nLine++;
+ else if( !IsBlank( c ) )
+ {
+ AddError( nLine, "Unexpected command or id" );
+ n = 0;
+ }
+ break;
+ case InCommand:
+ if( c == '=' )
+ {
+ eAct = PostEqu;
+ aVal.Erase();
+ }
+ else if( IsAlpha( c ) )
+ aCommand += c;
+ else if( IsBlank( c ) )
+ eAct = PostCommand;
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ eAct = InComment;
+ else
+ {
+ AddError( nLine, "Invalid command before comment", aCommand );
+ n = 0;
+ }
+ }
+ else
+ {
+ aCommand += '>';
+ aCommand += c;
+ aCommand += '<';
+ AddError( nLine, "Invalid character in command or id", aCommand );
+ n = 0;
+ }
+ break;
+ case PostCommand:
+ if( c == '=' )
+ {
+ eAct = PostEqu;
+ aVal.Erase();
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ eAct = InComment;
+ else
+ {
+ AddError( nLine, "Invalid command before comment", aCommand );
+ n = 0;
+ }
+ }
+ else if( !IsBlank( c ) )
+ {
+ AddError( nLine, "Expecting blank or \'=\' following the command", aCommand );
+ n = 0;
+ }
+ break;
+ case InId:
+ if( c == '=' )
+ {
+ eAct = PostEqu;
+ aVal.Erase();
+ }
+ else if( IsAlphaNum( c ) )
+ aCommand += c;
+ else if( IsBlank( c ) )
+ eAct = PostCommand;
+ else if( ( c == cComm1 && cNext == cComm2 ) || IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ AddError( nLine, "Unexpected end of record id", aCommand );
+ eAct = InComment;
+ }
+ else
+ {
+ AddError( nLine, "Unexpected sal_Char in record id", aCommand );
+ n = 0;
+ }
+ break;
+ case PostEqu:
+ if( bCommand )
+ { // Command
+ if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ eAct = InComment;
+ else
+ {
+ AddError( nLine, "Unknown command", aCommand );
+ n = 0;
+ }
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecCommand( nLine, aCommand ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ {
+ AddError( nLine, "Unknown command", aCommand );
+ n = 0;
+ }
+ }
+ else if( !bCommand && c == cParSep )
+ eAct = PostSepIEC;
+ else if( !IsBlank( c ) )
+ {
+ aVal.Erase();
+ aVal += c;
+ eAct = InVal;
+ }
+ }
+ else
+ { // Set
+ if( ( c == cComm1 && cNext == cComm2 ) || IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ AddError( nLine, "No mode set for record", aCommand );
+ n = 0;
+ }
+ else if( !bCommand && c == cParSep )
+ eAct = PostSepIEC;
+ else
+ {
+ aVal.Erase();
+ aVal += c;
+ eAct = InName;
+ aInExClude.Erase();
+ aHexBody.Erase();
+ }
+ }
+ break;
+ case InVal:
+ if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecCommand( nLine, aCommand, &aVal ) )
+ eAct = InComment;
+ else
+ {
+ AddError( nLine, "Unknown command", aCommand );
+ n = 0;
+ }
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecCommand( nLine, aCommand, &aVal ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ {
+ AddError( nLine, "Unknown command", aCommand );
+ n = 0;
+ }
+ }
+ else
+ aVal += c;
+ break;
+ case InName:
+ if( c == cParSep )
+ eAct = PostSepIEC;
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, NULL, NULL ) )
+ eAct = InComment;
+ else
+ n = 0;
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, NULL, NULL ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else
+ aVal += c;
+ break;
+ case InInExClude:
+ if( c == cParSep )
+ eAct = PostSepBM;
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, NULL ) )
+ eAct = InComment;
+ else
+ n = 0;
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, NULL ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else
+ aInExClude += c;
+ break;
+ case InBodyMode:
+ if( c == cParSep )
+ {
+ AddError( nLine, "Only 3 parameter possible" );
+ n = 0;
+ }
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, &aHexBody ) )
+ eAct = InComment;
+ else
+ n = 0;
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, &aHexBody ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else
+ aInExClude += c;
+ break;
+ case PostSepIEC:
+ if( c == cParSep )
+ eAct = PostSepBM;
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, NULL, NULL ) )
+ eAct = InComment;
+ else
+ n = 0;
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, NULL, NULL ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else if( !IsBlank( c ) )
+ {
+ aInExClude += c;
+ eAct = InInExClude;
+ }
+ break;
+ case PostSepBM:
+ if( c == cParSep )
+ eAct = PostSepBM;
+ else if( c == cComm1 && cNext == cComm2 )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, NULL ) )
+ eAct = InComment;
+ else
+ n = 0;
+ }
+ else if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ if( ExecSetVal( nLine, aCommand, &aVal, &aInExClude, NULL ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ else
+ n = 0;
+ }
+ else if( !IsBlank( c ) )
+ {
+ aHexBody += c;
+ eAct = InBodyMode;
+ }
+ break;
+ case InComment:
+ if( IsLineEnd( c, cNext, *pIn, n ) )
+ {
+ eAct = PreLine;
+ nLine++;
+ }
+ break;
+ default:
+ n = 0;
+ }
+
+ c = cNext;
+ *pIn >> cNext;
+ }
+
+ pIn->Close();
+ delete pIn;
+ }
+}
+
+
+BOOL Biff8RecDumper::ExecCommand( const UINT32 nL, const ByteString& r, const ByteString* pVal )
+{
+ _KEYWORD e = GetKeyType( r );
+ BOOL b = TRUE;
+ const UINT32 nValLen = ( pVal )? pVal->Len() : 0;
+ BOOL bSet;
+ UINT16 nMode;
+
+ switch( e )
+ {
+ case Skipdump: bSkip = TRUE; break;
+ case SkipOffset: bSkipOffset = TRUE; break;
+ case ReadContRecs: bReadContRecs = TRUE; break;
+ case NoWarnings: bWarnings = FALSE; break;
+ case Contload: bEndLoading = TRUE; break;
+ case BlankLine: bBlankLine = TRUE; break;
+ case ExportBookStream: bExportBookStream = TRUE; break;
+ case Parsep:
+ if( nValLen == 0 )
+ {
+ AddError( nL, "No separator found" );
+ b = FALSE;
+ }
+ else if( nValLen == 1 )
+ cParSep = *( pVal->GetBuffer() );
+ else
+ {
+ AddError( nL, "More than 1 sal_Char is not valid for separator", *pVal );
+ b = FALSE;
+ }
+ break;
+ case Maxbodylines:
+ if( nValLen )
+ {
+ UINT32 n = GetVal( *pVal );
+
+ if( n == 0xFFFFFFFF )
+ {
+ AddError( nL, "Syntax error in value of body lines" );
+ b = FALSE;
+ }
+ else
+ nMaxBodyLines = n;
+ }
+ else
+ {
+ AddError( nL, "No value specified for number of body lines" );
+ b = FALSE;
+ }
+ break;
+ case Include:
+ bSet = FALSE;
+ nMode = MODE_SKIP;
+ goto _common;
+ case Exclude:
+ bSet = TRUE;
+ nMode = MODE_SKIP;
+ goto _common;
+ case Hex:
+ bSet = TRUE;
+ nMode = MODE_HEX;
+ goto _common;
+ case Body:
+ bSet = FALSE;
+ nMode = MODE_HEX;
+ goto _common;
+ case NameOnly:
+ bSet = TRUE;
+ nMode = MODE_NAMEONLY;
+ goto _common;
+_common:
+ if( pVal )
+ {
+ IdRangeList aRL;
+ if( FillIdRangeList( nL, aRL, *pVal ) )
+ {
+ const IdRange* p = aRL.First();
+ if( bSet )
+ {
+ while( p )
+ { SetFlag( p->nFirst, p->nLast, nMode ); p = aRL.Next(); }
+ }
+ else
+ {
+ while( p )
+ { ClrFlag( p->nFirst, p->nLast, nMode ); p = aRL.Next(); }
+ }
+ }
+ else
+ b = FALSE;
+ }
+ break;
+ case Comment:
+ if( pVal && pVal->Len() >= 2 )
+ {
+ cComm1 = pVal->GetChar( 0 );
+ cComm2 = pVal->GetChar( 1 );
+ }
+ break;
+ case Output:
+ CopyStrpOnStrp( pOutName, pVal );
+ if( pOutName )
+ {
+ if( *pOutName == "*" )
+ {
+ ByteString aDefault( "DefaultDumpName.txt" );
+ SfxObjectShell* pShell = GetDocShell();
+ if( pShell )
+ {
+ SfxMedium* pMedium = pShell->GetMedium();
+ if( pMedium )
+ {
+ const ByteString aTextExtension( ".txt" );
+ aDefault = GETSTR( pMedium->GetPhysicalName() );
+ xub_StrLen nStrLen = aDefault.Len();
+ if( nStrLen >= 4 )
+ {
+ ByteString aTmp( aDefault );
+ aTmp.ToLowerAscii();
+ if( aTmp.Copy( nStrLen -4 ) == ".xls" )
+ aDefault.Replace( nStrLen - 4, aTextExtension.Len(), aTextExtension );
+ else
+ aDefault += aTextExtension;
+ }
+ else
+ aDefault += aTextExtension;
+ }
+ }
+
+ *pOutName = aDefault;
+ }
+ CreateOutStream();
+ }
+ else if( pDumpStream )
+ {
+ pDumpStream->Close();
+ DELANDNULL( pDumpStream );
+ }
+ break;
+ case Title:
+ CopyStrpOnStrp( pTitle, pVal );
+ break;
+ case ClearFile:
+ bClearFile = TRUE;
+ break;
+ default:
+ AddError( nL, "Unknown command", r );
+ b = FALSE;
+ }
+
+ return b;
+}
+
+
+BOOL Biff8RecDumper::ExecSetVal( const UINT32 nL, const ByteString& rId, const ByteString* pName,
+ const ByteString* pIEC, const ByteString* pHB )
+{
+ UINT32 _nId = GetVal( rId );
+
+ if( _nId == 0xFFFFFFFF )
+ {
+ AddError( nL, "Syntax error in record id", rId );
+ return FALSE;
+ }
+ else if( _nId >= ( UINT32 ) nRecCnt )
+ {
+ AddError( nL, "Record id to high", rId );
+ return FALSE;
+ }
+
+ UINT16 nId = ( UINT16 ) _nId;
+
+ if( pName && pName->Len() )
+ SetName( nId, *pName );
+
+ _KEYWORD e;
+ UINT16 n = GetMode( nId );
+
+ if( pIEC && pIEC->Len() )
+ {
+ e = GetKeyType( *pIEC );
+
+ if( e == Include )
+ n &= ~MODE_SKIP;
+ else if( e == Exclude )
+ n |= MODE_SKIP;
+ else
+ {
+ AddError( nL, "Invalid key for in-/exclude", *pIEC );
+ return FALSE;
+ }
+ }
+
+ if( pHB && pHB->Len() )
+ {
+ e = GetKeyType( *pHB );
+
+ if( e == NameOnly )
+ n |= MODE_NAMEONLY;
+ else
+ {
+ n &= ~MODE_NAMEONLY;
+ if( e == Hex )
+ n |= MODE_HEX;
+ else if( e == Body )
+ n &= ~MODE_HEX;
+ else
+ {
+ AddError( nL, "Invalid key for hex/body/name only", *pIEC );
+ return FALSE;
+ }
+ }
+ }
+
+ SetMode( nId, n );
+ return TRUE;
+}
+
+
+void Biff8RecDumper::SetFlag( const UINT16 nF, const UINT16 nL, const UINT16 nFl )
+{
+ UINT16 n = ( nF < nL )? nF : nL;
+ UINT16 nLast = ( nF < nL )? nL : nF;
+
+ if( nLast >= nRecCnt )
+ nLast = nRecCnt - 1;
+
+ while( n <= nLast )
+ {
+ pDumpModes[ n ] |= nFl;
+ n++;
+ }
+}
+
+
+void Biff8RecDumper::ClrFlag( const UINT16 nF, const UINT16 nL, const UINT16 nFlags )
+{
+ UINT16 n = ( nF < nL )? nF : nL;
+ UINT16 nLast = ( nF < nL )? nL : nF;
+ UINT16 nFl = ~nFlags;
+
+ if( nLast >= nRecCnt )
+ nLast = nRecCnt - 1;
+
+ while( n <= nLast )
+ {
+ pDumpModes[ n ] &= nFl;
+ n++;
+ }
+}
+
+
+void Biff8RecDumper::SetName( const UINT16 n, ByteString* p )
+{
+ if( n < nRecCnt )
+ CopyStrpOnStrp( ppRecNames[ n ], p );
+}
+
+
+UINT32 Biff8RecDumper::GetVal( const ByteString& r )
+{
+ const sal_Char* p = r.GetBuffer();
+ sal_Char c = *p;
+ UINT32 n = 0;
+ const UINT32 nLimitDec = 0xFFFFFFFF / 10;
+ const UINT32 nLimitHex = 0xFFFFFFFF / 16;
+ BOOL bError = FALSE;
+
+ enum STATE { First, Dec, MaybeHex, Hex };
+
+ STATE e = First;
+
+ while( c )
+ {
+ switch( e )
+ {
+ case First:
+ if( IsNum( c ) )
+ {
+ if( c == '0' )
+ e = MaybeHex;
+ else
+ {
+ e = Dec;
+ n = GetVal( c );
+ }
+ }
+ else
+ bError = TRUE;
+ break;
+ case Dec:
+ if( n < nLimitDec && IsNum( c ) )
+ {
+ n *= 10;
+ n += GetVal( c );
+ }
+ else
+ bError = TRUE;
+ break;
+ case MaybeHex:
+ if( c == 'x' || c == 'X' )
+ {
+ e = Hex;
+ n = 0;
+ }
+ else if( IsNum( c ) )
+ {
+ n = GetVal( c );
+ e = Dec;
+ }
+ else
+ bError = TRUE;
+ break;
+ case Hex:
+ if( n < nLimitHex && IsHex( c ) )
+ {
+ n *= 16;
+ n += GetVal( c );
+ }
+ else
+ bError = TRUE;
+ break;
+ }
+
+ if( bError )
+ c = 0x00;
+ else
+ {
+ p++;
+ c = *p;
+ }
+ }
+
+ if( bError )
+ return 0xFFFFFFFF;
+ else
+ return n;
+}
+
+
+BOOL Biff8RecDumper::FillIdRangeList( const UINT32 nL, IdRangeList& rRL, const ByteString& rV )
+{
+ rRL.Clear();
+
+ const sal_Char* pSyntErr = "Syntax error in number (list)";
+
+#define SYNTERR(ch) AddError( ((UINT32)(b=FALSE))+nL, pSyntErr, ch? ((((t+=">")+=ByteString::CreateFromInt32(ch))+="<")) : t )
+#define NEWVAL(_n) _n=(n>=(UINT32)nRecCnt)?nRecCnt-1:(UINT16)n
+#define ORDERN() {if(n1>n2){UINT16 nT=n1;n1=n2;n2=nT;}}
+
+ const sal_Char* p = rV.GetBuffer();
+ sal_Char c = *p;
+ const sal_Char cSep = cParSep;
+ const sal_Char cCont = '.';
+ const sal_Char cAll = '*';
+ ByteString t;
+ UINT16 n1 = 0, n2 = 0;
+ UINT32 n;
+ BOOL b = TRUE;
+ BOOL bExp2 = FALSE;
+
+ enum STATE { PreFirst, InFirst, PostFirst, InCont, PreLast, InLast, PostLast };
+ STATE e = PreFirst;
+
+ while( c )
+ {
+ switch( e )
+ {
+ case PreFirst:
+ if( IsAlphaNum( c ) )
+ {
+ t += c;
+ e = InFirst;
+ }
+ else if( c == cAll )
+ {
+ rRL.Append( 0, nRecCnt - 1 );
+ e = PostLast;
+ }
+ else if( !IsBlank( c ) )
+ SYNTERR( c );
+ break;
+ case InFirst:
+ if( c == cSep || c == cCont || IsBlank( c ) )
+ {
+ n = GetVal( t );
+ if( n == 0xFFFFFFFF )
+ SYNTERR( 0 );
+ else
+ NEWVAL( n1 );
+
+ t.Erase();
+
+ if( c == cSep )
+ {
+ rRL.Append( n1, n1 );
+ e = PreFirst;
+ }
+ else if( c == cCont )
+ {
+ bExp2 = TRUE;
+ e = InCont;
+ }
+ else
+ e = PostFirst;
+ }
+ else if( IsAlphaNum( c ) )
+ t += c;
+ else
+ SYNTERR( c );
+ break;
+ case PostFirst:
+ if( c == cCont )
+ {
+ e = InCont;
+ bExp2 = TRUE;
+ }
+ else if( c == cSep )
+ {
+ n = GetVal( t );
+ if( n == 0xFFFFFFFF )
+ SYNTERR( 0 );
+ else
+ NEWVAL( n1 );
+
+ e = PreFirst;
+ }
+ else if( !IsBlank( c ) )
+ SYNTERR( c );
+ break;
+ case InCont:
+ if( IsAlphaNum( c ) )
+ {
+ t += c;
+ e = InLast;
+ }
+ else if( IsBlank( c ) )
+ e = PreLast;
+ else if( c == cSep || c == cAll )
+ {
+ rRL.Append( n1, nRecCnt - 1 );
+ bExp2 = FALSE;
+ e = PreFirst;
+ }
+ else if( c != cCont )
+ SYNTERR( c );
+ break;
+ case PreLast:
+ if( IsAlphaNum( c ) )
+ {
+ t += c;
+ e = InLast;
+ }
+ else if( !IsBlank( c ) )
+ SYNTERR( c );
+ break;
+ break;
+ case InLast:
+ if( c == cSep || IsBlank( c ) )
+ {
+ n = GetVal( t );
+ if( n == 0xFFFFFFFF )
+ SYNTERR( 0 );
+ else
+ NEWVAL( n2 );
+
+ t.Erase();
+ ORDERN();
+ rRL.Append( n1, n2 );
+ bExp2 = FALSE;
+ e = ( c == cSep )? PreFirst : PostLast;
+ }
+ else if( IsAlphaNum( c ) )
+ t += c;
+ else
+ SYNTERR( c );
+ break;
+ case PostLast:
+ if( c == cSep )
+ {
+ e = PreFirst;
+ bExp2 = FALSE;
+ }
+ else if( !IsBlank( c ) )
+ SYNTERR( c );
+ break;
+ }
+
+ if( b )
+ {
+ p++;
+ c = *p;
+ }
+ else
+ c = 0x00;
+ }
+
+ if( bExp2 )
+ {
+ if( t.Len() )
+ {
+ n = GetVal( t );
+ if( n == 0xFFFFFFFF )
+ SYNTERR( 0 );
+ else
+ NEWVAL( n2 );
+ ORDERN();
+ }
+ else
+ n2 = nRecCnt - 1;
+
+ if( b )
+ rRL.Append( n1, n2 );
+ }
+
+#undef SYNTERR
+#undef NEWVAL
+#undef ORDERN
+
+ return b;
+}
+
+
+BOOL Biff8RecDumper::CreateOutStream()
+{
+ if( pDumpStream )
+ {
+ pDumpStream->Close();
+ DELANDNULL( pDumpStream );
+ }
+
+ if( !bSkip && pOutName )
+ {
+ pOutName->EraseLeadingChars( ' ' );
+ pOutName->EraseTrailingChars( ' ' );
+ pOutName->EraseLeadingChars( '\t' );
+ pOutName->EraseTrailingChars( '\t' );
+
+ pDumpStream = new SvFileStream( String::CreateFromAscii( pOutName->GetBuffer() ), STREAM_WRITE|STREAM_SHARE_DENYWRITE|(bClearFile?STREAM_TRUNC:0) );
+
+ if( pDumpStream->IsOpen() )
+ {
+ pDumpStream->Seek( bClearFile? STREAM_SEEK_TO_BEGIN : STREAM_SEEK_TO_END );
+ return TRUE;
+ }
+ else
+ {
+ DELANDNULL( pDumpStream );
+ }
+ }
+
+ return FALSE;
+}
+
+
+SvFileStream* Biff8RecDumper::CreateInStream( const sal_Char* pN )
+{
+ SvFileStream* p = new SvFileStream( String::CreateFromAscii( pN ), STREAM_READ|STREAM_SHARE_DENYWRITE );
+
+ if( p->IsOpen() )
+ return p;
+ else
+ {
+ delete p;
+ return NULL;
+ }
+}
+
+
+SvFileStream* Biff8RecDumper::CreateInStream( const sal_Char* pP, const sal_Char* pN )
+{
+ ByteString t( pP );
+ const sal_Char c = t.GetChar( t.Len() - 1 );
+
+ if( c != '\\' )
+ t += '\\';
+ else if( c != '/' )
+ t += '/';
+
+ t += pN;
+
+ return CreateInStream( t.GetBuffer() );
+}
+
+
+void Biff8RecDumper::AddError( const UINT32 n, const ByteString& rT, const ByteString& rH )
+{
+ DUMP_ERR* p = new DUMP_ERR( n, rT, rH );
+
+ if( pFirst )
+ pLast->pNext = p;
+ else
+ pFirst = p;
+
+ pLast = p;
+}
+
+
+Biff8RecDumper::Biff8RecDumper( const XclImpRoot& rRoot, BOOL _bBIFF8 ) :
+ XclImpRoot( rRoot ),
+ bBIFF8( _bBIFF8 ),
+ bEncrypted( false ),
+ mnEscherPos( 0 )
+{
+ nXFCount = 0;
+ nFontIndex = 0;
+ nInstances++;
+ mnSubstream = EXC_BOF_UNKNOWN;
+
+ if( !pCharType )
+ {
+ pCharType = new UINT8[ 256 ];
+ memset( pCharType, 0x00, 256 );
+
+ pCharVal = new UINT8[ 256 ];
+ memset( pCharVal, 0x00, 256 );
+
+ sal_Char c;
+ UINT8 n;
+
+#define __TYPE(n) pCharType[(UINT8)n]
+#define __VAL(n) pCharVal[(UINT8)n]
+
+ __TYPE( '\n' ) = CT_EOL;
+ __TYPE( '\r' ) = CT_EOL;
+
+ __TYPE( ' ' ) = CT_BLANK;
+ __TYPE( '\t' ) = CT_BLANK;
+
+ for( c = '0', n = 0 ; c <= '9' ; c++, n++ )
+ {
+ __TYPE( c ) = CT_NUM|CT_HEX|CT_ALPHANUM;
+ __VAL( c ) = n;
+ }
+ for( c = 'a', n = 10 ; c <= 'f' ; c++, n++ )
+ {
+ __TYPE( c ) = CT_HEX|CT_ALPHA|CT_ALPHANUM|CT_LOWERALPHA;
+ __VAL( c ) = n;
+ }
+ for( c = 'g' ; c <= 'z' ; c++ )
+ __TYPE( c ) = CT_ALPHA|CT_ALPHANUM|CT_LOWERALPHA;
+ for( c = 'A', n = 10 ; c <= 'F' ; c++, n++ )
+ {
+ __TYPE( c ) = CT_HEX|CT_ALPHA|CT_ALPHANUM|CT_UPPERALPHA;
+ __VAL( c ) = n;
+ }
+ for( c = 'G' ; c <= 'Z' ; c++ )
+ __TYPE( c ) = CT_ALPHA|CT_ALPHANUM|CT_UPPERALPHA;
+
+#undef __TYPE
+#undef __VAL
+ }
+
+ pDumpStream = NULL;
+
+ if( !pBlankLine )
+ {
+ pBlankLine = new sal_Char[ nLenBlankLine + 1 ];
+ memset( pBlankLine, ' ', nLenBlankLine );
+ pBlankLine[ nLenBlankLine ] = 0x00;
+ }
+
+ pTitle = NULL;
+ pOutName = NULL;
+ pLevelPre = pLevelPreStringNT;
+
+ nMaxBodyLines = 1024;
+ bEndLoading = bSkip = bSkipOffset = bReadContRecs = bBlankLine = bExportBookStream = FALSE;
+ bWarnings = TRUE;
+
+ pDumpModes = NULL;
+ ppRecNames = NULL;
+
+ pFirst = pLast = pAct = NULL;
+
+ cParSep = ',';
+ cComm1 = cComm2 = '/';
+
+ nFieldCnt = nItemCnt = nTabIndexCnt = 0;
+
+ Init();
+}
+
+
+Biff8RecDumper::~Biff8RecDumper()
+{
+ if( pDumpStream )
+ {
+ pDumpStream->Close();
+ delete pDumpStream;
+ }
+
+ if( nInstances )
+ {
+ nInstances--;
+ if( !nInstances )
+ {
+ delete[] pBlankLine;
+ pBlankLine = NULL;
+
+ delete[] pCharType;
+ pCharType = NULL;
+
+ delete[] pCharVal;
+ pCharVal = NULL;
+ }
+ }
+
+ if( pDumpModes )
+ delete[] pDumpModes;
+
+ if( ppRecNames )
+ {
+ ByteString** pp = ppRecNames;
+ UINT16 n = nRecCnt;
+ while( n )
+ {
+ if( *pp )
+ delete *pp;
+ pp++;
+ n--;
+ }
+ delete[] ppRecNames;
+ }
+
+ if( pTitle )
+ delete pTitle;
+
+ if( pOutName )
+ delete pOutName;
+
+ DUMP_ERR* p = pFirst;
+ DUMP_ERR* pD;
+ if( p )
+ {
+ pD = p;
+ p = p->pNext;
+ delete pD;
+ }
+}
+
+
+BOOL Biff8RecDumper::Dump( XclImpStream& r )
+{
+ const DUMP_ERR* pErr = FirstErr();
+
+ if( pErr )
+ {
+ if( pDumpStream )
+ {
+ SvFileStream& rOut = *pDumpStream;
+ while( pErr )
+ {
+ rOut << "\nError";
+ if( pErr->nLine )
+ {
+ ByteString t;
+ t += ByteString::CreateFromInt32( pErr->nLine );
+ rOut << " at line " << t.GetBuffer();
+ }
+
+ rOut << ": " << pErr->aText.GetBuffer();
+
+ if( pErr->pHint )
+ rOut << " (" << pErr->pHint->GetBuffer() << ')';
+ pErr = NextErr();
+ }
+ rOut << '\n';
+ }
+ }
+ else if( pDumpStream && !bSkip )
+ {
+ SvStream& rOutStrm = *pDumpStream;
+
+ if( bExportBookStream && pOutName )
+ {
+ ByteString aBookOutName( *pOutName, 0, pOutName->Len() - 4 );
+ aBookOutName.Append( "_book.xls" );
+ SvFileStream aBook( String::CreateFromAscii( aBookOutName.GetBuffer() ), STREAM_WRITE|STREAM_SHARE_DENYWRITE|STREAM_TRUNC );
+ if( aBook.IsOpen() )
+ {
+ const sal_uInt32 nBufLen = 0xFFFF;
+ sal_uInt8 pBuffer[ nBufLen ];
+ r.StoreGlobalPosition();
+ while( r.StartNextRecord() )
+ {
+ r.ResetRecord( false );
+ sal_uInt16 nRecSize = (sal_uInt16) Min( r.GetRecSize(), nBufLen );
+ aBook << r.GetRecId() << nRecSize;
+ r.Read( pBuffer, nRecSize );
+ aBook.Write( pBuffer, nRecSize );
+ }
+ r.SeekGlobalPosition();
+ }
+ }
+
+ if( pTitle )
+ rOutStrm << pTitle->GetBuffer();
+
+ pIn = &r;
+ r.StoreGlobalPosition();
+
+ ::std::auto_ptr< XclDumpStorageHeader > xStrgHerader;
+ SotStorageRef xRootStrg = GetRootStorage();
+ if( xRootStrg.Is() )
+ xStrgHerader.reset( new XclDumpStorageHeader( *xRootStrg, rOutStrm, EMPTY_STRING ) );
+
+ ::std::auto_ptr< ScfProgressBar > xProgress( new ScfProgressBar(
+ GetDocShell(), String( RTL_CONSTASCII_USTRINGPARAM( "Dumper" ) ) ) );
+ sal_Int32 nStreamSeg = xProgress->AddSegment( r.GetSvStreamSize() );
+ xProgress->ActivateSegment( nStreamSeg );
+
+ while( r.StartNextRecord() )
+ {
+ xProgress->ProgressAbs( r.GetSvStreamPos() );
+ if( HasModeDump( r.GetRecId() ) )
+ RecDump();
+ }
+
+ rOutStrm << "\n\n";
+
+ pIn = NULL;
+ xProgress.reset();
+
+ r.SeekGlobalPosition();
+
+ // dump substreams
+ if( xRootStrg.Is() )
+ {
+ pIn = NULL;
+ bool bOldEncr = bEncrypted;
+ bEncrypted = false;
+ DumpRecordStream( xRootStrg, EXC_STREAM_USERNAMES, EMPTY_STRING );
+
+ pIn = &r;
+ bEncrypted = bOldEncr;
+ DumpRecordStream( xRootStrg, EXC_STREAM_REVLOG, EMPTY_STRING );
+
+ pIn = NULL;
+
+ DumpCtlsStream();
+ DumpVbaProjectStorage();
+ }
+ }
+
+ return !bEndLoading;
+}
+
+#undef Read1
+#undef Read2
+#undef Read4
+#undef Read8
+
+#endif
+
diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx
index 312604d7ab92..b1ec8752de7b 100644
--- a/sc/source/filter/excel/colrowst.cxx
+++ b/sc/source/filter/excel/colrowst.cxx
@@ -95,6 +95,12 @@ void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt
{
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 )
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
index 80cfdf7d14cb..e5303ffbdb50 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -68,11 +68,11 @@
#include "convuno.hxx"
#include "patattr.hxx"
#include "docoptio.hxx"
+#include "tabprotection.hxx"
#include "excdoc.hxx"
#include "namebuff.hxx"
-#include "xcl97dum.hxx"
#include "xcl97rec.hxx"
#include "xcl97esc.hxx"
#include "xetable.hxx"
@@ -118,7 +118,7 @@ static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
aRecList.AppendNewRecord( new XclIteration( rDoc ) );
aRecList.AppendNewRecord( new XclDelta( rDoc ) );
- aRecList.AppendNewRecord( new ExcDummy8_02 );
+ aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
}
@@ -207,7 +207,16 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
Add( new ExcDummy_00 );
else
{
- Add( new ExcDummy8_00a );
+ if ( IsDocumentEncrypted() )
+ Add( new XclExpFilePass(GetRoot()) );
+
+ Add( new XclExpInterfaceHdr );
+ Add( new XclExpMMS );
+ Add( new XclExpInterfaceEnd );
+ Add( new XclExpWriteAccess );
+ Add( new XclExpCodePage );
+ Add( new XclExpDSF );
+ Add( new XclExpExcel9File );
rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
Add( rR.pTabId );
if( HasVbaStorage() )
@@ -217,7 +226,8 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
if( rCodeName.Len() )
Add( new XclCodename( rCodeName ) );
}
- Add( new ExcDummy8_00b );
+
+ Add( new XclExpFnGroupCount );
}
// erst Namen- und Tabellen-Eintraege aufbauen
@@ -237,12 +247,22 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
}
- aRecList.AppendNewRecord( new XclExpWindowProtection( GetExtDocOptions().GetDocSettings().mbWinProtected ) );
- aRecList.AppendNewRecord( new XclExpDocProtection( rDoc.IsDocProtected() ) );
- aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_PASSWORD, false ) );
+ // document protection options
+ const ScDocProtection* pProtect = GetDoc().GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ Add( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
+ Add( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
+#if ENABLE_SHEET_PROTECTION
+ Add( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
+#endif
+ }
if( GetBiff() == EXC_BIFF8 )
- Add( new ExcDummy8_040 );
+ {
+ Add( new XclExpProt4Rev );
+ Add( new XclExpProt4RevPass );
+ }
// document protection options
if( GetOutput() == EXC_OUTPUT_BINARY )
@@ -253,6 +273,12 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
+ if ( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
+ Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
+ }
+
if( GetBiff() <= EXC_BIFF5 )
{
Add( new ExcDummy_040 );
@@ -261,9 +287,11 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
}
else
{
+ // BIFF8
Add( new Exc1904( rDoc ) );
Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
- Add( new ExcDummy8_041 );
+ 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:
//
@@ -359,10 +387,14 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
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 );
@@ -422,8 +454,16 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx )
// page settings (SETUP and various other records)
aRecList.AppendRecord( xPageSett );
- if( rDoc.IsTabProtected( mnScTab ) )
- Add( new XclProtection() );
+ 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)) );
+#if ENABLE_SHEET_PROTECTION
+ Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
+#endif
+ }
// local link table: EXTERNCOUNT, EXTERNSHEET
if( eBiff <= EXC_BIFF5 )
@@ -459,6 +499,9 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx )
if( eBiff == EXC_BIFF8 )
{
+ // sheet protection options
+ Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
+
// web queries
Add( new XclExpWebQueryBuffer( GetRoot() ) );
@@ -759,7 +802,7 @@ void ExcDocument::WriteXml( SvStream& rStrm )
rWorkbook->endElement( XML_workbook );
rWorkbook.reset();
- aStrm.commit();
+ aStrm.commitStorage();
}
#if 0
if( pExpChangeTrack )
diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx
index 7072785b8936..3965d0acaf4e 100644
--- a/sc/source/filter/excel/excel.cxx
+++ b/sc/source/filter/excel/excel.cxx
@@ -39,6 +39,7 @@
#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"
@@ -86,9 +87,13 @@ FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument
{
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 ] <<= !bUseOoxFilter;
+ aArgs[ 1 ] <<= aArgSeq;
uno::Reference< document::XImporter > xImporter( ScfApiHelper::CreateInstanceWithArgs(
CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" ), aArgs ), uno::UNO_QUERY_THROW );
xImporter->setTargetDocument( xComponent );
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index b62470ceee3b..1d209b91bc68 100644
--- a/sc/source/filter/excel/excimp8.cxx
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -160,12 +160,6 @@ void ImportExcel8::Iteration( void )
}
-void ImportExcel8:: WinProtection( void )
-{
- if( aIn.ReaduInt16() != 0 )
- GetExtDocOptions().GetDocSettings().mbWinProtected = true;
-}
-
void ImportExcel8::Boundsheet( void )
{
UINT8 nLen;
@@ -249,6 +243,11 @@ void ImportExcel8::Codename( BOOL bWorkbookGlobals )
}
}
+void ImportExcel8::SheetProtection( void )
+{
+ GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
+}
+
bool lcl_hasVBAEnabled()
{
uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY);
@@ -295,6 +294,8 @@ void ImportExcel8::PostDocLoad( void )
pExcRoot->pAutoFilterBuffer->Apply();
GetWebQueryBuffer().Apply(); //! test if extant
+ GetSheetProtectBuffer().Apply();
+ GetDocProtectBuffer().Apply();
ImportExcel::PostDocLoad();
@@ -426,6 +427,38 @@ void XclImpAutoFilterData::InsertQueryParam()
}
}
+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 )
{
UINT16 nCol, nFlags;
@@ -463,14 +496,14 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
BOOL bIgnore;
UINT8 nStrLen[ 2 ] = { 0, 0 };
- String* pEntryStr[ 2 ] = { NULL, NULL };
+ ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
for( nE = 0; nE < 2; nE++ )
{
if( nFirstEmpty < nCount )
{
ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
- pEntryStr[ nE ] = aEntry.pStr;
+ pQueryEntries[ nE ] = &aEntry;
bIgnore = FALSE;
rStrm >> nType >> nOper;
@@ -558,8 +591,12 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
}
for( nE = 0; nE < 2; nE++ )
- if( nStrLen[ nE ] && pEntryStr[ nE ] )
- pEntryStr[ nE ]->Assign( rStrm.ReadUniString( nStrLen[ nE ] ) );
+ if( nStrLen[ nE ] && pQueryEntries[ nE ] )
+ {
+ pQueryEntries[ nE ]->pStr->Assign ( rStrm.ReadUniString( nStrLen[ nE ] ) );
+ ExcelQueryToOooQuery( *pQueryEntries[ nE ] );
+ }
+
}
}
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index 9d50ea0db534..5e31a2229919 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -101,6 +101,7 @@
#include <oox/core/tokens.hxx>
+using ::com::sun::star::uno::Sequence;
using ::rtl::OString;
@@ -433,7 +434,9 @@ ExcBundlesheetBase::ExcBundlesheetBase() :
void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
{
rStrm.SetSvStreamPos( nOwnPos );
+ rStrm.DisableEncryption();
rStrm << static_cast<sal_uInt32>(nStrPos);
+ rStrm.EnableEncryption();
}
@@ -533,7 +536,7 @@ void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
// XclExpWindowProtection ===============================================================
XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
- XclExpBoolRecord(EXC_ID_WINDOWPROTECT,bValue)
+ XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
{
}
@@ -546,13 +549,35 @@ void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
// XclExpDocProtection ===============================================================
-XclExpDocProtection::XclExpDocProtection(bool bValue) :
- XclExpBoolRecord(EXC_ID_PROTECT,bValue)
+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 )
{
@@ -700,7 +725,31 @@ BOOL XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
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
+ }
+ }
+ }
BOOL bLen = sText.Len() > 0;
@@ -760,6 +809,14 @@ BOOL XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
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 );
diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx
index 3b0095f64735..774f517dada6 100644
--- a/sc/source/filter/excel/expop2.cxx
+++ b/sc/source/filter/excel/expop2.cxx
@@ -102,7 +102,7 @@ FltError ExportBiff5::Write()
SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
if( nErr != ERRCODE_NONE )
- pDocShell->SetError( nErr );
+ pDocShell->SetError( nErr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
pExcDoc->ReadDoc(); // ScDoc -> ExcDoc
@@ -191,7 +191,7 @@ FltError ExportXml2007::Write()
SvxImportMSVBasic aBasicImport( *pDocShell, *xRootStrg, bWriteBasicCode, bWriteBasicStrg );
ULONG nErr = aBasicImport.SaveOrDelMSVBAStorage( TRUE, EXC_STORAGE_VBA_PROJECT );
if( nErr != ERRCODE_NONE )
- pDocShell->SetError( nErr );
+ pDocShell->SetError( nErr, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
pExcDoc->ReadDoc(); // ScDoc -> ExcDoc
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index 41f5e6d17234..c43c35b159ef 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -84,6 +84,7 @@
#include "xiview.hxx"
#include "xilink.hxx"
#include "xiescher.hxx"
+#include "xicontent.hxx"
#include "excimp8.hxx"
#include "excform.hxx"
@@ -418,14 +419,12 @@ void ImportExcel::Eof( void )
}
-BOOL ImportExcel::Password( void )
+void ImportExcel::SheetPassword( void )
{
- // POST: return = TRUE, wenn Password <> 0
- UINT16 nPasswd;
-
- aIn >> nPasswd;
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
- return nPasswd != 0x0000;
+ GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
}
@@ -439,6 +438,15 @@ void ImportExcel::Externsheet( void )
}
+void ImportExcel:: WinProtection( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
+}
+
+
void ImportExcel::Columndefault( void )
{// Default Cell Attributes
UINT16 nColMic, nColMac;
@@ -570,27 +578,33 @@ void ImportExcel::Defrowheight2( void )
}
-void ImportExcel::Protect( void )
+void ImportExcel::SheetProtect( void )
{
- if( aIn.ReaduInt16() )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- GetDoc().SetTabProtection( GetCurrScTab(), TRUE, aEmptyPass );
- }
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
}
void ImportExcel::DocProtect( void )
{
- if( aIn.ReaduInt16() )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- GetDoc().SetDocProtection( TRUE, aEmptyPass );
- }
+ 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 )
{
+ maStrm.EnableDecryption();
SetCodePage( maStrm.ReaduInt16() );
}
diff --git a/sc/source/filter/excel/namebuff.cxx b/sc/source/filter/excel/namebuff.cxx
index df53c3edcd3c..b01f5a728263 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -127,6 +127,9 @@ void ShrfmlaBuffer::Store( const ScRange& rRange, const ScTokenArray& rToken )
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< USHORT >( mnCurrIdx ) );
pExcRoot->pIR->GetNamedRanges().Insert( pData );
index_hash[rRange.aStart] = static_cast< USHORT >( mnCurrIdx );
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 21497f2927a3..8be7f2d94220 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -356,7 +356,7 @@ FltError ImportExcel::Read( void )
Eof();
eAkt = Z_Ende;
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x14:
case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
@@ -471,7 +471,7 @@ FltError ImportExcel::Read( void )
Eof();
eAkt = Z_Biff4E;
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x14:
case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
case 0x1A:
@@ -598,7 +598,7 @@ FltError ImportExcel::Read( void )
eAkt = Z_Biff5T;
aIn.SeekGlobalPosition(); // und zurueck an alte Position
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x1A:
case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
@@ -898,6 +898,7 @@ FltError ImportExcel8::Read( void )
}
break;
case 0x12: DocProtect(); break; // PROTECT [ 5678]
+ case 0x13: DocPasssword(); break;
case 0x19: WinProtection(); break;
case 0x2F: // FILEPASS [ 2345 ]
eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
@@ -1042,7 +1043,8 @@ FltError ImportExcel8::Read( void )
eAkt = EXC_STATE_SHEET;
aIn.SeekGlobalPosition(); // und zurueck an alte Position
break;
- case 0x12: Protect(); 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 ]
@@ -1058,6 +1060,7 @@ FltError ImportExcel8::Read( void )
case 0x0221: Array34(); break; // ARRAY [ 34 ]
case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
+ case 0x0867: SheetProtection(); break; // SHEETPROTECTION
}
}
break;
diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx
index bac636fc798d..b416e59b92ac 100644
--- a/sc/source/filter/excel/xechart.cxx
+++ b/sc/source/filter/excel/xechart.cxx
@@ -815,10 +815,11 @@ sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > x
if( !xDataSeq.is() )
return nDefCount;
- // compile the range representation string into token array
+ // 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( FormulaGrammar::GRAM_ENGLISH );
+ aComp.SetGrammar( GetDocPtr()->GetGrammar() );
ScTokenArray* pArray = aComp.CompileString( aRangeRepr );
if( !pArray )
return nDefCount;
@@ -1714,7 +1715,7 @@ bool XclExpChSeries::ConvertDataSeries(
Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
if( xDataSource.is() )
{
- Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq;
+ Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq, xBubbleSeq;
// find first sequence with role 'values-y'
Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
@@ -1730,12 +1731,18 @@ bool XclExpChSeries::ConvertDataSeries(
if( !xYValueSeq.is() && (aRole == EXC_CHPROP_ROLE_YVALUES) )
{
xYValueSeq = xTmpValueSeq;
- xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
+ 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
+ }
}
}
@@ -1752,6 +1759,10 @@ bool XclExpChSeries::ConvertDataSeries(
// X values of XY charts
maData.mnCategCount = mxCategLink->ConvertDataSequence( xXValueSeq, false, maData.mnValueCount );
+ // size values of bubble charts
+ if( mxBubbleLink.is() )
+ mxBubbleLink->ConvertDataSequence( xBubbleSeq, false, maData.mnValueCount );
+
// series formatting
XclChDataPointPos aPointPos( mnSeriesIdx );
ScfPropertySet aSeriesProp( xDataSeries );
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index 0c49d4e96702..4853fff46d9c 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -546,6 +546,9 @@ XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rObjMgr, Referenc
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 );
@@ -1000,7 +1003,7 @@ XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
{
// TODO: additional text
if( pScNote )
- if( SdrCaptionObj* pCaption = pScNote->GetCaption() )
+ if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) )
if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) );
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
index e065099b2824..457c31d4ab04 100644
--- a/sc/source/filter/excel/xeformula.cxx
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -619,7 +619,7 @@ void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokA
DBG_ASSERT( mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
// clone the passed token array, convert references relative to current cell position
mxOwnScTokArr.reset( rScTokArr.Clone() );
- ScCompiler::MoveRelWrap( *mxOwnScTokArr, GetDocPtr(), *pScBasePos );
+ ScCompiler::MoveRelWrap( *mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
// don't remember pScBasePos in mpScBasePos, shared formulas use real relative refs
break;
default:;
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
index 0d658541eee8..636a83ea3e47 100644
--- a/sc/source/filter/excel/xeroot.cxx
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -32,7 +32,11 @@
#include "precompiled_sc.hxx"
#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
#include <svtools/saveopt.hxx>
+#include <svtools/itemset.hxx>
+#include <svtools/stritem.hxx>
+#include <svtools/eitem.hxx>
#include "xecontent.hxx"
#include "xltracer.hxx"
#include "xeescher.hxx"
@@ -44,8 +48,10 @@
#include "xestyle.hxx"
#include "xeroot.hxx"
-// for filter manager
-#include "excrecds.hxx"
+#include "excrecds.hxx" // for filter manager
+#include "tabprotection.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
// Global data ================================================================
@@ -230,6 +236,40 @@ XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const
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 (GetPassword().Len() > 0)
+ // Password is entered directly into the save dialog.
+ return true;
+
+ return false;
+}
+
+const String XclExpRoot::GetPassword() const
+{
+ SfxItemSet* pSet = GetMedium().GetItemSet();
+ if (!pSet)
+ return String();
+
+ const SfxPoolItem* pItem = NULL;
+ if (SFX_ITEM_SET == pSet->GetItemState(SID_PASSWORD, sal_True, &pItem))
+ {
+ const SfxStringItem* pStrItem = dynamic_cast<const SfxStringItem*>(pItem);
+ if (pStrItem)
+ {
+ // Password from the save dialog.
+ return pStrItem->GetValue();
+ }
+ }
+
+ return String();
+}
+
XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const
{
return IsInGlobals() ? mrExpData.mxGlobLinkMgr : mrExpData.mxLocLinkMgr;
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 9cb054d2ada2..6b2f53c8056a 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -51,6 +51,8 @@
#include <oox/core/tokens.hxx>
#include <formula/grammar.hxx>
+#define DEBUG_XL_ENCRYPTION 0
+
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::io::XOutputStream;
using ::com::sun::star::io::XStream;
@@ -63,7 +65,10 @@ using ::com::sun::star::uno::UNO_QUERY;
using ::rtl::OString;
using ::rtl::OUString;
using ::utl::OStreamWrapper;
+using ::std::vector;
+
using namespace formula;
+
// ============================================================================
XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
@@ -92,16 +97,19 @@ XclExpStream::~XclExpStream()
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;
@@ -113,6 +121,86 @@ void XclExpStream::SetSliceSize( sal_uInt16 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;
@@ -127,9 +215,21 @@ sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
while( bValid && (nBytesLeft > 0) )
{
sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
- sal_Size nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
+ 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;
@@ -265,6 +365,26 @@ void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
Write( &rBuffer[ 0 ], rBuffer.size() );
}
+void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
+{
+ mxEncrypter = xEncrypter;
+}
+
+bool XclExpStream::HasValidEncrypter() const
+{
+ return mxEncrypter.is() && 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" );
@@ -356,6 +476,193 @@ void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
// ============================================================================
+XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] ) :
+ mrRoot(rRoot),
+ mnOldPos(STREAM_SEEK_TO_END),
+ mbValid(false)
+{
+ String aPass = rRoot.GetPassword();
+ if (aPass.Len() == 0)
+ // Empty password. Get the default biff8 password.
+ aPass = XclCryptoHelper::GetBiff8WbProtPassword();
+ Init(aPass, nDocId, nSalt);
+}
+
+XclExpBiff8Encrypter::~XclExpBiff8Encrypter()
+{
+}
+
+bool XclExpBiff8Encrypter::IsValid() const
+{
+ return mbValid;
+}
+
+void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const
+{
+ memcpy(nSaltDigest, mnSaltDigest, 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 String& aPass, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] )
+{
+ memset(mnSaltDigest, 0, sizeof(mnSaltDigest));
+
+ xub_StrLen nLen = aPass.Len();
+ bool bValid = (0 < nLen) && (nLen < 16);
+ if ( bValid )
+ {
+ // transform String to sal_uInt16 array
+ memset(mnPassw, 0, sizeof(mnPassw));
+ for (xub_StrLen nChar = 0; nChar < nLen; ++nChar)
+ mnPassw[nChar] = static_cast<sal_uInt16>(aPass.GetChar(nChar));
+
+ // copy document ID
+ memcpy(mnDocId, nDocId, sizeof(mnDocId));
+
+ // init codec
+ maCodec.InitKey(mnPassw, mnDocId);
+
+ // generate salt hash.
+ ::svx::MSCodec_Std97 aCodec;
+ aCodec.InitKey(mnPassw, mnDocId);
+ aCodec.CreateSaltDigest(nSalt, mnSaltDigest);
+
+ // verify to make sure it's in good shape.
+ bValid = maCodec.VerifyKey(nSalt, mnSaltDigest);
+ }
+
+ mbValid = bValid;
+}
+
+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;
+}
+
rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
{
rtl::OUStringBuffer sBuf;
@@ -666,7 +973,7 @@ sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
if( pRelationshipId )
*pRelationshipId = sRelationshipId;
- sax_fastparser::FSHelperPtr p = openOutputStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
+ sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
@@ -683,14 +990,14 @@ sal_Int32 XclExpXmlStream::getSchemeClr( sal_Int32 /*nColorSchemeToken*/ ) const
return -1;
}
-const oox::vml::DrawingPtr XclExpXmlStream::getDrawings()
+oox::vml::Drawing* XclExpXmlStream::getVmlDrawing()
{
- return oox::vml::DrawingPtr();
+ return 0;
}
const oox::drawingml::Theme* XclExpXmlStream::getCurrentTheme() const
{
- return NULL;
+ return 0;
}
const oox::drawingml::table::TableStyleListPtr XclExpXmlStream::getTableStyles()
diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx
index 663add62426a..4c2551387524 100644
--- a/sc/source/filter/excel/xichart.cxx
+++ b/sc/source/filter/excel/xichart.cxx
@@ -72,6 +72,9 @@
#include "document.hxx"
#include "drwlayer.hxx"
#include "rangeutl.hxx"
+#include "tokenarray.hxx"
+#include "token.hxx"
+#include "compiler.hxx"
#include "fprogressbar.hxx"
#include "xltracer.hxx"
#include "xistream.hxx"
@@ -79,9 +82,6 @@
#include "xistyle.hxx"
#include "xipage.hxx"
#include "xiview.hxx"
-#include "tokenarray.hxx"
-#include "token.hxx"
-#include "compiler.hxx"
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
@@ -643,8 +643,11 @@ Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
// ----------------------------------------------------------------------------
XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot& rRoot ) :
- XclImpChRoot( rRoot ),
- mpTokenArray(static_cast<ScTokenArray*>(NULL))
+ XclImpChRoot( rRoot )
+{
+}
+
+XclImpChSourceLink::~XclImpChSourceLink()
{
}
@@ -655,18 +658,16 @@ void XclImpChSourceLink::ReadChSourceLink( XclImpStream& rStrm )
>> maData.mnFlags
>> maData.mnNumFmtIdx;
+ mxTokenArray.reset();
if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET )
{
// read token array
XclTokenArray aXclTokArr;
rStrm >> aXclTokArr;
- // convert xcl formula tokens to Calc's.
- const ScTokenArray* pTokenArray =
- GetFormulaCompiler().CreateFormula(EXC_FMLATYPE_CHART, aXclTokArr);
-
- if (pTokenArray)
- mpTokenArray.reset(pTokenArray->Clone());
+ // 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
@@ -693,38 +694,37 @@ void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec& rFormats )
sal_uInt16 XclImpChSourceLink::GetCellCount() const
{
- using namespace ::formula;
-
sal_uInt32 nCellCount = 0;
- mpTokenArray->Reset();
- for (const FormulaToken* p = mpTokenArray->First(); p; p = mpTokenArray->Next())
+ if( mxTokenArray.is() )
{
- switch (p->GetType())
+ mxTokenArray->Reset();
+ for( const FormulaToken* pToken = mxTokenArray->First(); pToken; pToken = mxTokenArray->Next() )
{
- case svSingleRef:
- case svExternalSingleRef:
- // single cell
- ++nCellCount;
- break;
- case svDoubleRef:
- case svExternalDoubleRef:
+ switch( pToken->GetType() )
{
- // cell range
- const ScComplexRefData& rData = static_cast<const ScToken*>(p)->GetDoubleRef();
- const ScSingleRefData& s = rData.Ref1;
- const ScSingleRefData& e = rData.Ref2;
- SCsTAB nTab = e.nTab - s.nTab;
- SCsCOL nCol = e.nCol - s.nCol;
- SCsROW nRow = e.nRow - s.nRow;
- nCellCount += static_cast<sal_uInt32>(nCol+1) *
- static_cast<sal_uInt32>(nRow+1) *
- static_cast<sal_uInt32>(nTab+1);
+ 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: ;
}
- break;
- default: ;
}
}
- return limit_cast<sal_uInt16>(nCellCount);
+ return limit_cast< sal_uInt16 >( nCellCount );
}
void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
@@ -743,25 +743,23 @@ Reference< XDataSequence > XclImpChSourceLink::CreateDataSequence( const OUStrin
{
Reference< XDataSequence > xDataSeq;
Reference< XDataProvider > xDataProv = GetDataProvider();
- if( xDataProv.is() )
+ if( xDataProv.is() && mxTokenArray.is() )
{
- if (mpTokenArray)
+ ScCompiler aComp( GetDocPtr(), ScAddress(), *mxTokenArray );
+ aComp.SetGrammar( ::formula::FormulaGrammar::GRAM_ENGLISH );
+ OUStringBuffer aRangeRep;
+ aComp.CreateStringFromTokenArray( aRangeRep );
+ try
{
- ScCompiler aComp(GetDocPtr(), ScAddress(), *mpTokenArray);
- aComp.SetGrammar(::formula::FormulaGrammar::GRAM_ENGLISH);
- OUStringBuffer aBuf;
- aComp.CreateStringFromTokenArray(aBuf);
- xDataSeq = xDataProv->createDataSequenceByRangeRepresentation(
- aBuf.makeStringAndClear());
+ xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aRangeRep.makeStringAndClear() );
+ // set sequence role
+ ScfPropertySet aSeqProp( xDataSeq );
+ aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
}
- else
+ catch( Exception& )
{
// DBG_ERRORFILE( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
}
-
- // set sequence role
- ScfPropertySet aSeqProp( xDataSeq );
- aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
}
return xDataSeq;
}
@@ -1787,6 +1785,14 @@ Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const
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() )
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index 98cb602af5eb..239fbb57a545 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -41,6 +41,7 @@
#include "scitems.hxx"
#include <svx/eeitem.hxx>
#include <svtools/intitem.hxx>
+#include <svtools/stritem.hxx>
#include <svx/flditem.hxx>
#include <svx/fhgtitem.hxx>
#include <svx/wghtitem.hxx>
@@ -67,6 +68,12 @@
#include "xiname.hxx"
#include "excform.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
// Shared string table ========================================================
@@ -1089,12 +1096,191 @@ ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm ); break;
default: DBG_ERROR_BIFF();
};
+
+ if (!xDecr.is())
+ return EXC_ENCR_ERROR_UNSUPP_CRYPT;
+
// set decrypter at import stream
rStrm.SetDecrypter( xDecr );
- // remember encryption for export
- rStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true;
- return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
+ // Store the document password for export.
+ SfxItemSet* pSet = rStrm.GetRoot().GetDocShell()->GetMedium()->GetItemSet();
+ if (pSet)
+ {
+ String aPass = xDecr->GetPassword();
+ pSet->Put( SfxStringItem(SID_PASSWORD, aPass) );
+ }
+
+ return xDecr->GetError();
+}
+
+// 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 ENABLE_SHEET_PROTECTION
+ 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);
+ }
+#endif
+
+ // 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(19);
+ 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);
+
+#if ENABLE_SHEET_PROTECTION
+ // 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);
+ }
+#endif
+
+ // 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;
}
// ============================================================================
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index 84a385cabd97..eb8e1f677fce 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -1653,23 +1653,19 @@ void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags
void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
{
- SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj );
- if( pTextObj && maScPos.IsValid() )
+ // create formatted text
+ XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
+ OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
+ if( maScPos.IsValid() && pOutlinerObj )
{
- if( ScPostIt* pNote = GetDoc().GetOrCreateNote( maScPos ) )
- {
- if( SdrCaptionObj* pCaption = pNote->GetCaption() )
- {
- // create formatted text
- XclImpTextObj::DoPreProcessSdrObj( rDffConv, *pCaption );
- // set textbox rectangle from imported object
- pCaption->NbcSetLogicRect( pTextObj->GetLogicRect() );
- // copy all items from imported object (resets shadow items)
- pNote->SetCaptionItems( pTextObj->GetMergedItemSet() );
- // move caption to correct layer (visible/hidden)
- pNote->ShowCaption( ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ) );
- }
- }
+ // 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 );
}
}
@@ -1711,7 +1707,7 @@ void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) co
aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
// control visible and printable?
-// aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() ); // waiting for #i88878#
+ aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
// sheet links
@@ -3905,7 +3901,7 @@ void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm )
nTotalLen = 0;
}
}
- ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false );
+ ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
}
}
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
index 16a3edf46373..2c2426382178 100644
--- a/sc/source/filter/excel/xilink.cxx
+++ b/sc/source/filter/excel/xilink.cxx
@@ -263,6 +263,7 @@ 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();
diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx
index c64c10466d56..f6723f1d3887 100644
--- a/sc/source/filter/excel/xiroot.cxx
+++ b/sc/source/filter/excel/xiroot.cxx
@@ -52,6 +52,7 @@
XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ),
+ mbPassQueried( false ),
mbHasCodePage( false )
{
}
@@ -86,6 +87,8 @@ XclImpRoot::XclImpRoot( XclImpRootData& rImpRootData ) :
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() ) );
@@ -238,6 +241,18 @@ XclImpPivotTableManager& XclImpRoot::GetPivotTableManager() const
return *mrImpData.mxPTableMgr;
}
+XclImpSheetProtectBuffer& XclImpRoot::GetSheetProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxTabProtect.is(), "XclImpRoot::GetSheetProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxTabProtect;
+}
+
+XclImpDocProtectBuffer& XclImpRoot::GetDocProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxDocProtect.is(), "XclImpRoot::GetDocProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxDocProtect;
+}
+
XclImpPageSettings& XclImpRoot::GetPageSettings() const
{
return *mrImpData.mxPageSett;
@@ -261,5 +276,16 @@ String XclImpRoot::GetScAddInName( const String& rXclName ) const
return rXclName;
}
+const String& XclImpRoot::QueryPassword() const
+{
+ if( !mrImpData.mbPassQueried )
+ {
+ mrImpData.maPassw = ScfApiHelper::QueryPasswordForMedium( GetMedium() );
+ // set to true, even if dialog has been cancelled (never ask twice)
+ mrImpData.mbPassQueried = true;
+ }
+ return mrImpData.maPassw;
+}
+
// ============================================================================
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
index b7f0d3841645..e7780c065118 100644
--- a/sc/source/filter/excel/xistream.cxx
+++ b/sc/source/filter/excel/xistream.cxx
@@ -36,6 +36,8 @@
#include "xlstring.hxx"
#include "xiroot.hxx"
+#include <vector>
+
// ============================================================================
// Decryption
// ============================================================================
@@ -97,11 +99,21 @@ sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nByte
return nRet;
}
+const String XclImpDecrypter::GetPassword() const
+{
+ return maPass;
+}
+
void XclImpDecrypter::SetHasValidPassword( bool bValid )
{
mnError = bValid ? ERRCODE_NONE : EXC_ENCR_ERROR_WRONG_PASS;
}
+void XclImpDecrypter::SetPassword( const String& rPass )
+{
+ maPass = rPass;
+}
+
// ----------------------------------------------------------------------------
XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpRoot& rRoot, sal_uInt16 nKey, sal_uInt16 nHash )
@@ -157,6 +169,9 @@ void XclImpBiff5Decrypter::Init( const ByteString& rPass, sal_uInt16 nKey, sal_u
// init codec
maCodec.InitKey( mpnPassw );
bValid = maCodec.VerifyKey( nKey, nHash );
+
+ String aUniPass( rPass, RTL_TEXTENCODING_MS_1252 );
+ SetPassword( aUniPass );
}
SetHasValidPassword( bValid );
@@ -255,6 +270,8 @@ void XclImpBiff8Decrypter::Init(
// init codec
maCodec.InitKey( mpnPassw, mpnDocId );
bValid = maCodec.VerifyKey( pnSaltData, pnSaltHash );
+
+ SetPassword(rPass);
}
SetHasValidPassword( bValid );
diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx
index e41ce7711709..8a590fda4bfc 100644
--- a/sc/source/filter/excel/xlchart.cxx
+++ b/sc/source/filter/excel/xlchart.cxx
@@ -511,6 +511,7 @@ 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_PIE[] = "com.sun.star.chart2.PieChartType";
const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
+const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
@@ -529,7 +530,7 @@ static const XclChTypeInfo spTypeInfos[] =
{ 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_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, 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 }
};
diff --git a/sc/source/filter/excel/xlpage.cxx b/sc/source/filter/excel/xlpage.cxx
index 56ef285228b2..d1bea1addcec 100644
--- a/sc/source/filter/excel/xlpage.cxx
+++ b/sc/source/filter/excel/xlpage.cxx
@@ -44,7 +44,7 @@
struct XclPaperSize
{
- SvxPaper mePaper; /// SVX paper size identifier.
+ Paper mePaper; /// SVX paper size identifier.
long mnWidth; /// Paper width in twips.
long mnHeight; /// Paper height in twips.
};
@@ -54,97 +54,114 @@ struct XclPaperSize
static const XclPaperSize pPaperSizeTable[] =
{
-/* 0*/ { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_LETTER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Small
- { SVX_PAPER_TABLOID, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // Tabloid
- { SVX_PAPER_USER, IN2TWIPS( 17 ), IN2TWIPS( 11 ) }, // Ledger
-/* 5*/ { SVX_PAPER_LEGAL, IN2TWIPS( 8.5 ), IN2TWIPS( 14 ) }, // Legal
- { SVX_PAPER_USER, IN2TWIPS( 5.5 ), IN2TWIPS( 8.5 ) }, // Statement
- { SVX_PAPER_USER, IN2TWIPS( 7.25 ), IN2TWIPS( 10.5 ) }, // Executive
- { SVX_PAPER_A3, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3
- { SVX_PAPER_A4, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4
-/* 10*/ { SVX_PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Small
- { SVX_PAPER_A5, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5
- { SVX_PAPER_B4_JIS, MM2TWIPS( 257 ), MM2TWIPS( 364 ) }, // B4 (JIS)
- { SVX_PAPER_B5_JIS, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS)
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // Folio
-/* 15*/ { SVX_PAPER_USER, MM2TWIPS( 215 ), MM2TWIPS( 275 ) }, // Quarto
- { SVX_PAPER_USER, IN2TWIPS( 10 ), IN2TWIPS( 14 ) }, // 10x14
- { SVX_PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 17 ) }, // 11x17
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Note
- { SVX_PAPER_COM9, IN2TWIPS( 3.875 ), IN2TWIPS( 8.875 ) }, // Envelope #9
-/* 20*/ { SVX_PAPER_COM10, IN2TWIPS( 4.125 ), IN2TWIPS( 9.5 ) }, // Envelope #10
- { SVX_PAPER_COM11, IN2TWIPS( 4.5 ), IN2TWIPS( 10.375 ) }, // Envelope #11
- { SVX_PAPER_COM12, IN2TWIPS( 4.75 ), IN2TWIPS( 11 ) }, // Envelope #12
- { SVX_PAPER_USER, IN2TWIPS( 5 ), IN2TWIPS( 11.5 ) }, // Envelope #14
- { SVX_PAPER_C, IN2TWIPS( 17 ), IN2TWIPS( 22 ) }, // ANSI-C
-/* 25*/ { SVX_PAPER_D, IN2TWIPS( 22 ), IN2TWIPS( 34 ) }, // ANSI-D
- { SVX_PAPER_E, IN2TWIPS( 34 ), IN2TWIPS( 44 ) }, // ANSI-E
- { SVX_PAPER_DL, MM2TWIPS( 110 ), MM2TWIPS( 220 ) }, // Envelope DL
- { SVX_PAPER_C5, MM2TWIPS( 162 ), MM2TWIPS( 229 ) }, // Envelope C5
- { SVX_PAPER_USER, MM2TWIPS( 324 ), MM2TWIPS( 458 ) }, // Envelope C3
-/* 30*/ { SVX_PAPER_C4, MM2TWIPS( 229 ), MM2TWIPS( 324 ) }, // Envelope C4
- { SVX_PAPER_C6, MM2TWIPS( 114 ), MM2TWIPS( 162 ) }, // Envelope C6
- { SVX_PAPER_C65, MM2TWIPS( 114 ), MM2TWIPS( 229 ) }, // Envelope C65
- { SVX_PAPER_B4, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
- { SVX_PAPER_B5, MM2TWIPS( 176 ), MM2TWIPS( 250 ) }, // B5 (ISO)
-/* 35*/ { SVX_PAPER_B6, MM2TWIPS( 125 ), MM2TWIPS( 176 ) }, // B6 (ISO)
- { SVX_PAPER_USER, MM2TWIPS( 110 ), MM2TWIPS( 230 ) }, // Envelope Italy
- { SVX_PAPER_MONARCH, IN2TWIPS( 3.875 ), IN2TWIPS( 7.5 ) }, // Envelope Monarch
- { SVX_PAPER_COM675, IN2TWIPS( 3.625 ), IN2TWIPS( 6.5 ) }, // 6 3/4 Envelope
- { SVX_PAPER_USER, IN2TWIPS( 14.875 ), IN2TWIPS( 11 ) }, // US Std Fanfold
-/* 40*/ { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 12 ) }, // German Std Fanfold
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 13 ) }, // German Legal Fanfold
- { SVX_PAPER_B4, MM2TWIPS( 250 ), MM2TWIPS( 353 ) }, // B4 (ISO)
- { SVX_PAPER_USER, MM2TWIPS( 100 ), MM2TWIPS( 148 ) }, // Japanese Postcard
- { SVX_PAPER_USER, IN2TWIPS( 9 ), IN2TWIPS( 11 ) }, // 9x11
-/* 45*/ { SVX_PAPER_USER, IN2TWIPS( 10 ), IN2TWIPS( 11 ) }, // 10x11
- { SVX_PAPER_USER, IN2TWIPS( 15 ), IN2TWIPS( 11 ) }, // 15x11
- { SVX_PAPER_USER, MM2TWIPS( 220 ), MM2TWIPS( 220 ) }, // Envelope Invite
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
-/* 50*/ { SVX_PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra
- { SVX_PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 15 ) }, // Legal Extra
- { SVX_PAPER_USER, IN2TWIPS( 11.69 ), IN2TWIPS( 18 ) }, // Tabloid Extra
- { SVX_PAPER_USER, MM2TWIPS( 235 ), MM2TWIPS( 322 ) }, // A4 Extra
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 11 ) }, // Letter Transverse
-/* 55*/ { SVX_PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 297 ) }, // A4 Transverse
- { SVX_PAPER_USER, IN2TWIPS( 9.5 ), IN2TWIPS( 12 ) }, // Letter Extra Transverse
- { SVX_PAPER_USER, MM2TWIPS( 227 ), MM2TWIPS( 356 ) }, // Super A/A4
- { SVX_PAPER_USER, MM2TWIPS( 305 ), MM2TWIPS( 487 ) }, // Super B/A3
- { SVX_PAPER_USER, IN2TWIPS( 8.5 ), IN2TWIPS( 12.69 ) }, // Letter Plus
-/* 60*/ { SVX_PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 330 ) }, // A4 Plus
- { SVX_PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 210 ) }, // A5 Transverse
- { SVX_PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 257 ) }, // B5 (JIS) Transverse
- { SVX_PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra
- { SVX_PAPER_USER, MM2TWIPS( 174 ), MM2TWIPS( 235 ) }, // A5 Extra
-/* 65*/ { SVX_PAPER_USER, MM2TWIPS( 201 ), MM2TWIPS( 276 ) }, // B5 (ISO) Extra
- { SVX_PAPER_A2, MM2TWIPS( 420 ), MM2TWIPS( 594 ) }, // A2
- { SVX_PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 420 ) }, // A3 Transverse
- { SVX_PAPER_USER, MM2TWIPS( 322 ), MM2TWIPS( 445 ) }, // A3 Extra Transverse
- { SVX_PAPER_USER, MM2TWIPS( 200 ), MM2TWIPS( 148 ) }, // Double Japanese Postcard
-/* 70*/ { SVX_PAPER_USER, MM2TWIPS( 105 ), MM2TWIPS( 148 ) }, // A6
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
-/* 75*/ { SVX_PAPER_USER, IN2TWIPS( 11 ), IN2TWIPS( 8.5 ) }, // Letter Rotated
- { SVX_PAPER_USER, MM2TWIPS( 420 ), MM2TWIPS( 297 ) }, // A3 Rotated
- { SVX_PAPER_USER, MM2TWIPS( 297 ), MM2TWIPS( 210 ) }, // A4 Rotated
- { SVX_PAPER_USER, MM2TWIPS( 210 ), MM2TWIPS( 148 ) }, // A5 Rotated
- { SVX_PAPER_USER, MM2TWIPS( 364 ), MM2TWIPS( 257 ) }, // B4 (JIS) Rotated
-/* 80*/ { SVX_PAPER_USER, MM2TWIPS( 257 ), MM2TWIPS( 182 ) }, // B5 (JIS) Rotated
- { SVX_PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 100 ) }, // Japanese Postcard Rotated
- { SVX_PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 200 ) }, // Double Japanese Postcard Rotated
- { SVX_PAPER_USER, MM2TWIPS( 148 ), MM2TWIPS( 105 ) }, // A6 Rotated
- { SVX_PAPER_USER, 0, 0 }, // undefined
-/* 85*/ { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_USER, 0, 0 }, // undefined
- { SVX_PAPER_B6_JIS, MM2TWIPS( 128 ), MM2TWIPS( 182 ) }, // B6 (JIS)
- { SVX_PAPER_USER, MM2TWIPS( 182 ), MM2TWIPS( 128 ) }, // B6 (JIS) Rotated
-/* 90*/ { SVX_PAPER_USER, IN2TWIPS( 12 ), IN2TWIPS( 11 ) } // 12x11
+/* 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
@@ -193,15 +210,14 @@ Size XclPageData::GetScPaperSize() const
pEntry += mnPaperSize;
Size aSize;
- if( pEntry->mePaper == SVX_PAPER_USER )
+ 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::GetPaperSize( SvxPaperInfo::GetDefaultSvxPaper(
- Application::GetSettings().GetLanguage() ) );
+ aSize = SvxPaperInfo::GetDefaultPaperSize();
if( !mbPortrait )
::std::swap( aSize.Width(), aSize.Height() );
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx
index bdc75df21c13..8f5ddadd0370 100644
--- a/sc/source/filter/excel/xlroot.cxx
+++ b/sc/source/filter/excel/xlroot.cxx
@@ -92,8 +92,7 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
mxRD( new RootData ),//!
mnCharWidth( 110 ),
mnScTab( 0 ),
- mbExport( bExport ),
- mbHasPassw( false )
+ mbExport( bExport )
{
// default script type, e.g. for empty cells
switch( ScGlobal::GetDefaultScriptType() )
@@ -199,17 +198,6 @@ void XclRoot::SetCharWidth( const XclFontData& rFontData )
}
}
-const String& XclRoot::QueryPassword() const
-{
- if( !mrData.mbHasPassw )
- {
- mrData.maPassw = ScfApiHelper::QueryPasswordForMedium( GetMedium() );
- // set to true, even if dialog has been cancelled (never ask twice)
- mrData.mbHasPassw = true;
- }
- return mrData.maPassw;
-}
-
bool XclRoot::HasVbaStorage() const
{
SotStorageRef xRootStrg = GetRootStorage();
diff --git a/sc/source/filter/excel/xlstyle.cxx b/sc/source/filter/excel/xlstyle.cxx
index e8fab52ca819..4e5bf9b7570a 100644
--- a/sc/source/filter/excel/xlstyle.cxx
+++ b/sc/source/filter/excel/xlstyle.cxx
@@ -664,6 +664,8 @@ void XclFontPropSetHelper::ReadFontProperties( XclFontData& rFontData,
sal_Int16 nApiEscapement = 0;
sal_Int8 nApiEscHeight = 0;
maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
+ maHlpChEscapement.ReadFromPropertySet( rPropSet );
maHlpChEscapement >> nApiEscapement >> nApiEscHeight;
rFontData.SetApiEscapement( nApiEscapement );
}
diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx
index abc7d2b21392..5591e8ec993e 100644
--- a/sc/source/filter/html/htmlimp.cxx
+++ b/sc/source/filter/html/htmlimp.cxx
@@ -99,7 +99,7 @@ ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScR
if ( !aPageSize.Width() || !aPageSize.Height() )
{
DBG_ERRORFILE("PageSize Null ?!?!?");
- aPageSize = SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 );
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
}
aPageSize.Width() -= nLeftMargin + nRightMargin;
aPageSize.Height() -= nTopMargin + nBottomMargin;
@@ -109,7 +109,7 @@ ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScR
{
DBG_ERRORFILE("kein StyleSheet?!?");
aPageSize = pDefaultDev->LogicToPixel(
- SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 ), MapMode( MAP_TWIP ) );
+ SvxPaperInfo::GetPaperSize( PAPER_A4 ), MapMode( MAP_TWIP ) );
}
if( bCalcWidthHeight )
mpParser = new ScHTMLLayoutParser( mpEngine, rBaseURL, aPageSize, pDocP );
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
index 7fed8e84942a..36bbfe1d2787 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -49,10 +49,10 @@
#include <svx/udlnitem.hxx>
#include <svx/wghtitem.hxx>
#include <svx/boxitem.hxx>
-#include <sfx2/frmhtml.hxx>
#include <sfx2/objsh.hxx>
#include <svtools/eitem.hxx>
#include <svtools/filter.hxx>
+#include <svtools/parhtml.hxx>
#include <svtools/htmlkywd.hxx>
#include <svtools/htmltokn.h>
#include <sfx2/docfile.hxx>
@@ -1544,25 +1544,12 @@ void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
{
case HTML_META:
{
- USHORT nContentOpt = HTML_O_CONTENT;
- rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
HTMLParser* pParser = (HTMLParser*) pInfo->pParser;
- const HTMLOptions* pOptions = pParser->GetOptions( &nContentOpt );
uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
- SfxFrameHTMLParser::ParseMetaOptions(
+ pParser->ParseMetaOptions(
xDPS->getDocumentProperties(),
- mpDoc->GetDocumentShell()->GetHeaderAttributes(),
- pOptions, eEnc );
- // If the encoding is set by a META tag, it may only overwrite the
- // current encoding if both, the current and the new encoding, are 1-BYTE
- // encodings. Everything else cannot lead to reasonable results.
- if ( rtl_isOctetTextEncoding( eEnc ) &&
- rtl_isOctetTextEncoding( pParser->GetSrcEncoding() ) )
- {
- eEnc = GetExtendedCompatibilityTextEncoding( eEnc );
- pParser->SetSrcEncoding( eEnc );
- }
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
}
break;
case HTML_TITLE_ON:
@@ -1728,31 +1715,29 @@ void ScHTMLLayoutParser::ProcToken( ImportInfo* pInfo )
// ============================================================================
template< typename Type >
-inline Type bound( const Type& rValue, const Type& rMin, const Type& rMax )
+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.
+ 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 );
+ 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++();
+ 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 ) :
@@ -1777,7 +1762,6 @@ ScHTMLOptionIterator& ScHTMLOptionIterator::operator++()
return *this;
}
-
// ============================================================================
ScHTMLEntry::ScHTMLEntry( const SfxItemSet& rItemSet, ScHTMLTableId nTableId ) :
@@ -1832,14 +1816,15 @@ void ScHTMLEntry::Strip( const EditEngine& rEditEngine )
}
}
-
// ============================================================================
/** A map of ScHTMLTable objects.
- @descr 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. */
+
+ 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:
@@ -1851,36 +1836,35 @@ public:
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.
+ 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();
+ 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(); }
+ 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;
+ 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 );
+ 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; }
+ inline void SetCurrTable( ScHTMLTable* pTable ) const
+ { if( pTable ) mpCurrTable = pTable; }
};
-
// ----------------------------------------------------------------------------
ScHTMLTableMap::ScHTMLTableMap( ScHTMLTable& rParentTable ) :
@@ -1921,28 +1905,29 @@ ScHTMLTable* ScHTMLTableMap::CreateTable( const ImportInfo& rInfo, bool bPreForm
return pTable;
}
-
// ----------------------------------------------------------------------------
/** Simplified forward iterator for convenience.
- @descr Before the iterator can be dereferenced, it must be tested with the
- is() method. The iterator may be invalid directly after construction
- (i.e. empty container). */
+
+ 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
{
-private:
- ScHTMLTableMap::const_iterator maIter;
- ScHTMLTableMap::const_iterator maEnd;
-
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 );
+ explicit ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
- inline bool is() const { return maIter != maEnd; }
- inline ScHTMLTable* operator->() { return maIter->second.get(); }
- inline ScHTMLTable& operator*() { return *maIter->second; }
+ inline bool is() const { return 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;
};
ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap )
@@ -1954,7 +1939,6 @@ ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap )
}
}
-
// ============================================================================
ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
@@ -1964,7 +1948,6 @@ ScHTMLTableAutoId::ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId ) :
++mrnUnusedId;
}
-
// ----------------------------------------------------------------------------
ScHTMLTable::ScHTMLTable( ScHTMLTable& rParentTable, const ImportInfo& rInfo, bool bPreFormText ) :
@@ -2023,7 +2006,7 @@ ScHTMLTable::ScHTMLTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParse
// open the first "cell" of the document
ImplRowOn();
ImplDataOn( ScHTMLSize( 1, 1 ) );
- mpCurrEntry = CreateEntry();
+ mxCurrEntry = CreateEntry();
}
ScHTMLTable::~ScHTMLTable()
@@ -2033,45 +2016,46 @@ ScHTMLTable::~ScHTMLTable()
const SfxItemSet& ScHTMLTable::GetCurrItemSet() const
{
// first try cell item set, then row item set, then table item set
- return mpDataItemSet.get() ? *mpDataItemSet : (mpRowItemSet.get() ? *mpRowItemSet : maTableItemSet);
+ return mxDataItemSet.get() ? *mxDataItemSet : (mxRowItemSet.get() ? *mxRowItemSet : maTableItemSet);
}
ScHTMLSize ScHTMLTable::GetSpan( const ScHTMLPos& rCellPos ) const
{
ScHTMLSize aSpan( 1, 1 );
- if( ScRange* pRange = maLockList.Find( rCellPos.MakeAddr() ) )
+ ScRange* pRange = 0;
+ 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 mpNestedTables.get() ? mpNestedTables->FindTable( nTableId, true ) : 0;
+ return mxNestedTables.get() ? mxNestedTables->FindTable( nTableId, true ) : 0;
}
void ScHTMLTable::PutItem( const SfxPoolItem& rItem )
{
- DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::PutItem - no current entry" );
- if( mpCurrEntry.get() && mpCurrEntry->IsEmpty() )
- mpCurrEntry->GetItemSet().Put( 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( mpCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
- if( mpCurrEntry.get() )
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PutText - no current entry" );
+ if( mxCurrEntry.get() )
{
- if( !mpCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
- mpCurrEntry->AdjustStart( rInfo );
+ if( !mxCurrEntry->HasContents() && IsSpaceCharInfo( rInfo ) )
+ mxCurrEntry->AdjustStart( rInfo );
else
- mpCurrEntry->AdjustEnd( rInfo );
+ mxCurrEntry->AdjustEnd( rInfo );
}
}
void ScHTMLTable::InsertPara( const ImportInfo& rInfo )
{
- if( mpCurrEntry.get() && mbDataOn && !IsEmptyCell() )
- mpCurrEntry->SetImportAlways();
+ if( mxCurrEntry.get() && mbDataOn && !IsEmptyCell() )
+ mxCurrEntry->SetImportAlways();
PushEntry( rInfo );
CreateNewEntry( rInfo );
InsertLeadingEmptyLine();
@@ -2097,10 +2081,10 @@ void ScHTMLTable::InsertLeadingEmptyLine()
void ScHTMLTable::AnchorOn()
{
- DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::AnchorOn - no current entry" );
// don't skip entries with single hyperlinks
- if( mpCurrEntry.get() )
- mpCurrEntry->SetImportAlways();
+ if( mxCurrEntry.get() )
+ mxCurrEntry->SetImportAlways();
}
ScHTMLTable* ScHTMLTable::TableOn( const ImportInfo& rInfo )
@@ -2131,7 +2115,7 @@ void ScHTMLTable::RowOn( const ImportInfo& rInfo )
if( mpParentTable && !mbPreFormText ) // no rows allowed in global and preformatted tables
{
ImplRowOn();
- ProcessFormatOptions( *mpRowItemSet, rInfo );
+ ProcessFormatOptions( *mxRowItemSet, rInfo );
}
CreateNewEntry( rInfo );
}
@@ -2157,10 +2141,10 @@ void ScHTMLTable::DataOn( const ImportInfo& rInfo )
switch( aIter->GetToken() )
{
case HTML_O_COLSPAN:
- aSpanSize.mnCols = static_cast< SCCOL >( bound( aIter->GetString().ToInt32(), static_cast<sal_Int32>(1), static_cast<sal_Int32>(256) ) );
+ aSpanSize.mnCols = static_cast< SCCOL >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
break;
case HTML_O_ROWSPAN:
- aSpanSize.mnRows = static_cast< SCROW >( bound( aIter->GetString().ToInt32(), static_cast<sal_Int32>(1), static_cast<sal_Int32>(256) ) );
+ aSpanSize.mnRows = static_cast< SCROW >( getLimitedValue< sal_Int32 >( aIter->GetString().ToInt32(), 1, 256 ) );
break;
case HTML_O_SDVAL:
pValStr.reset( new String( aIter->GetString() ) );
@@ -2172,10 +2156,10 @@ void ScHTMLTable::DataOn( const ImportInfo& rInfo )
}
ImplDataOn( aSpanSize );
- ProcessFormatOptions( *mpDataItemSet, rInfo );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
CreateNewEntry( rInfo );
- mpCurrEntry->pValStr = pValStr.release();
- mpCurrEntry->pNumStr = pNumStr.release();
+ mxCurrEntry->pValStr = pValStr.release();
+ mxCurrEntry->pNumStr = pNumStr.release();
}
else
CreateNewEntry( rInfo );
@@ -2199,7 +2183,7 @@ void ScHTMLTable::BodyOn( const ImportInfo& rInfo )
ImplRowOn();
if( bPushed || !mbDataOn )
ImplDataOn( ScHTMLSize( 1, 1 ) );
- ProcessFormatOptions( *mpDataItemSet, rInfo );
+ ProcessFormatOptions( *mxDataItemSet, rInfo );
}
CreateNewEntry( rInfo );
}
@@ -2233,29 +2217,33 @@ ScHTMLTable* ScHTMLTable::CloseTable( const ImportInfo& rInfo )
SCCOLROW ScHTMLTable::GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
{
- const ScSizeVec& rSizes = maSizes[ eOrient ];
- return (static_cast< size_t >( nCellPos ) < rSizes.size()) ? rSizes[ nCellPos ] : 0;
+ 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
{
- SCCOLROW nSize = 0;
- for( SCCOLROW nCellPos = nCellBegin; nCellPos < nCellEnd; ++nCellPos )
- nSize += GetDocSize( eOrient, nCellPos );
- return nSize;
+ 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
{
- return GetDocSize( eOrient, 0, maSize.Get( eOrient ) );
+ const ScSizeVec& rSizes = maCumSizes[ eOrient ];
+ return rSizes.empty() ? 0 : rSizes.back();
}
ScHTMLSize ScHTMLTable::GetDocSize( const ScHTMLPos& rCellPos ) const
{
- ScHTMLSize aCellSpan( GetSpan( rCellPos ) );
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
return ScHTMLSize(
- static_cast<SCCOL>(GetDocSize( tdCol, rCellPos.mnCol, rCellPos.mnCol + aCellSpan.mnCols )),
- static_cast<SCROW>(GetDocSize( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow), static_cast<SCCOLROW>(rCellPos.mnRow + aCellSpan.mnRows) )) );
+ 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
@@ -2265,13 +2253,15 @@ SCCOLROW ScHTMLTable::GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos ) const
ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
{
- return ScHTMLPos( static_cast<SCCOL>(GetDocPos( tdCol, static_cast<SCCOLROW>(rCellPos.mnCol)) ), static_cast<SCROW>(GetDocPos( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow) )) );
+ 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, GetDocSize( tdRow ) - 1, 0 );
+ 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
@@ -2294,8 +2284,8 @@ void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos
{
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;
+ 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;
@@ -2317,11 +2307,10 @@ void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos
}
}
- for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
aIter->ApplyCellBorders( pDoc, rFirstPos );
}
-
// ----------------------------------------------------------------------------
bool ScHTMLTable::IsEmptyCell() const
@@ -2341,37 +2330,39 @@ ScHTMLTable::ScHTMLEntryPtr ScHTMLTable::CreateEntry() const
void ScHTMLTable::CreateNewEntry( const ImportInfo& rInfo )
{
- DBG_ASSERT( !mpCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
- mpCurrEntry = CreateEntry();
- mpCurrEntry->aSel = rInfo.aSelection;
+ DBG_ASSERT( !mxCurrEntry.get(), "ScHTMLTable::CreateNewEntry - old entry still present" );
+ mxCurrEntry = CreateEntry();
+ mxCurrEntry->aSel = rInfo.aSelection;
}
-void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rpEntry )
+void ScHTMLTable::ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rxEntry )
{
// HTML entry list does not own the entries
- rEntryList.push_back( rpEntry.get() );
+ rEntryList.push_back( rxEntry.get() );
// mrEEParseList (reference to member of ScEEParser) owns the entries
- mrEEParseList.Insert( rpEntry.release(), LIST_APPEND );
+ mrEEParseList.Insert( rxEntry.release(), LIST_APPEND );
}
-bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rpEntry )
+bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rxEntry )
{
bool bPushed = false;
- if( rpEntry.get() && rpEntry->HasContents() )
+ if( rxEntry.get() && rxEntry->HasContents() )
{
if( mpCurrEntryList )
{
if( mbPushEmptyLine )
{
- ScHTMLEntryPtr pEmptyEntry = CreateEntry();
- ImplPushEntryToList( *mpCurrEntryList, pEmptyEntry );
+ ScHTMLEntryPtr xEmptyEntry = CreateEntry();
+ ImplPushEntryToList( *mpCurrEntryList, xEmptyEntry );
mbPushEmptyLine = false;
}
- ImplPushEntryToList( *mpCurrEntryList, rpEntry );
+ ImplPushEntryToList( *mpCurrEntryList, rxEntry );
bPushed = true;
}
else if( mpParentTable )
- bPushed = mpParentTable->PushEntry( rpEntry );
+ {
+ bPushed = mpParentTable->PushEntry( rxEntry );
+ }
else
{
DBG_ERRORFILE( "ScHTMLTable::PushEntry - cannot push entry, no parent found" );
@@ -2382,24 +2373,24 @@ bool ScHTMLTable::PushEntry( ScHTMLEntryPtr& rpEntry )
bool ScHTMLTable::PushEntry( const ImportInfo& rInfo, bool bLastInCell )
{
- DBG_ASSERT( mpCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
+ DBG_ASSERT( mxCurrEntry.get(), "ScHTMLTable::PushEntry - no current entry" );
bool bPushed = false;
- if( mpCurrEntry.get() )
+ if( mxCurrEntry.get() )
{
- mpCurrEntry->AdjustEnd( rInfo );
- mpCurrEntry->Strip( mrEditEngine );
+ mxCurrEntry->AdjustEnd( rInfo );
+ mxCurrEntry->Strip( mrEditEngine );
// import entry always, if it is the last in cell, and cell is still empty
if( bLastInCell && IsEmptyCell() )
{
- mpCurrEntry->SetImportAlways();
+ mxCurrEntry->SetImportAlways();
// don't insert empty lines before single empty entries
- if( mpCurrEntry->IsEmpty() )
+ if( mxCurrEntry->IsEmpty() )
mbPushEmptyLine = false;
}
- bPushed = PushEntry( mpCurrEntry );
- mpCurrEntry.reset();
+ bPushed = PushEntry( mxCurrEntry );
+ mxCurrEntry.reset();
}
return bPushed;
}
@@ -2410,27 +2401,27 @@ bool ScHTMLTable::PushTableEntry( ScHTMLTableId nTableId )
bool bPushed = false;
if( nTableId != SC_HTML_GLOBAL_TABLE )
{
- ScHTMLEntryPtr pEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
- bPushed = PushEntry( pEntry );
+ ScHTMLEntryPtr xEntry( new ScHTMLEntry( maTableItemSet, nTableId ) );
+ bPushed = PushEntry( xEntry );
}
return bPushed;
}
ScHTMLTable* ScHTMLTable::GetExistingTable( ScHTMLTableId nTableId ) const
{
- ScHTMLTable* pTable = ((nTableId != SC_HTML_GLOBAL_TABLE) && mpNestedTables.get()) ?
- mpNestedTables->FindTable( nTableId, false ) : 0;
+ 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( !mpNestedTables.get() )
- mpNestedTables.reset( new ScHTMLTableMap( *this ) );
+ if( !mxNestedTables.get() )
+ mxNestedTables.reset( new ScHTMLTableMap( *this ) );
if( bPreFormText ) // enclose new preformatted table with empty lines
InsertLeadingEmptyLine();
- return mpNestedTables->CreateTable( rInfo, bPreFormText );
+ return mxNestedTables->CreateTable( rInfo, bPreFormText );
}
void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
@@ -2438,20 +2429,29 @@ void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
ScRange* pRange;
// find an unused cell
- while( (pRange = maLockList.Find( maCurrCell.MakeAddr() )) != 0 )
+ while( (pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0 )
maCurrCell.mnCol = pRange->aEnd.Col() + 1;
mpCurrEntryList = &maEntryMap[ maCurrCell ];
// try to find collisions, shrink existing ranges
SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols;
for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() )
- if( (pRange = maLockList.Find( aAddr )) != 0 )
+ if( (pRange = maVMergedCells.Find( aAddr )) != 0 )
pRange->aEnd.SetRow( maCurrCell.mnRow - 1 );
- // insert the new range into the lock list
+ // insert the new range into the cell lists
ScRange aNewRange( maCurrCell.MakeAddr() );
aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
- maLockList.Append( aNewRange );
+ if( rSpanSize.mnCols > 1 )
+ {
+ maVMergedCells.Append( aNewRange );
+ }
+ else
+ {
+ if( rSpanSize.mnRows > 1 )
+ maHMergedCells.Append( aNewRange );
+ maUsedCells.Join( aNewRange );
+ }
// adjust table size
maSize.mnCols = ::std::max< SCCOL >( maSize.mnCols, aNewRange.aEnd.Col() + 1 );
@@ -2462,7 +2462,7 @@ void ScHTMLTable::ImplRowOn()
{
if( mbRowOn )
ImplRowOff();
- mpRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
+ mxRowItemSet.reset( new SfxItemSet( maTableItemSet ) );
maCurrCell.mnCol = 0;
mbRowOn = true;
mbDataOn = false;
@@ -2474,7 +2474,7 @@ void ScHTMLTable::ImplRowOff()
ImplDataOff();
if( mbRowOn )
{
- mpRowItemSet.reset();
+ mxRowItemSet.reset();
++maCurrCell.mnRow;
mbRowOn = mbDataOn = false;
}
@@ -2486,7 +2486,7 @@ void ScHTMLTable::ImplDataOn( const ScHTMLSize& rSpanSize )
ImplDataOff();
if( !mbRowOn )
ImplRowOn();
- mpDataItemSet.reset( new SfxItemSet( *mpRowItemSet ) );
+ mxDataItemSet.reset( new SfxItemSet( *mxRowItemSet ) );
InsertNewCell( rSpanSize );
mbDataOn = true;
mbPushEmptyLine = false;
@@ -2496,7 +2496,7 @@ void ScHTMLTable::ImplDataOff()
{
if( mbDataOn )
{
- mpDataItemSet.reset();
+ mxDataItemSet.reset();
++maCurrCell.mnCol;
mpCurrEntryList = 0;
mbDataOn = false;
@@ -2559,11 +2559,17 @@ void ScHTMLTable::ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo&
void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW nSize )
{
- ScSizeVec& rSizes = maSizes[ eOrient ];
- if( static_cast< size_t >( nCellPos ) >= rSizes.size() )
- rSizes.resize( static_cast< size_t >( nCellPos + 1 ), 1 ); // expand with minimum height/width == 1
- if( rSizes[ nCellPos ] < nSize )
- rSizes[ nCellPos ] = 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
+ 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(
@@ -2582,31 +2588,35 @@ void ScHTMLTable::CalcNeededDocSize(
SetDocSize( eOrient, nCellPos, nRealDocSize );
}
-
// ----------------------------------------------------------------------------
void ScHTMLTable::FillEmptyCells()
{
- for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
aIter->FillEmptyCells();
+ for( const ScRange* pRange = maVMergedCells.First(); pRange; pRange = maVMergedCells.Next() )
+ maUsedCells.Join( *pRange );
+
for( ScAddress aAddr; aAddr.Row() < maSize.mnRows; aAddr.IncRow() )
{
for( aAddr.SetCol( 0 ); aAddr.Col() < maSize.mnCols; aAddr.IncCol() )
{
- if( !maLockList.Find( aAddr ) )
+ 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) && !maLockList.Find( aRange.aEnd ) );
+ }
+ while( (aRange.aEnd.Col() < maSize.mnCols) && !maUsedCells.Find( aRange.aEnd ) );
aRange.aEnd.IncCol( -1 );
- maLockList.Append( aRange );
+ maUsedCells.Join( aRange );
// insert a dummy entry
- ScHTMLEntryPtr pEntry = CreateEntry();
- ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], pEntry );
+ ScHTMLEntryPtr xEntry = CreateEntry();
+ ImplPushEntryToList( maEntryMap[ ScHTMLPos( aAddr ) ], xEntry );
}
}
}
@@ -2615,7 +2625,7 @@ void ScHTMLTable::FillEmptyCells()
void ScHTMLTable::RecalcDocSize()
{
// recalc table sizes recursively from inner to outer
- for( ScHTMLTableIterator aIter( mpNestedTables.get() ); aIter.is(); ++aIter )
+ for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter )
aIter->RecalcDocSize();
/* Two passes: first calculates the sizes of single columns/rows, then
@@ -2630,7 +2640,7 @@ void ScHTMLTable::RecalcDocSize()
for( ScHTMLEntryMap::const_iterator aMapIter = maEntryMap.begin(); aMapIter != aMapIterEnd; ++aMapIter )
{
const ScHTMLPos& rCellPos = aMapIter->first;
- ScHTMLSize aCellSpan( GetSpan( rCellPos ) );
+ ScHTMLSize aCellSpan = GetSpan( rCellPos );
const ScHTMLEntryList& rEntryList = aMapIter->second;
ScHTMLEntryList::const_iterator aListIter;
@@ -2650,7 +2660,7 @@ void ScHTMLTable::RecalcDocSize()
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 )) );
+ 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;
@@ -2659,9 +2669,9 @@ void ScHTMLTable::RecalcDocSize()
aDocSize.mnRows = 1;
if( bProcessColWidth )
- CalcNeededDocSize( tdCol, static_cast<SCCOLROW>(rCellPos.mnCol), static_cast<SCCOLROW>(aCellSpan.mnCols), static_cast<SCCOLROW>(aDocSize.mnCols) );
+ CalcNeededDocSize( tdCol, rCellPos.mnCol, aCellSpan.mnCols, aDocSize.mnCols );
if( bProcessRowHeight )
- CalcNeededDocSize( tdRow, static_cast<SCCOLROW>(rCellPos.mnRow), static_cast<SCCOLROW>(aCellSpan.mnRows), static_cast<SCCOLROW>(aDocSize.mnRows) );
+ CalcNeededDocSize( tdRow, rCellPos.mnRow, aCellSpan.mnRows, aDocSize.mnRows );
}
}
}
@@ -2695,12 +2705,12 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
pTable->RecalcDocPos( aEntryDocPos ); // recalc nested table
pEntry->nCol = SCCOL_MAX;
pEntry->nRow = SCROW_MAX;
- SCROW nTableRows = static_cast<SCROW>(pTable->GetDocSize( tdRow ));
+ 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 nStartCol = aEntryDocPos.mnCol + static_cast< SCCOL >( pTable->GetDocSize( tdCol ) );
SCCOL nNextCol = aEntryDocPos.mnCol + aCellDocSize.mnCols;
if( nStartCol < nNextCol )
{
@@ -2736,11 +2746,11 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
SCROW nFirstUnusedRow = aCellDocPos.mnRow + aCellDocSize.mnRows;
while( aEntryDocPos.mnRow < nFirstUnusedRow )
{
- ScHTMLEntryPtr pDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
- pDummyEntry->nCol = aEntryDocPos.mnCol;
- pDummyEntry->nRow = aEntryDocPos.mnRow;
- pDummyEntry->nColOverlap = aCellDocSize.mnCols;
- ImplPushEntryToList( rEntryList, pDummyEntry );
+ ScHTMLEntryPtr xDummyEntry( new ScHTMLEntry( pEntry->GetItemSet() ) );
+ xDummyEntry->nCol = aEntryDocPos.mnCol;
+ xDummyEntry->nRow = aEntryDocPos.mnRow;
+ xDummyEntry->nColOverlap = aCellDocSize.mnCols;
+ ImplPushEntryToList( rEntryList, xDummyEntry );
++aEntryDocPos.mnRow;
}
}
@@ -2748,7 +2758,6 @@ void ScHTMLTable::RecalcDocPos( const ScHTMLPos& rBasePos )
}
}
-
// ============================================================================
ScHTMLGlobalTable::ScHTMLGlobalTable( SfxItemPool& rPool, EditEngine& rEditEngine, ScEEParseList& rEEParseList, ScHTMLTableId& rnUnusedId ) :
@@ -2770,7 +2779,6 @@ void ScHTMLGlobalTable::Recalc()
RecalcDocPos( GetDocPos() );
}
-
// ============================================================================
ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc ) :
@@ -2778,8 +2786,8 @@ ScHTMLQueryParser::ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc
mnUnusedId( SC_HTML_GLOBAL_TABLE ),
mbTitleOn( false )
{
- mpGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, *pList, mnUnusedId ) );
- mpCurrTable = mpGlobTable.get();
+ mxGlobTable.reset( new ScHTMLGlobalTable( *pPool, *pEdit, *pList, mnUnusedId ) );
+ mpCurrTable = mxGlobTable.get();
}
ScHTMLQueryParser::~ScHTMLQueryParser()
@@ -2817,16 +2825,16 @@ ULONG ScHTMLQueryParser::Read( SvStream& rStrm, const String& rBaseURL )
ULONG nErr = pEdit->Read( rStrm, rBaseURL, EE_FORMAT_HTML, pAttributes );
pEdit->SetImportHdl( aOldLink );
- mpGlobTable->Recalc();
- nColMax = static_cast<SCCOL>(mpGlobTable->GetDocSize( tdCol ) - 1);
- nRowMax = static_cast<SCROW>(mpGlobTable->GetDocSize( tdRow ) - 1);
+ 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 mpGlobTable.get();
+ return mxGlobTable.get();
}
void ScHTMLQueryParser::ProcessToken( const ImportInfo& rInfo )
@@ -2941,7 +2949,7 @@ void ScHTMLQueryParser::FontOn( const ImportInfo& rInfo )
break;
case HTML_O_SIZE :
{
- sal_uInt32 nSize = bound( aIter->GetNumber(), static_cast<sal_uInt32>(1UL), SC_HTML_FONTSIZES );
+ sal_uInt32 nSize = getLimitedValue< sal_uInt32 >( aIter->GetNumber(), 1, SC_HTML_FONTSIZES );
mpCurrTable->PutItem( SvxFontHeightItem( maFontHeights[ nSize - 1 ], 100, ATTR_FONT_HEIGHT ) );
}
break;
@@ -2960,26 +2968,13 @@ void ScHTMLQueryParser::MetaOn( const ImportInfo& rInfo )
{
if( mpDoc->GetDocumentShell() )
{
- sal_uInt16 nContentOpt = HTML_O_CONTENT;
- rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
HTMLParser* pParser = static_cast< HTMLParser* >( rInfo.pParser );
- const HTMLOptions* pOptions = pParser->GetOptions( &nContentOpt );
uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
mpDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
- SfxFrameHTMLParser::ParseMetaOptions(
+ pParser->ParseMetaOptions(
xDPS->getDocumentProperties(),
- mpDoc->GetDocumentShell()->GetHeaderAttributes(),
- pOptions, eEnc );
- // If the encoding is set by a META tag, it may only overwrite the
- // current encoding if both, the current and the new encoding, are 1-BYTE
- // encodings. Everything else cannot lead to reasonable results.
- if( rtl_isOctetTextEncoding( eEnc ) &&
- rtl_isOctetTextEncoding( pParser->GetSrcEncoding() ) )
- {
- eEnc = GetExtendedCompatibilityTextEncoding( eEnc );
- pParser->SetSrcEncoding( eEnc );
- }
+ mpDoc->GetDocumentShell()->GetHeaderAttributes() );
}
}
@@ -3030,7 +3025,6 @@ void ScHTMLQueryParser::CloseTable( const ImportInfo& rInfo )
mpCurrTable = mpCurrTable->CloseTable( rInfo );
}
-
// ----------------------------------------------------------------------------
IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
@@ -3065,6 +3059,5 @@ IMPL_LINK( ScHTMLQueryParser, HTMLImportHdl, const ImportInfo*, pInfo )
return 0;
}
-
// ============================================================================
diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx
index 2f3913f01c57..9bd633eae879 100644
--- a/sc/source/filter/inc/excimp8.hxx
+++ b/sc/source/filter/inc/excimp8.hxx
@@ -61,7 +61,6 @@ class ImportExcel8 : public ImportExcel
void Precision( void ); // 0x0E
void Delta( void ); // 0x10
void Iteration( void ); // 0x11
- void WinProtection( void ); // 0x19
void Boundsheet( void ); // 0x85
void FilterMode( void ); // 0x9B
void AutoFilterInfo( void ); // 0x9D
@@ -73,6 +72,7 @@ class ImportExcel8 : public ImportExcel
void Hlink( void ); // 0x01B8
void Codename( BOOL bWBGlobals ); // 0x01BA
+ void SheetProtection( void ); // 0x0867
virtual void EndSheet( void );
virtual void PostDocLoad( void );
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
index da4115fc8003..1f2eee05fd55 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -246,10 +246,23 @@ class XclExpWindowProtection : public XclExpBoolRecord
};
// EXC_ID_PROTECT Document Protection
-class XclExpDocProtection : public XclExpBoolRecord
+class XclExpProtection : public XclExpBoolRecord
{
public:
- XclExpDocProtection(bool bValue);
+ 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;
};
diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx
index b75a44c618db..e3f53a5ddc5b 100644
--- a/sc/source/filter/inc/htmlpars.hxx
+++ b/sc/source/filter/inc/htmlpars.hxx
@@ -218,30 +218,29 @@ 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) ? static_cast<SCCOLROW>(mnCol) : static_cast<SCCOLROW>(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 ); }
+ 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 )
@@ -254,25 +253,24 @@ 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) ? static_cast<SCCOLROW>(mnCols) : static_cast<SCCOLROW>(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; }
+ 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 )
@@ -280,183 +278,182 @@ 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 );
+ 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(); }
+ inline bool IsEmpty() const { return !aSel.HasRange(); }
/** Returns true, if the entry has any content to be imported. */
- bool HasContents() const;
+ bool HasContents() const;
/** Returns true, if the entry represents a table. */
- inline bool IsTable() const { return nTab != SC_HTML_NO_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; }
+ inline ScHTMLTableId GetTableId() const { return nTab; }
/** Sets or cleares the import always state. */
- inline void SetImportAlways( bool bSet = true ) { mbImportAlways = bSet; }
+ 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 );
+ 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 );
+ void AdjustEnd( const ImportInfo& rInfo );
/** Deletes leading and trailing empty paragraphs from the entry. */
- void Strip( const EditEngine& rEditEngine );
+ void Strip( const EditEngine& rEditEngine );
/** Returns read/write access to the item set of this entry. */
- inline SfxItemSet& GetItemSet() { return aItemSet; }
+ inline SfxItemSet& GetItemSet() { return aItemSet; }
/** Returns read-only access to the item set of this entry. */
- inline const SfxItemSet& GetItemSet() const { return aItemSet; }
+ inline const SfxItemSet& GetItemSet() const { return aItemSet; }
private:
- bool mbImportAlways; /// true = Always import this entry.
+ 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.
+ 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 );
+ explicit ScHTMLTableAutoId( ScHTMLTableId& rnUnusedId );
};
-
// ----------------------------------------------------------------------------
class ScHTMLTableMap;
/** Stores data for one table in an HTML document.
- @descr 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. */
+
+ 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().
+ @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 );
+ explicit ScHTMLTable(
+ ScHTMLTable& rParentTable,
+ const ImportInfo& rInfo,
+ bool bPreFormText );
- virtual ~ScHTMLTable();
+ virtual ~ScHTMLTable();
/** Returns the name of the table, specified in the TABLE tag. */
- inline const String& GetTableName() const { return maTableName; }
+ inline const String& GetTableName() const { return maTableName; }
/** Returns the unique identifier of the table. */
- inline ScHTMLTableId GetTableId() const { return maTableId.mnTableId; }
+ inline ScHTMLTableId GetTableId() const { return maTableId.mnTableId; }
/** Returns the table size. */
- inline const ScHTMLSize& GetSize() const { return maSize; }
+ inline const ScHTMLSize& GetSize() const { return maSize; }
/** Returns the cell spanning of the specified cell. */
- ScHTMLSize GetSpan( const ScHTMLPos& rCellPos ) const;
+ 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;
+ ScHTMLTable* FindNestedTable( ScHTMLTableId nTableId ) const;
/** Puts the item into the item set of the current entry. */
- void PutItem( const SfxPoolItem& rItem );
+ void PutItem( const SfxPoolItem& rItem );
/** Inserts a text portion into current entry. */
- void PutText( const ImportInfo& rInfo );
+ void PutText( const ImportInfo& rInfo );
/** Inserts a new line, if in preformatted text, else does nothing. */
- void InsertPara( const ImportInfo& rInfo );
+ void InsertPara( const ImportInfo& rInfo );
/** Inserts a line break (<br> tag).
@descr Inserts the current entry regardless if it is empty. */
- void BreakOn();
+ void BreakOn();
/** Inserts a heading line (<p> and <h*> tags). */
- void HeadingOn();
+ void HeadingOn();
/** Processes a hyperlink (<a> tag). */
- void AnchorOn();
+ void AnchorOn();
/** Starts a *new* table nested in this table (<table> tag).
@return Pointer to the new table. */
- ScHTMLTable* TableOn( const ImportInfo& rInfo );
+ ScHTMLTable* TableOn( const ImportInfo& rInfo );
/** Closes *this* table (</table> tag).
@return Pointer to the parent table. */
- ScHTMLTable* TableOff( const ImportInfo& rInfo );
+ 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 );
+ 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 );
+ 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 );
+ 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 );
+ void RowOff( const ImportInfo& rInfo );
/** Starts the next cell (<td> or <th> tag). */
- void DataOn( const ImportInfo& rInfo );
+ 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 );
+ void DataOff( const ImportInfo& rInfo );
/** Starts the body of the HTML document (<body> tag). */
- void BodyOn( const ImportInfo& rInfo );
+ void BodyOn( const ImportInfo& rInfo );
/** Closes the body of the HTML document (</body> tag). */
- void BodyOff( const ImportInfo& rInfo );
+ 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 );
+ 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 range [nCellBegin, nCellEnd). */
- SCCOLROW GetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellBegin, SCCOLROW nCellEnd ) const;
+ 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;
+ SCCOLROW GetDocSize( ScHTMLOrient eOrient ) const;
/** Returns the total document row/column count of the specified HTML cell. */
- ScHTMLSize GetDocSize( const ScHTMLPos& rCellPos ) const;
+ 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; }
+ 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;
+ SCCOLROW GetDocPos( ScHTMLOrient eOrient, SCCOLROW nCellPos = 0 ) const;
/** Calculates the resulting Calc position of the specified HTML cell. */
- ScHTMLPos GetDocPos( const ScHTMLPos& rCellPos ) const;
+ ScHTMLPos GetDocPos( const ScHTMLPos& rCellPos ) const;
/** Calculates the current Calc document area of this table. */
- void GetDocRange( ScRange& rRange ) const;
+ void GetDocRange( ScRange& rRange ) const;
/** Applies border formatting to the passed document. */
- void ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const;
+ 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,
- ScEEParseList& rEEParseList,
- ScHTMLTableId& rnUnusedId );
+ explicit ScHTMLTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ScEEParseList& rEEParseList,
+ ScHTMLTableId& rnUnusedId );
/** Fills all empty cells in this and nested tables with dummy parse entries. */
- void FillEmptyCells();
+ void FillEmptyCells();
/** Recalculates the size of all columns/rows in the table, regarding nested tables. */
- void RecalcDocSize();
+ 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 );
+ void RecalcDocPos( const ScHTMLPos& rBasePos );
private:
typedef ::std::auto_ptr< ScHTMLTableMap > ScHTMLTableMapPtr;
@@ -467,172 +464,174 @@ private:
typedef ::std::auto_ptr< ScHTMLEntry > ScHTMLEntryPtr;
/** Returns true, if the current cell does not contain an entry yet. */
- bool IsEmptyCell() const;
+ bool IsEmptyCell() const;
/** Returns the item set from cell, row, or table, depending on current state. */
- const SfxItemSet& GetCurrItemSet() const;
+ const SfxItemSet& GetCurrItemSet() const;
/** Returns true, if import info represents a space character. */
- static bool IsSpaceCharInfo( const ImportInfo& rInfo );
+ static bool IsSpaceCharInfo( const ImportInfo& rInfo );
/** Creates and returns a new empty flying entry at position (0,0). */
- ScHTMLEntryPtr CreateEntry() const;
+ ScHTMLEntryPtr CreateEntry() const;
/** Creates a new flying entry.
@param rInfo Contains the initial edit engine selection for the entry. */
- void CreateNewEntry( const ImportInfo& rInfo );
+ void CreateNewEntry( const ImportInfo& rInfo );
/** Inserts an empty line in front of the next entry. */
- void InsertLeadingEmptyLine();
+ void InsertLeadingEmptyLine();
/** Pushes the passed entry into the list of the current cell. */
- void ImplPushEntryToList( ScHTMLEntryList& rEntryList, ScHTMLEntryPtr& rpEntry );
+ 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& rpEntry );
+ 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 );
+ 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 );
+ 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;
+ 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 );
+ 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 );
+ void InsertNewCell( const ScHTMLSize& rSpanSize );
/** Set internal states for a new table row. */
- void ImplRowOn();
+ void ImplRowOn();
/** Set internal states for leaving a table row. */
- void ImplRowOff();
+ void ImplRowOff();
/** Set internal states for entering a new table cell. */
- void ImplDataOn( const ScHTMLSize& rSpanSize );
+ void ImplDataOn( const ScHTMLSize& rSpanSize );
/** Set internal states for leaving a table cell. */
- void ImplDataOff();
+ void ImplDataOff();
/** Inserts additional formatting options from import info into the item set. */
- void ProcessFormatOptions( SfxItemSet& rItemSet, const ImportInfo& rInfo );
+ 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 );
+ 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 );
+ void CalcNeededDocSize(
+ ScHTMLOrient eOrient, SCCOLROW nCellPos,
+ SCCOLROW nCellSpan, SCCOLROW nRealDocSize );
private:
- ScHTMLTable* mpParentTable; /// Pointer to parent table.
- ScHTMLTableMapPtr mpNestedTables; /// 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 mpRowItemSet; /// Items for the current table row.
- SfxItemSetPtr mpDataItemSet; /// Items for the current cell.
- ScRangeList maLockList; /// Locked cells (needed for merged cells).
- EditEngine& mrEditEngine; /// Edit engine (from ScEEParser).
- ScEEParseList& 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 mpCurrEntry; /// Working entry, not yet inserted in a list.
- ScSizeVec maSizes[ 2 ]; /// Calc cell count of 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.
+ 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).
+ ScEEParseList& 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,
- ScEEParseList& rEEParseList,
- ScHTMLTableId& rnUnusedId );
+ explicit ScHTMLGlobalTable(
+ SfxItemPool& rPool,
+ EditEngine& rEditEngine,
+ ScEEParseList& rEEParseList,
+ ScHTMLTableId& rnUnusedId );
- virtual ~ScHTMLGlobalTable();
+ virtual ~ScHTMLGlobalTable();
/** Recalculates sizes and resulting positions of all document entries. */
- void Recalc();
+ void Recalc();
};
-
// ============================================================================
/** The HTML parser for data queries. Focuses on data import, not on layout.
- @descr Builds the table structure correctly, ignores extended formatting
- like pictures or column widths. */
+
+ 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();
+ explicit ScHTMLQueryParser( EditEngine* pEditEngine, ScDocument* pDoc );
+ virtual ~ScHTMLQueryParser();
- virtual ULONG Read( SvStream& rStrm, const String& rBaseURL );
+ virtual ULONG Read( SvStream& rStrm, const String& rBaseURL );
/** Returns the "global table" which contains the entire HTML document. */
- virtual const ScHTMLTable* GetGlobalTable() const;
+ virtual const ScHTMLTable* GetGlobalTable() const;
private:
/** Handles all possible tags in the HTML document. */
- void ProcessToken( const ImportInfo& rInfo );
+ void ProcessToken( const ImportInfo& rInfo );
/** Inserts a text portion into current entry. */
- void InsertText( const ImportInfo& rInfo );
+ void InsertText( const ImportInfo& rInfo );
/** Processes the <font> tag. */
- void FontOn( const ImportInfo& rInfo );
+ void FontOn( const ImportInfo& rInfo );
/** Processes the <meta> tag. */
- void MetaOn( const ImportInfo& rInfo );
+ void MetaOn( const ImportInfo& rInfo );
/** Opens the title of the HTML document (<title> tag). */
- void TitleOn( const ImportInfo& rInfo );
+ void TitleOn( const ImportInfo& rInfo );
/** Closes the title of the HTML document (</title> tag). */
- void TitleOff( const ImportInfo& rInfo );
+ void TitleOff( const ImportInfo& rInfo );
/** Opens a new table at the current position. */
- void TableOn( const ImportInfo& rInfo );
+ void TableOn( const ImportInfo& rInfo );
/** Closes the current table. */
- void TableOff( const ImportInfo& rInfo );
+ void TableOff( const ImportInfo& rInfo );
/** Opens a new table based on preformatted text. */
- void PreOn( const ImportInfo& rInfo );
+ void PreOn( const ImportInfo& rInfo );
/** Closes the current preformatted text table. */
- void PreOff( const ImportInfo& rInfo );
+ void PreOff( const ImportInfo& rInfo );
/** Closes the current table, regardless on opening tag. */
- void CloseTable( const ImportInfo& rInfo );
+ 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 mpGlobTable; /// 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>.
+ 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>.
};
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
index 66a58ffb67a4..f8dad9a45c48 100644
--- a/sc/source/filter/inc/imp_op.hxx
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -135,9 +135,11 @@ protected:
void Bof2( void ); // 0x09
void Eof( void ); // 0x0A
void DocProtect( void ); // 0x12
- void Protect( void ); // 0x12 Sheet Protection
- BOOL Password( void ); // 0x13
+ 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
diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx
index 8d48e7119629..7729e0ab11cc 100644
--- a/sc/source/filter/inc/xcl97rec.hxx
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -398,23 +398,24 @@ public:
virtual sal_Size GetLen() const;
};
+// ============================================================================
-// ---- class XclProtection ------------------------------------------
-
-class XclProtection : public ExcDummyRec
+/** 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
{
- // replacement for records PROTECT, SCENPROTECT, OBJPROTECT...
-private:
- static const BYTE pMyData[];
- static const sal_Size nMyLen;
public:
- virtual sal_Size GetLen( void ) const;
- virtual const BYTE* GetData( void ) const;
-};
+ 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
{
@@ -478,5 +479,162 @@ public:
virtual void SaveXml( XclExpXmlStream& rStrm );
};
+// ============================================================================
+
+class XclExpFilePass : public XclExpRecord
+{
+public:
+ explicit XclExpFilePass( const XclExpRoot& rRoot );
+ virtual ~XclExpFilePass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpRoot& mrRoot;
+};
+
+// ============================================================================
+
+class XclExpFnGroupCount : public XclExpRecord
+{
+public:
+ explicit XclExpFnGroupCount();
+ virtual ~XclExpFnGroupCount();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceHdr : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceHdr();
+ virtual ~XclExpInterfaceHdr();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceEnd : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceEnd();
+ virtual ~XclExpInterfaceEnd();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** ADDMENU/DELMENU Record Group Count */
+class XclExpMMS : public XclExpRecord
+{
+public:
+ explicit XclExpMMS();
+ virtual ~XclExpMMS();
+
+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 XclExpCodePage : public XclExpRecord
+{
+public:
+ explicit XclExpCodePage();
+ virtual ~XclExpCodePage();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpDSF : public XclExpRecord
+{
+public:
+ explicit XclExpDSF();
+ virtual ~XclExpDSF();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+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 );
+};
+
+// ============================================================================
+
+/** What's this record for? It is a zero-byte record. */
+class XclExpExcel9File : public XclExpRecord
+{
+public:
+ explicit XclExpExcel9File();
+ virtual ~XclExpExcel9File();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpRecalcId : public XclExpDummyRecord
+{
+public:
+ explicit XclExpRecalcId();
+};
+
+// ============================================================================
+
+class XclExpBookExt : public XclExpDummyRecord
+{
+public:
+ explicit XclExpBookExt();
+};
+
#endif // _XCL97REC_HXX
diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx
index 6ca53ed8655f..27975a723792 100644
--- a/sc/source/filter/inc/xeroot.hxx
+++ b/sc/source/filter/inc/xeroot.hxx
@@ -159,7 +159,12 @@ public:
@param nRecId Identifier that specifies which record is returned. */
XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+ bool IsDocumentEncrypted() const;
+
+ const String GetPassword() const;
+
private:
+
/** Returns the local or global link manager, depending on current context. */
XclExpRootData::XclExpLinkMgrRef GetLocalLinkMgrRef() const;
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 8792f26c6582..676b0d550875 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -43,6 +43,9 @@
#include "xlstream.hxx"
#include "xestring.hxx"
+#include <svx/mscodec.hxx>
+#include <vector>
+
/* ============================================================================
Output stream class for Excel export
- CONTINUE record handling
@@ -50,6 +53,8 @@ Output stream class for Excel export
============================================================================ */
class XclExpRoot;
+class XclExpBiff8Encrypter;
+typedef ScfRef< 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
@@ -108,14 +113,14 @@ public:
/** Sets data slice length. 0 = no slices. */
void SetSliceSize( sal_uInt16 nSize );
- inline XclExpStream& operator<<( sal_Int8 nValue );
- inline XclExpStream& operator<<( sal_uInt8 nValue );
- inline XclExpStream& operator<<( sal_Int16 nValue );
- inline XclExpStream& operator<<( sal_uInt16 nValue );
- inline XclExpStream& operator<<( sal_Int32 nValue );
- inline XclExpStream& operator<<( sal_uInt32 nValue );
- inline XclExpStream& operator<<( float fValue );
- inline XclExpStream& operator<<( double fValue );
+ 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 );
@@ -158,6 +163,14 @@ public:
/** 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 );
@@ -180,6 +193,9 @@ 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.
@@ -197,64 +213,50 @@ private:
// ----------------------------------------------------------------------------
-inline XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
-{
- PrepareWrite( 1 );
- mrStrm << nValue;
- return *this;
-}
-inline XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
-{
- PrepareWrite( 1 );
- mrStrm << nValue;
- return *this;
-}
+// ============================================================================
-inline XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
+class XclExpBiff8Encrypter
{
- PrepareWrite( 2 );
- mrStrm << nValue;
- return *this;
-}
+public:
+ explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] );
+ ~XclExpBiff8Encrypter();
-inline XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
-{
- PrepareWrite( 2 );
- mrStrm << nValue;
- return *this;
-}
+ bool IsValid() const;
-inline XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
-{
- PrepareWrite( 4 );
- mrStrm << nValue;
- return *this;
-}
+ void GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const;
-inline XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
-{
- PrepareWrite( 4 );
- mrStrm << nValue;
- return *this;
-}
+ void Encrypt( SvStream& rStrm, sal_uInt8 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt16 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt32 nData );
-inline XclExpStream& XclExpStream::operator<<( float fValue )
-{
- PrepareWrite( 4 );
- mrStrm << fValue;
- return *this;
-}
+ void Encrypt( SvStream& rStrm, sal_Int8 nData );
+ void Encrypt( SvStream& rStrm, sal_Int16 nData );
+ void Encrypt( SvStream& rStrm, sal_Int32 nData );
-inline XclExpStream& XclExpStream::operator<<( double fValue )
-{
- PrepareWrite( 8 );
- mrStrm << fValue;
- return *this;
-}
+ 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 String& aPass, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] );
+
+ sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const;
+ sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const;
+
+private:
+ ::svx::MSCodec_Std97 maCodec; /// Crypto algorithm implementation.
+ sal_uInt16 mnPassw[16]; /// Cached password data for copy construction.
+ sal_uInt8 mnDocId[16]; /// Cached document ID for copy construction.
+ sal_uInt8 mnSaltDigest[16];
+
+ const XclExpRoot& mrRoot;
+ sal_Size mnOldPos; /// Last known stream position
+ bool mbValid;
+};
// ----------------------------------------------------------------------------
@@ -335,7 +337,7 @@ public:
// only needed for import; ignore
virtual bool importDocument() throw();
virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const;
- virtual const oox::vml::DrawingPtr getDrawings();
+ 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();
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 7be4f406ee23..5322b0c47f01 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -1088,7 +1088,5 @@ private:
XclExpDvalRef mxDval; /// Data validation with DVAL and DV records.
};
-// ============================================================================
-
#endif
diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx
index 36ddc773dd5f..dc650b3f0373 100644
--- a/sc/source/filter/inc/xichart.hxx
+++ b/sc/source/filter/inc/xichart.hxx
@@ -44,8 +44,6 @@
#include "xiescher.hxx"
#include "xistring.hxx"
-#include <boost/shared_ptr.hpp>
-
namespace com { namespace sun { namespace star {
namespace frame
{
@@ -375,6 +373,7 @@ public:
public:
explicit XclImpChSourceLink( const XclImpChRoot& rRoot );
+ virtual ~XclImpChSourceLink();
/** Reads the CHSOURCELINK record (link to source data). */
void ReadChSourceLink( XclImpStream& rStrm );
@@ -407,10 +406,7 @@ public:
private:
XclChSourceLink maData; /// Contents of the CHSOURCELINK record.
XclImpStringRef mxString; /// Text data (CHSTRING record).
-
- // Tokens representing data ranges. This must be ref-counted to allow the
- // parent class to be stored in a STL container.
- ::boost::shared_ptr<ScTokenArray> mpTokenArray;
+ ScfRef< ScTokenArray> mxTokenArray; /// Token array representing the data ranges.
};
typedef ScfRef< XclImpChSourceLink > XclImpChSourceLinkRef;
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
index 2b777e57600c..53ed10583249 100644
--- a/sc/source/filter/inc/xicontent.hxx
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -37,6 +37,8 @@
#include "xistring.hxx"
#include "xiroot.hxx"
+#include <map>
+
/* ============================================================================
Classes to import the big Excel document contents (related to several cells or
globals for the document).
@@ -249,5 +251,64 @@ public:
// ============================================================================
+// 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
diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx
index ea3edb342907..ac0be294f8e8 100644
--- a/sc/source/filter/inc/xiroot.hxx
+++ b/sc/source/filter/inc/xiroot.hxx
@@ -62,6 +62,8 @@ class XclImpPivotTableManager;
class XclImpPageSettings;
class XclImpDocViewSettings;
class XclImpTabViewSettings;
+class XclImpSheetProtectBuffer;
+class XclImpDocProtectBuffer;
class _ScRangeListTabs;
class ExcelToSc;
@@ -88,6 +90,8 @@ struct XclImpRootData : public XclRootData
typedef ScfRef< XclImpPageSettings > XclImpPageSettRef;
typedef ScfRef< XclImpDocViewSettings > XclImpDocViewSettRef;
typedef ScfRef< XclImpTabViewSettings > XclImpTabViewSettRef;
+ typedef ScfRef< XclImpSheetProtectBuffer > XclImpTabProtectRef;
+ typedef ScfRef< XclImpDocProtectBuffer > XclImpDocProtectRef;
XclImpAddrConvRef mxAddrConv; /// The address converter.
XclImpFmlaCompRef mxFmlaComp; /// The formula compiler.
@@ -111,6 +115,11 @@ struct XclImpRootData : public XclRootData
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.
+
+ String maPassw; /// Entered password for stream decryption.
+ bool mbPassQueried; /// true = Password already querried.
bool mbHasCodePage; /// true = CODEPAGE record exists.
@@ -184,6 +193,10 @@ public:
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;
@@ -195,6 +208,9 @@ public:
/** Returns the Calc add-in function name for an Excel function name. */
String GetScAddInName( const String& rXclName ) const;
+ /** Queries a password from the user and returns it (empty string -> input cancelled). */
+ const String& QueryPassword() const;
+
private:
mutable XclImpRootData& mrImpData; /// Reference to the global import data struct.
};
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
index aa1cae84d8f6..ccaaccdc0357 100644
--- a/sc/source/filter/inc/xistream.hxx
+++ b/sc/source/filter/inc/xistream.hxx
@@ -73,6 +73,8 @@ public:
@return Count of bytes really read. */
sal_uInt16 Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes );
+ const String GetPassword() const;
+
protected:
/** Protected copy c'tor for OnClone(). */
explicit XclImpDecrypter( const XclImpDecrypter& rSrc );
@@ -80,6 +82,8 @@ protected:
/** Sets the decrypter to a state showing whether the password was correct. */
void SetHasValidPassword( bool bValid );
+ void SetPassword( const String& rPass );
+
private:
/** Implementation of cloning this object. */
virtual XclImpDecrypter* OnClone() const = 0;
@@ -89,6 +93,7 @@ private:
virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ) = 0;
private:
+ String maPass; /// Stored password (needed for export)
ErrCode mnError; /// Decrypter error code.
sal_Size mnOldPos; /// Last known stream position.
sal_uInt16 mnRecSize; /// Current record size.
diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx
index 92a3b60ce970..1666ecc49ba1 100644
--- a/sc/source/filter/inc/xlchart.hxx
+++ b/sc/source/filter/inc/xlchart.hxx
@@ -157,6 +157,7 @@ namespace com { namespace sun { namespace star {
#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 =================================================
diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx
index 12ab2808a1ab..36056ead2fe2 100644
--- a/sc/source/filter/inc/xlroot.hxx
+++ b/sc/source/filter/inc/xlroot.hxx
@@ -92,7 +92,6 @@ struct XclRootData
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 maPassw; /// Entered password for stream encryption/decryption.
rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings.
LanguageType meSysLang; /// System language.
LanguageType meDocLang; /// Document language (import: from file, export: from system).
@@ -116,7 +115,6 @@ struct XclRootData
long mnCharWidth; /// Width of '0' in default font (twips).
SCTAB mnScTab; /// Current Calc sheet index.
const bool mbExport; /// false = Import, true = Export.
- bool mbHasPassw; /// true = Password already querried.
explicit XclRootData( XclBiff eBiff, SfxMedium& rMedium,
SotStorageRef xRootStrg, ScDocument& rDoc,
@@ -184,8 +182,6 @@ public:
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; }
- /** Queries a password from the user and returns it (empty string -> input cancelled). */
- const String& QueryPassword() 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. */
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
index dab66815947e..92cb49e786eb 100644
--- a/sc/source/filter/lotus/op.cxx
+++ b/sc/source/filter/lotus/op.cxx
@@ -466,7 +466,7 @@ void OP_Note123( SvStream& r, UINT16 n)
delete [] pText;
ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) );
- ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
}
void OP_HorAlign123( BYTE nAlignPattern, SfxItemSet& rPatternItemSet )
diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx
index 511c706abdfb..e2a7d9e4d538 100644
--- a/sc/source/filter/starcalc/scflt.cxx
+++ b/sc/source/filter/starcalc/scflt.cxx
@@ -81,6 +81,7 @@
#include "postit.hxx"
#include "globstr.hrc"
#include "ftools.hxx"
+#include "tabprotection.hxx"
#include "fprogressbar.hxx"
@@ -1087,9 +1088,11 @@ void Sc10Import::LoadProtect()
//rStream.Read(&SheetProtect, sizeof(SheetProtect));
lcl_ReadSheetProtect(rStream, SheetProtect);
nError = rStream.GetError();
- uno::Sequence<sal_Int8> aPass;
- SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( SheetProtect.PassWord ));
- pDoc->SetDocProtection( SheetProtect.Protect, aPass);
+
+ ScDocProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(SheetProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(SheetProtect.PassWord));
+ pDoc->SetDocProtection(&aProtection);
}
@@ -1441,10 +1444,11 @@ void Sc10Import::LoadTables()
//rStream.Read(&TabProtect, sizeof(TabProtect));
lcl_ReadTabProtect(rStream, TabProtect);
- uno::Sequence<sal_Int8> aPass;
- SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( TabProtect.PassWord ));
- pDoc->SetTabProtection( static_cast<SCTAB>(Tab), TabProtect.Protect, aPass);
+ ScTableProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(TabProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(TabProtect.PassWord));
+ pDoc->SetTabProtection(static_cast<SCTAB>(Tab), &aProtection);
rStream >> TabNo;
@@ -1710,7 +1714,7 @@ void Sc10Import::LoadCol(SCCOL Col, SCTAB Tab)
String aNoteText( SC10TOSTRING(pNote));
delete [] pNote;
ScAddress aPos( Col, static_cast<SCROW>(Row), Tab );
- ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false );
+ ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
}
}
pPrgrsBar->Progress();
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
index 760599ff594b..a38b023d4f55 100644
--- a/sc/source/filter/xcl97/XclExpChangeTrack.cxx
+++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
@@ -491,6 +491,7 @@ void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
{
+ rStrm.EnableEncryption();
if( pBuffer )
for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
rStrm << *pElem;
diff --git a/sc/source/filter/xcl97/makefile.mk b/sc/source/filter/xcl97/makefile.mk
index c40209d40819..58e2b8cb3074 100644
--- a/sc/source/filter/xcl97/makefile.mk
+++ b/sc/source/filter/xcl97/makefile.mk
@@ -51,7 +51,6 @@ VISIBILITY_HIDDEN=TRUE
# --- Files --------------------------------------------------------
SLOFILES = \
- $(SLO)$/xcl97dum.obj \
$(SLO)$/xcl97esc.obj \
$(SLO)$/xcl97rec.obj \
$(SLO)$/XclImpChangeTrack.obj \
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index 3d878243b2c2..bd40e98a02f4 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -79,6 +79,7 @@
#include "scextopt.hxx"
#include "docoptio.hxx"
#include "patattr.hxx"
+#include "tabprotection.hxx"
#include <oox/core/tokens.hxx>
@@ -716,6 +717,7 @@ ExcBof8_Base::ExcBof8_Base()
void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
{
+ rStrm.DisableEncryption();
rStrm << nVers << nDocType << nRupBuild << nRupYear
<< nFileHistory << nLowestBiffVer;
}
@@ -775,7 +777,10 @@ void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
{
nOwnPos = rStrm.GetSvStreamPos();
// write dummy position, real position comes later
- rStrm << sal_uInt32( 0 ) << nGrbit << GetName();
+ rStrm.DisableEncryption();
+ rStrm << sal_uInt32(0);
+ rStrm.EnableEncryption();
+ rStrm << nGrbit << GetName();
}
@@ -1083,33 +1088,73 @@ sal_Size ExcEScenarioManager::GetLen() const
return 8;
}
+// ============================================================================
-
-// ---- class XclProtection ------------------------------------------
-
-const BYTE XclProtection::pMyData[] =
+struct XclExpTabProtectOption
{
- 0x12, 0x00, 0x02, 0x00, 0x01, 0x00, // PROTECT
- 0xDD, 0x00, 0x02, 0x00, 0x01, 0x00, // SCENPROTECT
- 0x63, 0x00, 0x02, 0x00, 0x01, 0x00 // OBJPROTECT
+ ScTableProtection::Option eOption;
+ sal_uInt16 nMask;
};
-const sal_Size XclProtection::nMyLen = sizeof( XclProtection::pMyData );
-sal_Size XclProtection::GetLen( void ) const
+XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRecord( 0x0867, 23 )
{
- return nMyLen;
-}
-
+ 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;
-const BYTE* XclProtection::GetData( void ) const
-{
- return pMyData;
+ 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;
+}
+// ============================================================================
@@ -1214,8 +1259,253 @@ void XclDelta::SaveXml( XclExpXmlStream& rStrm )
FSEND );
}
+// ============================================================================
+
+XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) :
+ XclExpRecord(0x002F, 54),
+ mrRoot(rRoot)
+{
+}
+
+XclExpFilePass::~XclExpFilePass()
+{
+}
+
+void XclExpFilePass::WriteBody( XclExpStream& rStrm )
+{
+ static const sal_uInt8 nDocId[] = {
+ 0x17, 0xf7, 0x01, 0x08, 0xea, 0xad, 0x30, 0x5c,
+ 0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d };
+
+
+ static const sal_uInt8 nSalt[] = {
+ 0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5,
+ 0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 };
+
+ // 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 nSaltHash[16];
+ XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot, nDocId, nSalt) );
+ xEnc->GetSaltDigest(nSaltHash);
+
+ rStrm.Write(nDocId, 16);
+ rStrm.Write(nSalt, 16);
+ rStrm.Write(nSaltHash, 16);
+
+ rStrm.SetEncrypter(xEnc);
+}
+
+// ============================================================================
+
+XclExpFnGroupCount::XclExpFnGroupCount() :
+ XclExpRecord(0x009C, 2)
+{
+}
+
+XclExpFnGroupCount::~XclExpFnGroupCount()
+{
+}
+
+void XclExpFnGroupCount::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(14);
+}
+
+// ============================================================================
+
+XclExpInterfaceHdr::XclExpInterfaceHdr() :
+ XclExpRecord(0x00E1, 2)
+{
+}
+
+XclExpInterfaceHdr::~XclExpInterfaceHdr()
+{
+}
+void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
+{
+ // The value must be the same value as the CODEPAGE record.
+ rStrm.DisableEncryption();
+ rStrm << static_cast<sal_uInt16>(0x04B0);
+}
+
+// ============================================================================
+
+XclExpInterfaceEnd::XclExpInterfaceEnd() :
+ XclExpRecord(0x00E2, 0)
+{
+}
+
+XclExpInterfaceEnd::~XclExpInterfaceEnd()
+{
+}
+
+void XclExpInterfaceEnd::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ============================================================================
+
+XclExpMMS::XclExpMMS() :
+ XclExpRecord(0x00C1, 2)
+{
+}
+
+XclExpMMS::~XclExpMMS()
+{
+}
+
+void XclExpMMS::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+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];
+}
+
+// ============================================================================
+
+XclExpCodePage::XclExpCodePage() :
+ XclExpRecord(0x0042, 2)
+{
+}
+
+XclExpCodePage::~XclExpCodePage()
+{
+}
+
+void XclExpCodePage::WriteBody( XclExpStream& rStrm )
+{
+ // 0x04B0 : UTF-16 (BIFF8)
+ rStrm << static_cast<sal_uInt16>(0x04B0);
+}
+
+// ============================================================================
+
+XclExpDSF::XclExpDSF() :
+ XclExpRecord(0x0161, 2)
+{
+}
+
+XclExpDSF::~XclExpDSF()
+{
+}
+
+void XclExpDSF::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+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);
+}
+
+// ============================================================================
+
+XclExpExcel9File::XclExpExcel9File() :
+ XclExpRecord(0x01C0, 0)
+{
+}
+
+XclExpExcel9File::~XclExpExcel9File()
+{
+}
+
+void XclExpExcel9File::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ============================================================================
+
+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 )
diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx
index e0a20ad4353e..84fdba343630 100644
--- a/sc/source/filter/xml/XMLConverter.cxx
+++ b/sc/source/filter/xml/XMLConverter.cxx
@@ -31,20 +31,17 @@
// 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 <tools/datetime.hxx>
-#include <xmloff/xmltoken.hxx>
-#include <xmloff/xmluconv.hxx>
-#include <com/sun/star/util/DateTime.hpp>
+#include "ftools.hxx"
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
@@ -385,3 +382,292 @@ void ScXMLConverter::ConvertAPIToCoreDateTime(const util::DateTime& aDateTime, D
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
+
+// ----------------------------------------------------------------------------
+
+/*static*/ 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 );
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/filter/xml/XMLConverter.hxx b/sc/source/filter/xml/XMLConverter.hxx
index 75254a7b3300..090a3553aa91 100644
--- a/sc/source/filter/xml/XMLConverter.hxx
+++ b/sc/source/filter/xml/XMLConverter.hxx
@@ -36,8 +36,10 @@
#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;
@@ -117,6 +119,62 @@ public:
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
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 4ca83809843d..b9d9b4936961 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -203,44 +203,56 @@ void ScXMLExportDatabaseRanges::WriteImportDescriptor(const uno::Sequence <beans
}
}
-rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const sheet::FilterOperator aFilterOperator, const sal_Bool bUseRegularExpressions) const
+rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const
{
switch (aFilterOperator)
{
- case sheet::FilterOperator_EQUAL :
+ case sheet::FilterOperator2::EQUAL :
{
if (bUseRegularExpressions)
return GetXMLToken(XML_MATCH);
else
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
}
- case sheet::FilterOperator_NOT_EQUAL :
+ case sheet::FilterOperator2::NOT_EQUAL :
{
if (bUseRegularExpressions)
return GetXMLToken(XML_NOMATCH);
else
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
}
- case sheet::FilterOperator_BOTTOM_PERCENT :
+ case sheet::FilterOperator2::BOTTOM_PERCENT :
return GetXMLToken(XML_BOTTOM_PERCENT);
- case sheet::FilterOperator_BOTTOM_VALUES :
+ case sheet::FilterOperator2::BOTTOM_VALUES :
return GetXMLToken(XML_BOTTOM_VALUES);
- case sheet::FilterOperator_EMPTY :
+ case sheet::FilterOperator2::EMPTY :
return GetXMLToken(XML_EMPTY);
- case sheet::FilterOperator_GREATER :
+ case sheet::FilterOperator2::GREATER :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
- case sheet::FilterOperator_GREATER_EQUAL :
+ case sheet::FilterOperator2::GREATER_EQUAL :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
- case sheet::FilterOperator_LESS :
+ case sheet::FilterOperator2::LESS :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
- case sheet::FilterOperator_LESS_EQUAL :
+ case sheet::FilterOperator2::LESS_EQUAL :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
- case sheet::FilterOperator_NOT_EMPTY :
+ case sheet::FilterOperator2::NOT_EMPTY :
return GetXMLToken(XML_NOEMPTY);
- case sheet::FilterOperator_TOP_PERCENT :
+ case sheet::FilterOperator2::TOP_PERCENT :
return GetXMLToken(XML_TOP_PERCENT);
- case sheet::FilterOperator_TOP_VALUES :
+ 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
@@ -249,7 +261,7 @@ rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const sheet::FilterOpera
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
}
-void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
+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)
@@ -267,9 +279,9 @@ void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField& aF
SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
}
-void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName)
+void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName)
{
- uno::Sequence <sheet::TableFilterField> aTableFilterFields(xSheetFilterDescriptor->getFilterFields());
+ uno::Sequence< sheet::TableFilterField2 > aTableFilterFields( xSheetFilterDescriptor->getFilterFields2() );
sal_Int32 nTableFilterFields = aTableFilterFields.getLength();
if (nTableFilterFields > 0)
{
@@ -336,7 +348,7 @@ void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <shee
else
{
SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
- sheet::TableFilterField aPrevFilterField = aTableFilterFields[0];
+ 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));
@@ -632,7 +644,9 @@ void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::R
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::XSheetFilterDescriptor> xSheetFilterDescriptor(xDatabaseRange->getFilterDescriptor());
+
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
uno::Sequence <beans::PropertyValue> aSortProperties(xDatabaseRange->getSortDescriptor());
if (xSheetFilterDescriptor.is())
{
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.hxx b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
index c4829ffd3fdd..81d1399e16b3 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx
@@ -33,9 +33,9 @@
#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/beans/PropertyValue.hpp>
-#include <com/sun/star/sheet/FilterOperator.hpp>
-#include <com/sun/star/sheet/TableFilterField.hpp>
-#include <com/sun/star/sheet/XSheetFilterDescriptor.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>
@@ -49,9 +49,9 @@ class ScXMLExportDatabaseRanges
ScDocument* pDoc;
void WriteImportDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aImportDescriptor);
- rtl::OUString getOperatorXML(const com::sun::star::sheet::FilterOperator aFilterOperator, const sal_Bool bUseRegularExpressions) const;
- void WriteCondition(const com::sun::star::sheet::TableFilterField& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions);
- void WriteFilterDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSheetFilterDescriptor>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName);
+ 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:
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
index d1320a8c737f..2d8eac1dfc76 100644
--- a/sc/source/filter/xml/XMLTrackedChangesContext.cxx
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
@@ -109,6 +109,7 @@ class ScXMLCellContentDeletionContext : public SvXMLImportContext
{
rtl::OUString sFormulaAddress;
rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
rtl::OUString sInputString;
ScBigRange aBigRange;
double fValue;
@@ -298,7 +299,8 @@ public:
ScXMLChangeCellContext( ScXMLImport& rImport, USHORT 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& sFormula,
+ 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);
@@ -322,6 +324,7 @@ class ScXMLPreviousContext : public SvXMLImportContext
{
rtl::OUString sFormulaAddress;
rtl::OUString sFormula;
+ rtl::OUString sFormulaNmsp;
rtl::OUString sInputString;
double fValue;
ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
@@ -329,7 +332,7 @@ class ScXMLPreviousContext : public SvXMLImportContext
sal_uInt32 nID;
sal_Int32 nMatrixCols;
sal_Int32 nMatrixRows;
- formula::FormulaGrammar::Grammar eGrammar;
+ formula::FormulaGrammar::Grammar eGrammar;
sal_uInt16 nType;
sal_uInt8 nMatrixFlag;
@@ -831,7 +834,7 @@ SvXMLImportContext *ScXMLCellContentDeletionContext::CreateChildContext( USHORT
{
bContainsCell = sal_True;
pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
- pCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
+ pCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows );
}
else if (IsXMLToken(rLocalName, XML_CELL_ADDRESS))
{
@@ -1115,7 +1118,8 @@ ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList,
- ScBaseCell*& rTempOldCell, rtl::OUString& rAddress, rtl::OUString& rFormula,
+ 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 ) :
@@ -1130,7 +1134,6 @@ ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport,
bString(sal_True),
bFormula(sal_False)
{
- const formula::FormulaGrammar::Grammar eStorageGrammar = rGrammar = GetScImport().GetDocument()->GetStorageGrammar();
sal_Bool bIsMatrix(sal_False);
sal_Bool bIsCoveredMatrix(sal_False);
sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
@@ -1147,12 +1150,7 @@ ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport,
if (IsXMLToken(aLocalName, XML_FORMULA))
{
bEmpty = sal_False;
- sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
- _GetKeyByAttrName( sValue, &rFormula, sal_False );
-
- if (!ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
- sValue, rGrammar, eStorageGrammar))
- rFormula = sValue;
+ GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, rGrammar, sValue );
bFormula = sal_True;
}
else if (IsXMLToken(aLocalName, XML_CELL_ADDRESS))
@@ -1339,8 +1337,6 @@ ScXMLPreviousContext::ScXMLPreviousContext( ScXMLImport& rImport,
const uno::Reference<xml::sax::XAttributeList>& xAttrList,
ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) :
SvXMLImportContext( rImport, nPrfx, rLName ),
- sFormulaAddress(),
- sFormula(),
pChangeTrackingImportHelper(pTempChangeTrackingImportHelper),
pOldCell(NULL),
nID(0),
@@ -1380,7 +1376,7 @@ SvXMLImportContext *ScXMLPreviousContext::CreateChildContext( USHORT nPrefix,
if ((nPrefix == XML_NAMESPACE_TABLE) && (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL)))
pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList,
- pOldCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
+ pOldCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows);
if( !pContext )
pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx
index 5160b17a1a9d..f8081b7b8f48 100644
--- a/sc/source/filter/xml/xmlannoi.cxx
+++ b/sc/source/filter/xml/xmlannoi.cxx
@@ -31,13 +31,10 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
-
-
// INCLUDE ---------------------------------------------------------------
#include "xmlannoi.hxx"
#include "xmlimprt.hxx"
-#include "xmlcelli.hxx"
#include "xmlconti.hxx"
#include "XMLTableShapeImportHelper.hxx"
@@ -45,25 +42,34 @@
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmltoken.hxx>
-#include <svx/unoshape.hxx>
-#include <svx/svdobj.hxx>
-#include <svx/outlobj.hxx>
using namespace com::sun::star;
using namespace xmloff::token;
//------------------------------------------------------------------
+ScXMLAnnotationData::ScXMLAnnotationData() :
+ mbUseShapePos( false ),
+ mbShown( false )
+{
+}
+
+ScXMLAnnotationData::~ScXMLAnnotationData()
+{
+}
+
+//------------------------------------------------------------------
+
ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList,
+ ScXMLAnnotationData& rAnnotationData,
ScXMLTableRowCellContext* pTempCellContext) :
SvXMLImportContext( rImport, nPrfx, rLName ),
+ mrAnnotationData( rAnnotationData ),
nParagraphCount(0),
- bDisplay(sal_False),
bHasTextP(sal_False),
- bHasPos(sal_False),
pCellContext(pTempCellContext),
pShapeContext(NULL)
{
@@ -91,32 +97,32 @@ ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport,
{
case XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR:
{
- sAuthorBuffer = sValue;
+ maAuthorBuffer = sValue;
}
break;
case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE:
{
- sCreateDateBuffer = sValue;
+ maCreateDateBuffer = sValue;
}
break;
case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING:
{
- sCreateDateStringBuffer = sValue;
+ maCreateDateStringBuffer = sValue;
}
break;
case XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY:
{
- bDisplay = IsXMLToken(sValue, XML_TRUE);
+ mrAnnotationData.mbShown = IsXMLToken(sValue, XML_TRUE);
}
break;
case XML_TOK_TABLE_ANNOTATION_ATTR_X:
{
- bHasPos = sal_True;
+ mrAnnotationData.mbUseShapePos = true;
}
break;
case XML_TOK_TABLE_ANNOTATION_ATTR_Y:
{
- bHasPos = sal_True;
+ mrAnnotationData.mbUseShapePos = true;
}
break;
}
@@ -144,28 +150,28 @@ SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( USHORT nPrefix,
{
if( IsXMLToken( rLName, XML_CREATOR ) )
pContext = new ScXMLContentContext(GetScImport(), nPrefix,
- rLName, xAttrList, sAuthorBuffer);
+ rLName, xAttrList, maAuthorBuffer);
else if( IsXMLToken( rLName, XML_DATE ) )
pContext = new ScXMLContentContext(GetScImport(), nPrefix,
- rLName, xAttrList, sCreateDateBuffer);
+ rLName, xAttrList, maCreateDateBuffer);
}
else if( XML_NAMESPACE_META == nPrefix )
{
if( IsXMLToken( rLName, XML_DATE_STRING ) )
pContext = new ScXMLContentContext(GetScImport(), nPrefix,
- rLName, xAttrList, sCreateDateStringBuffer);
+ rLName, xAttrList, maCreateDateStringBuffer);
}
/* else if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_P) )
{
if (!bHasTextP)
{
bHasTextP = sal_True;
- sOUText.setLength(0);
+ maTextBuffer.setLength(0);
}
if(nParagraphCount)
- sOUText.append(static_cast<sal_Unicode>('\n'));
+ maTextBuffer.append(static_cast<sal_Unicode>('\n'));
++nParagraphCount;
- pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sOUText);
+ pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, maTextBuffer);
}*/
if( !pContext && pShapeContext )
@@ -180,7 +186,7 @@ SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( USHORT nPrefix,
void ScXMLAnnotationContext::Characters( const ::rtl::OUString& rChars )
{
if (!bHasTextP)
- sOUText.append(rChars);
+ maTextBuffer.append(rChars);
}
void ScXMLAnnotationContext::EndElement()
@@ -191,41 +197,19 @@ void ScXMLAnnotationContext::EndElement()
delete pShapeContext;
}
- ScMyImportAnnotation* pMyAnnotation = new ScMyImportAnnotation();
- pMyAnnotation->sAuthor = sAuthorBuffer.makeStringAndClear();
- pMyAnnotation->sCreateDate = sCreateDateBuffer.makeStringAndClear();
- if (!pMyAnnotation->sCreateDate.getLength())
- pMyAnnotation->sCreateDate = sCreateDateStringBuffer.makeStringAndClear();
- pMyAnnotation->sText = sOUText.makeStringAndClear();
- pMyAnnotation->bDisplay = bDisplay;
-
- if (xShape.is() && xShapes.is())
- {
- SvxShape* pShapeImp = SvxShape::getImplementation(xShape);
- if (pShapeImp)
- {
- SdrObject *pSdrObj = pShapeImp->GetSdrObject();
- if (pSdrObj)
- {
- if (bHasPos)
- {
- pMyAnnotation->pItemSet = pSdrObj->GetMergedItemSet().Clone();
- awt::Point aPos = xShape->getPosition();
- awt::Size aSize = xShape->getSize();
- Rectangle aRect(Point(aPos.X, aPos.Y), Size(aSize.Width, aSize.Height));
- pMyAnnotation->pRect = new Rectangle(aRect);
- }
-
- if( OutlinerParaObject* pOPO = pSdrObj->GetOutlinerParaObject() )
- pMyAnnotation->pOPO = new OutlinerParaObject( *pOPO );
-
- xShapes->remove(xShape);
- }
- }
- }
+ 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);
+}
- pCellContext->AddAnnotation(pMyAnnotation);
+void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes )
+{
+ mrAnnotationData.mxShape = rxShape;
+ mrAnnotationData.mxShapes = rxShapes;
}
+
diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx
index 3a65d5b444ff..c509b72124ed 100644
--- a/sc/source/filter/xml/xmlannoi.hxx
+++ b/sc/source/filter/xml/xmlannoi.hxx
@@ -30,6 +30,7 @@
#ifndef SC_XMLANNOI_HXX
#define SC_XMLANNOI_HXX
+#include <memory>
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <rtl/ustrbuf.hxx>
@@ -39,30 +40,31 @@
class ScXMLImport;
class ScXMLTableRowCellContext;
-class ScXMLAnnotationContext : public SvXMLImportContext
+struct ScXMLAnnotationData
{
- rtl::OUStringBuffer sOUText;
- rtl::OUStringBuffer sAuthorBuffer;
- rtl::OUStringBuffer sCreateDateBuffer;
- rtl::OUStringBuffer sCreateDateStringBuffer;
- sal_Int32 nParagraphCount;
- sal_Bool bDisplay;
- sal_Bool bHasTextP;
- sal_Bool bHasPos;
- ScXMLTableRowCellContext* pCellContext;
- SvXMLImportContext* pShapeContext;
- com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape;
- com::sun::star::uno::Reference< com::sun::star::drawing::XShapes > xShapes;
+ ::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;
+ bool mbUseShapePos;
+ bool mbShown;
- const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
- ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+ explicit ScXMLAnnotationData();
+ ~ScXMLAnnotationData();
+};
+class ScXMLAnnotationContext : public SvXMLImportContext
+{
public:
ScXMLAnnotationContext( ScXMLImport& rImport, USHORT nPrfx,
const ::rtl::OUString& rLName,
const ::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLAnnotationData& rAnnotationData,
ScXMLTableRowCellContext* pCellContext);
virtual ~ScXMLAnnotationContext();
@@ -78,8 +80,23 @@ public:
virtual void EndElement();
- void SetShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xTempShape,
- const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xTempShapes) { xShape.set(xTempShape); xShapes.set(xTempShapes); }
+ 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 );
+
+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(); }
};
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
index fd9562a9b1fb..048f1ec0c549 100644
--- a/sc/source/filter/xml/xmlbodyi.cxx
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -52,6 +52,7 @@
#include "XMLTrackedChangesContext.hxx"
#include "XMLEmptyContext.hxx"
#include "scerrors.hxx"
+#include "tabprotection.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -62,7 +63,10 @@
#include <sal/types.h>
#include <tools/debug.hxx>
+#include <memory>
+
using rtl::OUString;
+
using namespace com::sun::star;
using namespace xmloff::token;
@@ -281,10 +285,17 @@ void ScXMLBodyContext::EndElement()
// #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);
- pDoc->SetDocProtection(bProtected, aPass);
+ pProtection->setPasswordHash(aPass, PASSHASH_OOO);
+ }
+
+ pDoc->SetDocProtection(pProtection.get());
}
}
GetScImport().UnlockSolarMutex();
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 06c84ac83366..f0a4569cc86e 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -68,6 +68,7 @@
#include <svx/svdocapt.hxx>
#include <svx/outlobj.hxx>
#include <svx/editobj.hxx>
+#include <svx/unoapi.hxx>
#include <svtools/languageoptions.hxx>
#include <com/sun/star/frame/XModel.hpp>
@@ -99,15 +100,6 @@ using namespace xmloff::token;
//------------------------------------------------------------------
-ScMyImportAnnotation::~ScMyImportAnnotation()
-{
- delete pRect;
- delete pItemSet;
- delete pOPO;
-}
-
-//------------------------------------------------------------------
-
ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -117,7 +109,6 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
const sal_Int32 nTempRepeatedRows ) :
SvXMLImportContext( rImport, nPrfx, rLName ),
pContentValidationName(NULL),
- pMyAnnotation(NULL),
pDetectiveObjVec(NULL),
pCellRangeSource(NULL),
fValue(0.0),
@@ -138,7 +129,6 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
bSolarMutexLocked(sal_False),
bFormulaTextResult(sal_False)
{
- formula::FormulaGrammar::Grammar eStorageGrammar = eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
rXMLImport.SetRemoveLastChar(sal_False);
rXMLImport.GetTables().AddColumn(bTempIsCovered);
const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
@@ -241,25 +231,9 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
if (sValue.getLength())
{
DBG_ASSERT(!pOUFormula, "here should be only one formula");
- rtl::OUString sFormula;
- sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
- _GetKeyByAttrName( sValue, &sFormula, sal_False );
-
- if (ScXMLImport::IsAcceptedFormulaNamespace(
- nFormulaPrefix, sValue, eGrammar,
- eStorageGrammar))
- {
- // Namespaces we accept.
- pOUFormula.reset( sFormula);
- }
- else
- {
- // No namespace => entire string.
- // Also unknown namespace included in formula,
- // so hopefully will result in string or
- // compile error.
- pOUFormula.reset( sValue);
- }
+ rtl::OUString aFormula, aFormulaNmsp;
+ rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
+ pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
}
}
break;
@@ -283,8 +257,6 @@ ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
{
if (pContentValidationName)
delete pContentValidationName;
- if (pMyAnnotation)
- delete pMyAnnotation;
if (pDetectiveObjVec)
delete pDetectiveObjVec;
if (pCellRangeSource)
@@ -425,8 +397,10 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( USHORT nPrefix
case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
{
bIsEmpty = sal_False;
+ DBG_ASSERT( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
+ mxAnnotationData.reset( new ScXMLAnnotationData );
pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
- xAttrList, this);
+ xAttrList, *mxAnnotationData, this);
}
break;
case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
@@ -539,7 +513,7 @@ void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Referen
if (pContentValidationName)
{
ScMyImportValidation aValidation;
- aValidation.eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
+ 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);
@@ -568,8 +542,11 @@ void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Referen
// #b4974740# 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.
- xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar)));
+ // 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));
@@ -607,71 +584,98 @@ void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCe
void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress)
{
- /*uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor(xCell, uno::UNO_QUERY);
- if (xSheetAnnotationAnchor.is())
+ 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() )
{
- uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation (xSheetAnnotationAnchor->getAnnotation());
- uno::Reference<text::XSimpleText> xSimpleText(xSheetAnnotation, uno::UNO_QUERY);
- if (xSheetAnnotation.is() && xSimpleText.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 )
{
- xSimpleText->setString(aMyAnnotation.sText);
- //xSheetAnnotation->setAuthor(aMyAnnotation.sAuthor);
- //xSheetAnnotation->setDate();
- xSheetAnnotation->setIsVisible(aMyAnnotation.bDisplay);
+ 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;
+ }
}
- }*/
- if( pMyAnnotation )
- {
- double fDate;
- rXMLImport.GetMM100UnitConverter().convertDateTime(fDate, pMyAnnotation->sCreateDate);
- ScDocument* pDoc = rXMLImport.GetDocument();
- if (pDoc)
+
+ // drawing object has not been used to create a note -> use shape data
+ if( pObject )
{
- LockSolarMutex();
- SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
- sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM);
- String sDate;
- Color* pColor = NULL;
- Color** ppColor = &pColor;
- pNumForm->GetOutputString(fDate, nfIndex, sDate, ppColor);
+ // 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();
- ScAddress aPos;
- ScUnoConversion::FillScAddress( aPos, aCellAddress );
- if( ScPostIt* pNote = pDoc->GetOrCreateNote( aPos ) )
+ // an outliner object is required (empty note captions not allowed)
+ if( xOutlinerObj.get() )
{
- pNote->SetDate( sDate );
- pNote->SetAuthor( pMyAnnotation->sAuthor );
- if( SdrCaptionObj* pCaption = pNote->GetCaption() )
- {
- if( pMyAnnotation->pOPO )
- {
- // transfer outliner object to caption
- pCaption->SetOutlinerParaObject( pMyAnnotation->pOPO );
- // do not delete the object in ScMyImportAnnotation d'tor
- pMyAnnotation->pOPO = 0;
- }
- else
- pCaption->SetText( pMyAnnotation->sText );
- // copy all items and reset shadow items
- if( pMyAnnotation->pItemSet )
- pNote->SetCaptionItems( *pMyAnnotation->pItemSet );
- else
- pNote->SetCaptionDefaultItems(); // default items need to be applied to text
- if( pMyAnnotation->pRect )
- pCaption->SetLogicRect( *pMyAnnotation->pRect );
-
- uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
- if (xShapesIndex.is())
- {
- sal_Int32 nShapes = xShapesIndex->getCount();
- uno::Reference < drawing::XShape > xShape;
- rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
- }
- }
- pNote->ShowCaption( pMyAnnotation->bDisplay );
+ // 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() );
+ }
}
// core implementation
@@ -798,7 +802,7 @@ void ScXMLTableRowCellContext::EndElement()
// uno::Reference <table::XCell> xCell;
table::CellAddress aCurrentPos( aCellPos );
if ((pContentValidationName && pContentValidationName->getLength()) ||
- pMyAnnotation || pDetectiveObjVec || pCellRangeSource)
+ mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource)
bIsEmpty = sal_False;
ScMyTables& rTables = rXMLImport.GetTables();
@@ -980,7 +984,7 @@ void ScXMLTableRowCellContext::EndElement()
}
else
{
- if (!bWasEmpty || (pMyAnnotation))
+ if (!bWasEmpty || mxAnnotationData.get())
{
if (aCurrentPos.Row > MAXROW)
rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
@@ -1028,7 +1032,7 @@ void ScXMLTableRowCellContext::EndElement()
//SetType(xTempCell);
}
}
- else
+ else // if ( !pOUFormula )
{
if (CellExists(aCellPos))
{
@@ -1041,7 +1045,7 @@ void ScXMLTableRowCellContext::EndElement()
{
DBG_ERRORFILE("It seems here are to many columns or rows");
}
- if (xCell.is() && pOUFormula)
+ if (xCell.is())
{
SetCellProperties(xCell); // set now only the validation
DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
@@ -1054,7 +1058,7 @@ void ScXMLTableRowCellContext::EndElement()
xCell));
if (pCellObj)
{
- pCellObj->SetFormulaWithGrammar( *pOUFormula, eGrammar);
+ pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar);
if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength())
pCellObj->SetFormulaResultString( *pOUTextValue);
else if (fValue != 0.0)
@@ -1069,7 +1073,7 @@ void ScXMLTableRowCellContext::EndElement()
aCellPos.Column, aCellPos.Row,
aCellPos.Column + nMatrixCols - 1,
aCellPos.Row + nMatrixRows - 1,
- *pOUFormula, eGrammar);
+ pOUFormula->first, pOUFormula->second, eGrammar);
}
}
SetAnnotation( aCellPos );
@@ -1086,7 +1090,7 @@ void ScXMLTableRowCellContext::EndElement()
rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
}
- }
+ } // if ( !pOUFormula )
}
UnlockSolarMutex();
}
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 67b619a15ed3..fe2bfd116348 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -30,6 +30,7 @@
#ifndef SC_XMLCELLI_HXX
#define SC_XMLCELLI_HXX
+#include <memory>
#include "XMLDetectiveContext.hxx"
#include "XMLCellRangeSourceContext.hxx"
#include <xmloff/xmlictxt.hxx>
@@ -37,7 +38,6 @@
#include <com/sun/star/table/XCell.hpp>
#include <tools/time.hxx>
#include <com/sun/star/util/DateTime.hpp>
-#include <sal/types.h>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/table/CellRangeAddress.hpp>
#include <com/sun/star/table/CellAddress.hpp>
@@ -48,31 +48,18 @@
#include <boost/optional.hpp>
class ScXMLImport;
-class OutlinerParaObject;
-
-struct ScMyImportAnnotation
-{
- rtl::OUString sAuthor;
- rtl::OUString sCreateDate;
- rtl::OUString sText;
- sal_Bool bDisplay;
- Rectangle* pRect;
- SfxItemSet* pItemSet;
- OutlinerParaObject* pOPO;
-
- ScMyImportAnnotation() : bDisplay(sal_False), pRect(NULL), pItemSet(NULL), pOPO(NULL) {}
- ~ScMyImportAnnotation();
-};
+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< rtl::OUString > pOUFormula;
+ ::boost::optional< FormulaWithNamespace > pOUFormula;
rtl::OUString* pContentValidationName;
- ScMyImportAnnotation* pMyAnnotation;
+ ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData;
ScMyImpDetectiveObjVec* pDetectiveObjVec;
ScMyImpCellRangeSource* pCellRangeSource;
double fValue;
@@ -140,8 +127,6 @@ public:
void SetCellRangeSource( const ::com::sun::star::table::CellAddress& rPosition );
virtual void EndElement();
-
- void AddAnnotation(ScMyImportAnnotation* pValue) { pMyAnnotation = pValue; }
};
#endif
diff --git a/sc/source/filter/xml/xmlcvali.cxx b/sc/source/filter/xml/xmlcvali.cxx
index d8d8eb0d7cc2..aeff28f3eed6 100644
--- a/sc/source/filter/xml/xmlcvali.cxx
+++ b/sc/source/filter/xml/xmlcvali.cxx
@@ -51,6 +51,8 @@
using namespace com::sun::star;
using namespace xmloff::token;
+using namespace ::formula;
+using ::rtl::OUString;
class ScXMLContentValidationContext : public SvXMLImportContext
{
@@ -62,7 +64,6 @@ class ScXMLContentValidationContext : public SvXMLImportContext
rtl::OUString sErrorMessageType;
rtl::OUString sBaseCellAddress;
rtl::OUString sCondition;
- formula::FormulaGrammar::Grammar eGrammar;
sal_Int16 nShowList;
sal_Bool bAllowEmptyCell;
sal_Bool bDisplayHelp;
@@ -73,11 +74,10 @@ class ScXMLContentValidationContext : public SvXMLImportContext
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
- void GetAlertStyle(const rtl::OUString& sMessageType, com::sun::star::sheet::ValidationAlertStyle& aAlertStyle);
- void SetFormulas(const rtl::OUString& sFormulas, rtl::OUString& sFormula1, rtl::OUString& sFormula2) const;
- void GetCondition(const rtl::OUString& sCondition, rtl::OUString& sFormula1, rtl::OUString& sFormula2,
- com::sun::star::sheet::ValidationType& aValidationType,
- com::sun::star::sheet::ConditionOperator& aOperator);
+ 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:
@@ -235,20 +235,11 @@ ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImpo
const ::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
SvXMLImportContext( rImport, nPrfx, rLName ),
- sName(),
- sHelpTitle(),
- sHelpMessage(),
- sErrorTitle(),
- sErrorMessage(),
- sErrorMessageType(),
- sBaseCellAddress(),
- sCondition(),
nShowList(sheet::TableValidationVisibility::UNSORTED),
bAllowEmptyCell(sal_True),
bDisplayHelp(sal_False),
bDisplayError(sal_False)
{
- const formula::FormulaGrammar::Grammar eStorageGrammar = eGrammar = GetScImport().GetDocument()->GetStorageGrammar();
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationAttrTokenMap();
for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -265,14 +256,7 @@ ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImpo
sName = sValue;
break;
case XML_TOK_CONTENT_VALIDATION_CONDITION:
- {
- sal_uInt16 nCondPrefix = GetImport().GetNamespaceMap().
- _GetKeyByAttrName( sValue, &sCondition, sal_False );
-
- if (!ScXMLImport::IsAcceptedFormulaNamespace( nCondPrefix,
- sValue, eGrammar, eStorageGrammar))
- sCondition = sValue;
- }
+ sCondition = sValue;
break;
case XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS:
sBaseCellAddress = sValue;
@@ -336,189 +320,116 @@ SvXMLImportContext *ScXMLContentValidationContext::CreateChildContext( USHORT nP
return pContext;
}
-void ScXMLContentValidationContext::GetAlertStyle(const rtl::OUString& sMessageType, com::sun::star::sheet::ValidationAlertStyle& aAlertStyle)
+sheet::ValidationAlertStyle ScXMLContentValidationContext::GetAlertStyle() const
{
- if (IsXMLToken(sMessageType, XML_MACRO))
- aAlertStyle = sheet::ValidationAlertStyle_MACRO;
- else if (IsXMLToken(sMessageType, XML_STOP))
- aAlertStyle = sheet::ValidationAlertStyle_STOP;
- else if (IsXMLToken(sMessageType, XML_WARNING))
- aAlertStyle = sheet::ValidationAlertStyle_WARNING;
- else if (IsXMLToken(sMessageType, XML_INFORMATION))
- aAlertStyle = sheet::ValidationAlertStyle_INFO;
- else // don't leave uninitialized
- aAlertStyle = sheet::ValidationAlertStyle_STOP;
+ 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::SetFormulas(const rtl::OUString& sFormulas, rtl::OUString& sFormula1, rtl::OUString& sFormula2) const
+void ScXMLContentValidationContext::SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const
{
- sal_Int32 i = 0;
- sal_Bool bString = sal_False;
- sal_Int32 nBrakes = 0;
- while ((sFormulas[i] != ',' || nBrakes > 0 || bString) && i < sFormulas.getLength())
+ reGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
{
- if (sFormulas[i] == '(')
- ++nBrakes;
- if (sFormulas[i] == ')')
- --nBrakes;
- if (sFormulas[i] == '"')
- bString = !bString;
- ++i;
+ // the entire attribute contains a namespace: internal namespace not allowed
+ rFormula = rCondition;
+ rFormulaNmsp = rGlobNmsp;
+ reGrammar = eGlobGrammar;
}
- if (sFormulas[i] == ',')
+ else
{
- sFormula1 = sFormulas.copy(0, i);
- sFormula2 = sFormulas.copy(i + 1);
+ // 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(const rtl::OUString& sTempCondition, rtl::OUString& sFormula1, rtl::OUString& sFormula2,
- com::sun::star::sheet::ValidationType& aValidationType,
- com::sun::star::sheet::ConditionOperator& aOperator)
+void ScXMLContentValidationContext::GetCondition( ScMyImportValidation& rValidation ) const
{
- aValidationType = sheet::ValidationType_ANY; // #b6343997# default if no condition is given
- aOperator = sheet::ConditionOperator_NONE;
+ rValidation.aValidationType = sheet::ValidationType_ANY; // #b6343997# default if no condition is given
+ rValidation.aOperator = sheet::ConditionOperator_NONE;
- rtl::OUString sLocalCondition(sTempCondition);
- if (sLocalCondition.getLength())
+ if( sCondition.getLength() > 0 )
{
- // ToDo: erase all blanks in the condition, but not in formulas or strings
- rtl::OUString scell_content(RTL_CONSTASCII_USTRINGPARAM("cell_content"));
- rtl::OUString scell_content_is_date(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-date"));
- rtl::OUString scell_content_is_time(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-time"));
- rtl::OUString scell_content_is_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between"));
- rtl::OUString scell_content_is_in_list(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-in-list"));
- rtl::OUString scell_content_text_length(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length"));
- rtl::OUString scell_content_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between"));
- rtl::OUString scell_content_is_whole_number(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-whole-number"));
- rtl::OUString scell_content_is_decimal_number(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-decimal-number"));
- rtl::OUString scell_content_text_length_is_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-between"));
- rtl::OUString scell_content_text_length_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-not-between"));
- sal_Int32 i = 0;
- sal_Bool bAnd(sal_True);
- while (sLocalCondition[i] != '(' && i < sLocalCondition.getLength())
- ++i;
- if (sLocalCondition[i] == '(')
+ // 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 )
{
- if (i != scell_content_text_length.getLength() &&
- i != scell_content_text_length_is_between.getLength() &&
- i != scell_content_text_length_is_not_between.getLength() &&
- i != scell_content_is_in_list.getLength())
- {
- if (i == scell_content_is_time.getLength())
- {
- rtl::OUString sTemp = sLocalCondition.copy(0, i);
- if (sTemp == scell_content_is_time)
- aValidationType = sheet::ValidationType_TIME;
- else
- aValidationType = sheet::ValidationType_DATE;
- }
- else if (i == scell_content_is_whole_number.getLength())
- aValidationType = sheet::ValidationType_WHOLE;
- else if (i == scell_content_is_decimal_number.getLength())
- aValidationType = sheet::ValidationType_DECIMAL;
- sLocalCondition = sLocalCondition.copy(i + 2);
- rtl::OUString sTemp = sLocalCondition.copy(0, 5);
- if (sTemp.compareToAscii(" and ") == 0)
- sLocalCondition = sLocalCondition.copy(5);
- else
- bAnd = sal_False;
- }
- if (sLocalCondition.getLength() && bAnd)
+ 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 )
{
- i = 0;
- while (sLocalCondition[i] != '(' && i < sLocalCondition.getLength())
- ++i;
- if (sLocalCondition[i] == '(')
+ ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex );
+ switch( aParseResult.meToken )
{
- rtl::OUString sTemp = sLocalCondition.copy(0, i);
- sLocalCondition = sLocalCondition.copy(i + 1);
- if (i == scell_content_is_between.getLength() ||
- i == scell_content_text_length_is_between.getLength())
- {
- if (sTemp == scell_content_is_in_list)
- {
- aValidationType = sheet::ValidationType_LIST;
- sFormula1 = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
- aOperator = sheet::ConditionOperator_EQUAL;
- }
- else
- {
- if (i == scell_content_text_length_is_between.getLength())
- aValidationType = sheet::ValidationType_TEXT_LEN;
- aOperator = sheet::ConditionOperator_BETWEEN;
- sLocalCondition = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
- SetFormulas(sLocalCondition, sFormula1, sFormula2);
- }
- }
- else if (i == scell_content_is_not_between.getLength() ||
- i == scell_content_text_length_is_not_between.getLength())
- {
- if (i == scell_content_text_length_is_not_between.getLength())
- aValidationType = sheet::ValidationType_TEXT_LEN;
- aOperator = sheet::ConditionOperator_NOT_BETWEEN;
- sLocalCondition = sLocalCondition.copy(0, sLocalCondition.getLength() - 1);
- SetFormulas(sLocalCondition, sFormula1, sFormula2);
- }
- else if (i == scell_content.getLength() ||
- i == scell_content_text_length.getLength())
- {
- if (i == scell_content_text_length.getLength())
- aValidationType = sheet::ValidationType_TEXT_LEN;
- sLocalCondition = sLocalCondition.copy(1);
- switch (sLocalCondition[0])
- {
- case '<' :
- {
- if (sLocalCondition[1] == '=')
- {
- aOperator = sheet::ConditionOperator_LESS_EQUAL;
- sLocalCondition = sLocalCondition.copy(2);
- }
- else
- {
- aOperator = sheet::ConditionOperator_LESS;
- sLocalCondition = sLocalCondition.copy(1);
- }
- }
- break;
- case '>' :
- {
- if (sLocalCondition[1] == '=')
- {
- aOperator = sheet::ConditionOperator_GREATER_EQUAL;
- sLocalCondition = sLocalCondition.copy(2);
- }
- else
- {
- aOperator = sheet::ConditionOperator_GREATER;
- sLocalCondition = sLocalCondition.copy(1);
- }
- }
- break;
- case '=' :
- {
- aOperator = sheet::ConditionOperator_EQUAL;
- sLocalCondition = sLocalCondition.copy(1);
- }
- break;
- case '!' :
- {
- aOperator = sheet::ConditionOperator_NOT_EQUAL;
- sLocalCondition = sLocalCondition.copy(1);
- }
- break;
- }
- sFormula1 = sLocalCondition;
- }
+ 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 ( aOperator == sheet::ConditionOperator_NONE )
- aValidationType = sheet::ValidationType_ANY;
+ // 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()
@@ -546,15 +457,15 @@ void ScXMLContentValidationContext::EndElement()
}
ScMyImportValidation aValidation;
- aValidation.eGrammar = eGrammar;
+ 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(sCondition, aValidation.sFormula1, aValidation.sFormula2, aValidation.aValidationType, aValidation.aOperator);
- GetAlertStyle(sErrorMessageType, aValidation.aAlertStyle);
+ GetCondition( aValidation );
+ aValidation.aAlertStyle = GetAlertStyle();
aValidation.bShowErrorMessage = bDisplayError;
aValidation.bShowImputMessage = bDisplayHelp;
aValidation.bIgnoreBlanks = bAllowEmptyCell;
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index e2aa6fcd7504..55a1859211d0 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -381,7 +381,8 @@ void ScXMLDatabaseRangeContext::EndElement()
pDBData->SetSortParam(aSortParam);
}
- uno::Reference <sheet::XSheetFilterDescriptor> xSheetFilterDescriptor(xDatabaseRange->getFilterDescriptor());
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY );
if (xSheetFilterDescriptor.is())
{
uno::Reference <beans::XPropertySet> xFilterPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY);
@@ -396,7 +397,7 @@ void ScXMLDatabaseRangeContext::EndElement()
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->setFilterFields(aFilterFields);
+ xSheetFilterDescriptor->setFilterFields2(aFilterFields);
if (bFilterConditionSourceRange)
{
ScRange aAdvSource;
diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx
index 36c668b0f77f..be55e5b143cc 100644
--- a/sc/source/filter/xml/xmldrani.hxx
+++ b/sc/source/filter/xml/xmldrani.hxx
@@ -36,7 +36,7 @@
#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/TableFilterField.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>
@@ -79,7 +79,7 @@ class ScXMLDatabaseRangeContext : public SvXMLImportContext
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::TableFilterField> aFilterFields;
+ 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;
@@ -146,7 +146,7 @@ public:
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::TableFilterField>& aTemp) { aFilterFields = aTemp; }
+ 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; }
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 7d95e92c2891..98965cba07bc 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -69,6 +69,7 @@
#include "postit.hxx"
#include "externalrefmgr.hxx"
#include "editutil.hxx"
+#include "tabprotection.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
@@ -595,6 +596,7 @@ void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCo
if (!pSharedData)
CreateSharedData(nTableCount);
pCellStyles->AddNewTable(nTableCount - 1);
+ pDoc->InitializeAllNoteCaptions( true );
if (HasDrawPages(xSpreadDoc))
{
rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ));
@@ -1469,7 +1471,11 @@ void ScXMLExport::SetBodyAttributes()
{
AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
- SvXMLUnitConverter::encodeBase64(aBuffer, pDoc->GetDocPassword());
+ uno::Sequence<sal_Int8> aPassHash;
+ const ScDocProtection* p = pDoc->GetDocProtection();
+ if (p)
+ aPassHash = p->getPasswordHash(PASSHASH_OOO);
+ SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash);
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
@@ -1543,7 +1549,11 @@ void ScXMLExport::_ExportContent()
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
if (pDoc)
- SvXMLUnitConverter::encodeBase64(aBuffer, pDoc->GetTabPassword(static_cast<SCTAB>(nTable)));
+ {
+ ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable));
+ if (pProtect)
+ SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO));
+ }
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx
index 59d53542535a..87bdc748906c 100644
--- a/sc/source/filter/xml/xmlfilti.cxx
+++ b/sc/source/filter/xml/xmlfilti.cxx
@@ -335,48 +335,60 @@ SvXMLImportContext *ScXMLConditionContext::CreateChildContext( USHORT nPrefix,
return new SvXMLImportContext( GetImport(), nPrefix, rLName );
}
-void ScXMLConditionContext::getOperatorXML(const rtl::OUString sTempOperator, sheet::FilterOperator& aFilterOperator, sal_Bool& bUseRegularExpressions) const
+void ScXMLConditionContext::getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const
{
bUseRegularExpressions = sal_False;
if (IsXMLToken(sTempOperator, XML_MATCH))
{
bUseRegularExpressions = sal_True;
- aFilterOperator = sheet::FilterOperator_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
}
else if (IsXMLToken(sTempOperator, XML_NOMATCH))
{
bUseRegularExpressions = sal_True;
- aFilterOperator = sheet::FilterOperator_NOT_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
}
else if (sTempOperator.compareToAscii("=") == 0)
- aFilterOperator = sheet::FilterOperator_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::EQUAL;
else if (sTempOperator.compareToAscii("!=") == 0)
- aFilterOperator = sheet::FilterOperator_NOT_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::NOT_EQUAL;
else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT))
- aFilterOperator = sheet::FilterOperator_BOTTOM_PERCENT;
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_PERCENT;
else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES))
- aFilterOperator = sheet::FilterOperator_BOTTOM_VALUES;
+ aFilterOperator = sheet::FilterOperator2::BOTTOM_VALUES;
else if (IsXMLToken(sTempOperator, XML_EMPTY))
- aFilterOperator = sheet::FilterOperator_EMPTY;
+ aFilterOperator = sheet::FilterOperator2::EMPTY;
else if (sTempOperator.compareToAscii(">") == 0)
- aFilterOperator = sheet::FilterOperator_GREATER;
+ aFilterOperator = sheet::FilterOperator2::GREATER;
else if (sTempOperator.compareToAscii(">=") == 0)
- aFilterOperator = sheet::FilterOperator_GREATER_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::GREATER_EQUAL;
else if (sTempOperator.compareToAscii("<") == 0)
- aFilterOperator = sheet::FilterOperator_LESS;
+ aFilterOperator = sheet::FilterOperator2::LESS;
else if (sTempOperator.compareToAscii("<=") == 0)
- aFilterOperator = sheet::FilterOperator_LESS_EQUAL;
+ aFilterOperator = sheet::FilterOperator2::LESS_EQUAL;
else if (IsXMLToken(sTempOperator, XML_NOEMPTY))
- aFilterOperator = sheet::FilterOperator_NOT_EMPTY;
+ aFilterOperator = sheet::FilterOperator2::NOT_EMPTY;
else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT))
- aFilterOperator = sheet::FilterOperator_TOP_PERCENT;
+ aFilterOperator = sheet::FilterOperator2::TOP_PERCENT;
else if (IsXMLToken(sTempOperator, XML_TOP_VALUES))
- aFilterOperator = sheet::FilterOperator_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::TableFilterField aFilterField;
+ sheet::TableFilterField2 aFilterField;
if (pFilterContext->GetConnection())
aFilterField.Connection = sheet::FilterConnection_OR;
else
diff --git a/sc/source/filter/xml/xmlfilti.hxx b/sc/source/filter/xml/xmlfilti.hxx
index f0021e9dda1b..b2b45175c138 100644
--- a/sc/source/filter/xml/xmlfilti.hxx
+++ b/sc/source/filter/xml/xmlfilti.hxx
@@ -36,7 +36,8 @@
#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/TableFilterField.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
#include <tools/stack.hxx>
#include "xmldrani.hxx"
@@ -48,7 +49,7 @@ class ScXMLFilterContext : public SvXMLImportContext
{
ScXMLDatabaseRangeContext* pDatabaseRangeContext;
- com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField> aFilterFields;
+ 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;
@@ -89,7 +90,7 @@ public:
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::TableFilterField aFilterField) { aFilterFields.realloc(aFilterFields.getLength() + 1);
+ void AddFilterField(const com::sun::star::sheet::TableFilterField2 aFilterField) { aFilterFields.realloc(aFilterFields.getLength() + 1);
aFilterFields[aFilterFields.getLength() - 1] = aFilterField; }
};
@@ -171,7 +172,7 @@ public:
const ::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList>& xAttrList );
- void getOperatorXML(const rtl::OUString sTempOperator, com::sun::star::sheet::FilterOperator& aFilterOperator, sal_Bool& bUseRegularExpressions) const;
+ void getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const;
virtual void EndElement();
};
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 873e95168088..200e33743020 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -74,6 +74,7 @@
#include "unonames.hxx"
#include "rangeutl.hxx"
#include "postit.hxx"
+#include "formulaparserpool.hxx"
#include <comphelper/extract.hxx>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -2850,36 +2851,99 @@ void ScXMLImport::ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc)
}
}
-// static
-bool ScXMLImport::IsAcceptedFormulaNamespace( const sal_uInt16 nFormulaPrefix,
- const rtl::OUString & rValue, formula::FormulaGrammar::Grammar& rGrammar,
- const formula::FormulaGrammar::Grammar eStorageGrammar )
+sal_Int32 ScXMLImport::GetVisibleSheet()
{
- switch (nFormulaPrefix)
+ // 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())
{
- case XML_NAMESPACE_OF:
- rGrammar = formula::FormulaGrammar::GRAM_ODFF;
- return true;
- case XML_NAMESPACE_OOOC:
- rGrammar = formula::FormulaGrammar::GRAM_PODF;
- return true;
+ 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;
+ }
+ }
+ }
+ }
+ }
}
- // An invalid namespace can occur from a colon in the formula text if no
- // namespace tag was added. First character in string has to be '=' in that
- // case.
- bool bNoNamespace = (nFormulaPrefix == XML_NAMESPACE_NONE ||
- (nFormulaPrefix == XML_NAMESPACE_UNKNOWN && rValue.toChar() == '='));
-
- if (bNoNamespace && eStorageGrammar == formula::FormulaGrammar::GRAM_PODF)
- // There may be documents in the wild that stored no namespace in ODF 1.x
- rGrammar = formula::FormulaGrammar::GRAM_PODF;
- else if (bNoNamespace)
- // The default for ODF 1.2 and later without namespace is 'of:' ODFF
- rGrammar = formula::FormulaGrammar::GRAM_ODFF;
- else
- // Whatever ...
- rGrammar = eStorageGrammar;
+ return 0;
+}
- return false;
+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, sal_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;
}
+
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 052ef20c6022..f96d34c40ca5 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -598,6 +598,7 @@ struct ScMyNamedExpression
{
rtl::OUString sName;
rtl::OUString sContent;
+ rtl::OUString sContentNmsp;
rtl::OUString sBaseCellAddress;
rtl::OUString sRangeType;
formula::FormulaGrammar::Grammar eGrammar;
@@ -624,11 +625,14 @@ struct ScMyImportValidation
rtl::OUString sErrorMessage;
rtl::OUString sFormula1;
rtl::OUString sFormula2;
+ rtl::OUString sFormulaNmsp1;
+ rtl::OUString sFormulaNmsp2;
rtl::OUString sBaseCellAddress; // #b4974740# 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 eGrammar;
+ formula::FormulaGrammar::Grammar eGrammar1;
+ formula::FormulaGrammar::Grammar eGrammar2;
sal_Int16 nShowList;
sal_Bool bShowErrorMessage;
sal_Bool bShowImputMessage;
@@ -983,46 +987,43 @@ public:
void SetLabelRanges();
void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
-
- /** If namespace prefix is an accepted formula namespace.
-
- For an accepted namespace (return <TRUE/>), the formula text is the
- part without the namespace tag (aFormula of the _GetKeyByAttrName()
- example below).
-
- For an invalid namespace (not defined in the file,
- XML_NAMESPACE_UNKNOWN; may also be the result of no namespace with
- colon in the formula text, in that case text has to start with
- character '=') or no namespace tag (XML_NAMESPACE_NONE) the full text
- (rValue) should be used (return <FALSE/>).
-
- @param nFormulaPrefix
- The result of a _GetKeyByAttrName( rValue, aFormula, sal_False)
- call.
-
- @param rValue
- The attribute's string (formula text) including the namespace, if
- any.
-
- @param rGrammar
- Return value set toformula::FormulaGrammar::GRAM_ODFF orformula::FormulaGrammar::GRAM_PODF or
- eStorageGrammar, according to the namespace or absence thereof
- encountered.
-
- @param eStorageGrammar
- Default storage grammar of the document,formula::FormulaGrammar::GRAM_ODFF for
- ODF 1.2 and later documents,formula::FormulaGrammar::GRAM_PODF for ODF 1.x
- documents.
-
- @return
- <TRUE/> if an accepted namespace (XML_NAMESPACE_OF or
- XML_NAMESPACE_OOOC), else <FALSE/>.
+ 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 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.
*/
-
- static bool IsAcceptedFormulaNamespace( const sal_uInt16 nFormulaPrefix,
- const rtl::OUString & rValue, formula::FormulaGrammar::Grammar& rGrammar,
- const formula::FormulaGrammar::Grammar eStorageGrammar );
-
+ void ExtractFormulaNamespaceGrammar(
+ ::rtl::OUString& rFormula,
+ ::rtl::OUString& rFormulaNmsp,
+ ::formula::FormulaGrammar::Grammar& reGrammar,
+ const ::rtl::OUString& rAttrValue,
+ bool bRestrictToExternalNmsp = false ) const;
};
#endif
diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx
index 3f822d5274c6..9a2a49f0b021 100644
--- a/sc/source/filter/xml/xmlnexpi.cxx
+++ b/sc/source/filter/xml/xmlnexpi.cxx
@@ -196,8 +196,6 @@ ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport,
SvXMLImportContext( rImport, nPrfx, rLName )
{
ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression);
- const formula::FormulaGrammar::Grammar eStorageGrammar = pNamedExpression->eGrammar =
- GetScImport().GetDocument()->GetStorageGrammar();
sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetNamedExpressionAttrTokenMap());
for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -217,16 +215,9 @@ ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport,
break;
case XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION :
{
- rtl::OUString sFormula;
- sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
- _GetKeyByAttrName( sValue, &sFormula, sal_False );
-
- if (ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
- sValue, pNamedExpression->eGrammar,
- eStorageGrammar))
- pNamedExpression->sContent = sFormula;
- else
- pNamedExpression->sContent = sValue;
+ GetScImport().ExtractFormulaNamespaceGrammar(
+ pNamedExpression->sContent, pNamedExpression->sContentNmsp,
+ pNamedExpression->eGrammar, sValue );
}
break;
case XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS :
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
index ac6cef7e54ec..79ba79f0e689 100644
--- a/sc/source/filter/xml/xmlstyli.cxx
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -73,6 +73,7 @@ using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace xmloff::token;
//using namespace ::com::sun::star::text;
+using namespace ::formula;
ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper(
const UniReference< XMLPropertySetMapper >& rMapper,
@@ -248,8 +249,14 @@ void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& r
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;
- pOptimalHeight->mnIndex = -1;
+ }
+ else
+ pOptimalHeight->mnIndex = -1;
}
}
else if (pHeight)
@@ -279,10 +286,7 @@ public:
ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
const OUString& rLName, const uno::Reference< xml::sax::XAttributeList > & xAttrList )
- : SvXMLImportContext( rImport, nPrfx, rLName ),
- sApplyStyle(),
- sCondition(),
- sBaseCell()
+ : SvXMLImportContext( rImport, nPrfx, rLName )
{
sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -309,200 +313,118 @@ ScXMLMapContext::~ScXMLMapContext()
{
}
-void XMLTableStyleContext::SetOperator(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
- const com::sun::star::sheet::ConditionOperator aOp) const
-{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OPERATOR));
- aProps[nLength].Value <<= aOp;
-}
+namespace {
-void XMLTableStyleContext::SetBaseCellAddress(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
- const rtl::OUString& sBaseCell) const
+template< typename Type >
+inline void lclAppendProperty( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rPropName, const Type& rValue )
{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
-
- // #b4974740# source position must be set as string, because it may
- // refer to a sheet that hasn't been loaded yet.
-
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR));
- aProps[nLength].Value <<= sBaseCell;
+ sal_Int32 nLength = rProps.getLength();
+ rProps.realloc( nLength + 1 );
+ rProps[ nLength ].Name = rPropName;
+ rProps[ nLength ].Value <<= rValue;
}
-void XMLTableStyleContext::SetStyle(com::sun::star::uno::Sequence<beans::PropertyValue>& aProps,
- const rtl::OUString& sApplyStyle) const
+} // namespace
+
+void XMLTableStyleContext::SetOperator( uno::Sequence< beans::PropertyValue >& rProps, sheet::ConditionOperator eOp ) const
{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STYLENAME));
- aProps[nLength].Value <<= sApplyStyle;
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_OPERATOR ) ), eOp );
}
-void XMLTableStyleContext::SetFormula1(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormula, bool bPreParse) const
+void XMLTableStyleContext::SetBaseCellAddress( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rBaseCell ) const
{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULA1));
- if (bPreParse)
- {
- rtl::OUString sRealFormula(sFormula);
- ScXMLConverter::ParseFormula(sRealFormula);
- aProps[nLength].Value <<= sRealFormula;
- }
- else
- aProps[nLength].Value <<= sFormula;
+ /* #b4974740# 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::SetFormula2(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormula) const
+void XMLTableStyleContext::SetStyle( uno::Sequence<beans::PropertyValue>& rProps, const OUString& rApplyStyle ) const
{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULA2));
- rtl::OUString sRealFormula(sFormula);
- ScXMLConverter::ParseFormula(sRealFormula);
- aProps[nLength].Value <<= sRealFormula;
+ lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_STYLENAME ) ), rApplyStyle );
}
-void XMLTableStyleContext::SetFormulas(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormulas) const
+void XMLTableStyleContext::SetFormula( uno::Sequence< beans::PropertyValue >& rProps,
+ sal_Int32 nFormulaIdx, const OUString& rFormula, const OUString& rFormulaNmsp,
+ FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const
{
- sal_Int32 i(0);
- sal_Bool bString(sal_False);
- sal_Int32 nBrakes(0);
- while ((sFormulas[i] != ',' || nBrakes > 0 || bString) && i < sFormulas.getLength())
+ OUString aFormula, aFormulaNmsp;
+ FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
+ if( bHasNmsp )
{
- if (sFormulas[i] == '(')
- ++nBrakes;
- if (sFormulas[i] == ')')
- --nBrakes;
- if (sFormulas[i] == '"')
- bString = !bString;
- ++i;
+ // the entire attribute contains a namespace: internal namespace not allowed
+ aFormula = rFormula;
+ aFormulaNmsp = rFormulaNmsp;
+ eNewGrammar = eGrammar;
}
- if (sFormulas[i] == ',')
+ else
{
- rtl::OUString sFormula1(sFormulas.copy(0, i));
- rtl::OUString sFormula2(sFormulas.copy(i + 1));
- SetFormula1(aProps, sFormula1);
- SetFormula2(aProps, sFormula2);
+ // 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;
}
-}
-void XMLTableStyleContext::SetGrammar(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const formula::FormulaGrammar::Grammar eGrammar) const
-{
- sal_Int32 nLength(aProps.getLength());
- aProps.realloc(nLength + 1);
- aProps[nLength].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR));
- aProps[nLength].Value <<= static_cast<sal_Int32>(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_ENSURE( false, "XMLTableStyleContext::SetFormula - invalid formula index" );
+ }
}
void XMLTableStyleContext::GetConditionalFormat(uno::Any& aAny,
const rtl::OUString& sTempCondition,
const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const
{
- rtl::OUString sCondition(sTempCondition);
- if (sCondition.getLength() && sApplyStyle.getLength())
+ if (sTempCondition.getLength() && sApplyStyle.getLength())
{
uno::Reference<sheet::XSheetConditionalEntries> xConditionalEntries(aAny, uno::UNO_QUERY);
if (xConditionalEntries.is())
{
- const formula::FormulaGrammar::Grammar eStorageGrammar = GetScImport().GetDocument()->GetStorageGrammar();
- formula::FormulaGrammar::Grammar eGrammar = eStorageGrammar;
- // ToDo: erase all blanks in the condition, but not in formulas or strings
- rtl::OUString scell_content(RTL_CONSTASCII_USTRINGPARAM("cell_content"));
- rtl::OUString scell_content_is_between(RTL_CONSTASCII_USTRINGPARAM("cell_content_is_between"));
- rtl::OUString scell_content_is_not_between(RTL_CONSTASCII_USTRINGPARAM("cell_content_is_not_between"));
- rtl::OUString sis_true_formula(RTL_CONSTASCII_USTRINGPARAM("is_true_formula"));
uno::Sequence<beans::PropertyValue> aProps;
if (sBaseCell.getLength())
SetBaseCellAddress(aProps, sBaseCell);
SetStyle(aProps, sApplyStyle);
- sal_Int32 i = 0;
- while (sCondition[i] != '(' && i < sCondition.getLength())
- ++i;
- if (sCondition[i] == '(')
+
+ // 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 )
{
- sCondition = sCondition.copy(i + 1);
- if (i == scell_content.getLength())
- {
- sCondition = sCondition.copy(1);
- switch (sCondition[0])
- {
- case '<' :
- {
- if (sCondition[1] == '=')
- {
- SetOperator(aProps, sheet::ConditionOperator_LESS_EQUAL);
- sCondition = sCondition.copy(2);
- }
- else
- {
- SetOperator(aProps, sheet::ConditionOperator_LESS);
- sCondition = sCondition.copy(1);
- }
- }
- break;
- case '>' :
- {
- if (sCondition[1] == '=')
- {
- SetOperator(aProps, sheet::ConditionOperator_GREATER_EQUAL);
- sCondition = sCondition.copy(2);
- }
- else
- {
- SetOperator(aProps, sheet::ConditionOperator_GREATER);
- sCondition = sCondition.copy(1);
- }
- }
- break;
- case '=' :
- {
- SetOperator(aProps, sheet::ConditionOperator_EQUAL);
- sCondition = sCondition.copy(1);
- }
- break;
- case '!' :
- {
- SetOperator(aProps, sheet::ConditionOperator_NOT_EQUAL);
- sCondition = sCondition.copy(1);
- }
- break;
- }
- SetFormula1(aProps, sCondition);
- }
- else if (i == scell_content_is_between.getLength())
- {
- SetOperator(aProps, sheet::ConditionOperator_BETWEEN);
- sCondition = sCondition.copy(0, sCondition.getLength() - 1);
- SetFormulas(aProps, sCondition);
- }
- else if (i == scell_content_is_not_between.getLength())
- {
- SetOperator(aProps, sheet::ConditionOperator_NOT_BETWEEN);
- sCondition = sCondition.copy(0, sCondition.getLength() - 1);
- SetFormulas(aProps, sCondition);
- }
- else if (i == sis_true_formula.getLength())
- {
- SetOperator(aProps, sheet::ConditionOperator_FORMULA);
- sCondition = sCondition.copy(0, sCondition.getLength() - 1);
- rtl::OUString sFormula;
- sal_uInt16 nFormulaPrefix = GetImport().GetNamespaceMap().
- _GetKeyByAttrName( sCondition, &sFormula, sal_False );
- if (ScXMLImport::IsAcceptedFormulaNamespace( nFormulaPrefix,
- sCondition, eGrammar, eStorageGrammar))
- sCondition = sFormula;
- SetFormula1(aProps, sCondition, false);
- }
+ 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
}
- SetGrammar( aProps, eGrammar);
- xConditionalEntries->addNew(aProps);
+
+ xConditionalEntries->addNew( aProps );
aAny <<= xConditionalEntries;
}
}
diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx
index 4d80f5710ac9..272ec0151134 100644
--- a/sc/source/filter/xml/xmlstyli.hxx
+++ b/sc/source/filter/xml/xmlstyli.hxx
@@ -107,20 +107,22 @@ class XMLTableStyleContext : public XMLPropStyleContext
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>& aProps,
- const com::sun::star::sheet::ConditionOperator aOp) const;
- void SetBaseCellAddress(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sBaseCell) const;
- void SetStyle(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sApplyStyle) const;
- void SetFormula1(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormula, bool bPreParse = true) const;
- void SetFormula2(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormula) const;
- void SetFormulas(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const rtl::OUString& sFormulas) const;
- void SetGrammar(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps,
- const formula::FormulaGrammar::Grammar eGrammar) const;
+ 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,
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 03437449ec61..231839b9f946 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -38,10 +38,13 @@
#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 "tabprotection.hxx"
+#include <svx/svdpage.hxx>
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
@@ -58,6 +61,10 @@
#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;
@@ -576,7 +583,35 @@ void ScMyTables::UpdateRowHeights()
{
rImport.LockSolarMutex();
// update automatic row heights
- ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights();
+
+ // 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, TRUE );
+ else
+ pDoc->SetPendingRowHeights( nTab, TRUE );
+ }
+
+ if (aUpdateSheets.GetSelectCount())
+ ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+ }
+
rImport.UnlockSolarMutex();
}
}
@@ -606,7 +641,7 @@ void ScMyTables::DeleteTable()
ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
while(aItr != aEndItr)
{
- SetMatrix(aItr->aRange, aItr->sFormula, aItr->eGrammar);
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
++aItr;
}
aMatrixRangeList.clear();
@@ -616,13 +651,10 @@ void ScMyTables::DeleteTable()
{
uno::Sequence<sal_Int8> aPass;
SvXMLUnitConverter::decodeBase64(aPass, sPassword);
- rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), bProtection, aPass);
- /*uno::Reference <util::XProtectable> xProtectable(xCurrentSheet, uno::UNO_QUERY);
- if (xProtectable.is())
- {
- rtl::OUString sKey;
- xProtectable->protect(sKey);
- }*/
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(bProtection);
+ pProtect->setPasswordHash(aPass, PASSHASH_OOO);
+ rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get());
}
rImport.UnlockSolarMutex();
@@ -723,7 +755,9 @@ void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape,
aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY);
}
-void ScMyTables::AddMatrixRange(sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow, const rtl::OUString& rFormula, const formula::FormulaGrammar::Grammar eGrammar)
+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");
@@ -733,7 +767,7 @@ void ScMyTables::AddMatrixRange(sal_Int32 nStartColumn, sal_Int32 nStartRow, sal
aRange.EndColumn = nEndColumn;
aRange.EndRow = nEndRow;
aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
- ScMatrixRange aMRange(aRange, rFormula, eGrammar);
+ ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
aMatrixRangeList.push_back(aMRange);
}
@@ -754,7 +788,7 @@ sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
}
else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
{
- SetMatrix(aItr->aRange, aItr->sFormula, aItr->eGrammar);
+ SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
aItr = aMatrixRangeList.erase(aItr);
}
else if (nColumn < aItr->aRange.StartColumn)
@@ -771,7 +805,8 @@ sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
return bResult;
}
-void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const formula::FormulaGrammar::Grammar eGrammar)
+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,
@@ -785,7 +820,7 @@ void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUS
static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
xMatrixCellRange));
if (pCellRangeObj)
- pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, eGrammar);
+ pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);
}
}
}
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
index 84a07ff90449..c5a16e2c3ef4 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -97,10 +97,12 @@ public:
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 formula::FormulaGrammar::Grammar eGrammarP) :
+ 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)
{
@@ -181,11 +183,13 @@ public:
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 );
};
diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx
index 616071be52d4..3ed9b4062a9d 100644
--- a/sc/source/ui/Accessibility/AccessibleDocument.cxx
+++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx
@@ -563,31 +563,6 @@ uno::Reference< XAccessible > ScChildrenShapes::GetAt(const awt::Point& rPoint)
--i;
}
-/* Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
- if (pWindow)
- {
- Point aPnt( rPoint.X, rPoint.Y );
- aPnt = pWindow->PixelToLogic( aPnt );
- SdrPage* pDrawPage = GetDrawPage();
- if (pDrawPage)
- {
- SdrObject * pObj = GetDrawPage()->CheckHit(aPnt, 1, NULL, false);
- if (pObj)
- {
- uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
- SortedShapes::iterator aItr;;
- if (FindShape(xShape, aItr))
- {
- if ((*aItr) && (*aItr)->pAccShape)
- xAccessible = (*aItr)->pAccShape;
- else
- xAccessible = Get(aItr - maZOrderedShapes.begin());
- }
- else
- DBG_ERRORFILE("a shape is not in the list");
- }
- }
- }*/
}
return xAccessible;
}
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 3e069b6c9e59..46987c88636f 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -113,14 +113,22 @@ extern USHORT nEditAdjust; //! Member an ViewData
//==================================================================
+static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc)
+{
+ ScCompiler aComp(pDoc, ScAddress());
+ aComp.SetGrammar(pDoc->GetGrammar());
+ return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
+}
+
void ScInputHandler::InitRangeFinder( const String& rFormula )
{
DeleteRangeFinder();
+ ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc);
if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() )
return;
- ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
- ScDocument* pDoc = pDocSh->GetDocument();
// String aDelimiters = pEngine->GetWordDelimiters();
String aDelimiters = ScEditUtil::ModifyDelimiters(
@@ -129,7 +137,7 @@ void ScInputHandler::InitRangeFinder( const String& rFormula )
xub_StrLen nColon = aDelimiters.Search(':');
if ( nColon != STRING_NOTFOUND )
aDelimiters.Erase( nColon, 1 ); // Delimiter ohne Doppelpunkt
- xub_StrLen nDot = aDelimiters.Search('.');
+ xub_StrLen nDot = aDelimiters.Search(cSheetSep);
if ( nDot != STRING_NOTFOUND )
aDelimiters.Erase( nDot, 1 ); // Delimiter ohne Punkt
@@ -702,6 +710,9 @@ void ScInputHandler::ShowTipCursor()
HideTip();
HideTipBelow();
EditView* pActiveView = pTopView ? pTopView : pTableView;
+ ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+ const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 )
{
@@ -730,7 +741,7 @@ void ScInputHandler::ShowTipCursor()
nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 );
if( nLeftParentPos != STRING_NOTFOUND )
{
- sal_Unicode c = aSelText.GetChar( nLeftParentPos-1 );
+ sal_Unicode c = ( nLeftParentPos > 0 ) ? aSelText.GetChar( nLeftParentPos-1 ) : 0;
if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z' )) )
continue;
nNextFStart = aHelper.GetFunctionStart( aSelText, nLeftParentPos, TRUE);
@@ -764,8 +775,8 @@ void ScInputHandler::ShowTipCursor()
}
if( bFlag )
{
- nCountSemicolon = aNew.GetTokenCount(';')-1;
- nCountDot = aNew.GetTokenCount('.')-1;
+ nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+ nCountDot = aNew.GetTokenCount(cSheetSep)-1;
if( !nCountSemicolon )
{
@@ -787,7 +798,7 @@ void ScInputHandler::ShowTipCursor()
{
nStartPosition = i+1;
}
- else if( cNext == ';' )
+ else if( cNext == cSep )
{
nCount ++;
nEndPosition = i;
@@ -808,7 +819,7 @@ void ScInputHandler::ShowTipCursor()
{
nStartPosition = i+1;
}
- else if( cNext == ';' )
+ else if( cNext == cSep )
{
nCount ++;
nEndPosition = i;
@@ -818,7 +829,7 @@ void ScInputHandler::ShowTipCursor()
}
nStartPosition = nEndPosition+1;
}
- else if( cNext == '.' )
+ else if( cNext == cSheetSep )
{
continue;
}
@@ -919,6 +930,9 @@ void ScInputHandler::ShowTipBelow( const String& rText )
void ScInputHandler::UseFormulaData()
{
EditView* pActiveView = pTopView ? pTopView : pTableView;
+ ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+ const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
// Formeln duerfen nur 1 Absatz haben
if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 )
@@ -969,7 +983,8 @@ void ScInputHandler::UseFormulaData()
if( nLeftParentPos == STRING_NOTFOUND )
break;
- sal_Unicode c = aFormula.GetChar( nLeftParentPos-1 );
+ // #160063# nLeftParentPos can be 0 if a parenthesis is inserted before the formula
+ sal_Unicode c = ( nLeftParentPos > 0 ) ? aFormula.GetChar( nLeftParentPos-1 ) : 0;
if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z') ) )
continue;
nNextFStart = aHelper.GetFunctionStart( aFormula, nLeftParentPos, TRUE);
@@ -1003,8 +1018,8 @@ void ScInputHandler::UseFormulaData()
}
if( bFlag )
{
- nCountSemicolon = aNew.GetTokenCount(';')-1;
- nCountDot = aNew.GetTokenCount('.')-1;
+ nCountSemicolon = aNew.GetTokenCount(cSep)-1;
+ nCountDot = aNew.GetTokenCount(cSheetSep)-1;
if( !nCountSemicolon )
{
@@ -1026,7 +1041,7 @@ void ScInputHandler::UseFormulaData()
{
nStartPosition = i+1;
}
- else if( cNext == ';' )
+ else if( cNext == cSep )
{
nCount ++;
nEndPosition = i;
@@ -1047,7 +1062,7 @@ void ScInputHandler::UseFormulaData()
{
nStartPosition = i+1;
}
- else if( cNext == ';' )
+ else if( cNext == cSep )
{
nCount ++;
nEndPosition = i;
@@ -1057,7 +1072,7 @@ void ScInputHandler::UseFormulaData()
}
nStartPosition = nEndPosition+1;
}
- else if( cNext == '.' )
+ else if( cNext == cSheetSep )
{
continue;
}
@@ -2740,6 +2755,7 @@ BOOL ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
void ScInputHandler::AddRefEntry()
{
+ const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
UpdateActiveView();
if (!pTableView && !pTopView)
return; // z.B. FillMode
@@ -2748,9 +2764,9 @@ void ScInputHandler::AddRefEntry()
RemoveSelection();
if (pTableView)
- pTableView->InsertText( ';', FALSE );
+ pTableView->InsertText( cSep, FALSE );
if (pTopView)
- pTopView->InsertText( ';', FALSE );
+ pTopView->InsertText( cSep, FALSE );
DataChanged();
}
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 8fd3c1f8ac0b..5a3fd605b08f 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1699,7 +1699,7 @@ void ScPosWnd::DoEnter()
ScRangeName aNewRanges( *pNames );
ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
String aContent;
- aSelection.Format( aContent, SCR_ABS_3D, pDoc );
+ aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
if ( aNewRanges.Insert(pNew) )
{
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 076cd3581d26..94a2cdfc3324 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -658,7 +658,7 @@ void ScTransferObj::InitDocShell()
// page format (grid etc) and page size (maximum size for ole object)
- Size aPaperSize = SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 ); // Twips
+ Size aPaperSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); // Twips
ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
String aStyleName = pDoc->GetPageStyle( aBlock.aStart.Tab() );
SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx
index 84d274580aa0..60b101d482c0 100644
--- a/sc/source/ui/attrdlg/scdlgfact.cxx
+++ b/sc/source/ui/attrdlg/scdlgfact.cxx
@@ -714,6 +714,24 @@ VclAbstractDialog * ScAbstractDialogFactory_Impl::CreateScColOrRowDlg(Window*
}
//add for ScColOrRowDlg end
+//add for ScSortWarningDlg begin
+VclAbstractDialog * ScAbstractDialogFactory_Impl::CreateScSortWarningDlg( Window* pParent, const String& rExtendText,
+ const String& rCurrentText, int nId )
+{
+ Dialog * pDlg=NULL;
+ switch ( nId )
+ {
+ case RID_SCDLG_SORT_WARNING:
+ pDlg = new ScSortWarningDlg( pParent, rExtendText, rCurrentText );
+ break;
+ default:
+ break;
+ }
+ if( pDlg )
+ return new VclAbstractDialog_Impl( pDlg );
+ return 0;
+}
+//add for ScSortWarningDlg end
//add for ScDataPilotDatabaseDlg begin
diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx
index 2bec64c31e13..40f6d3bee976 100644
--- a/sc/source/ui/attrdlg/scdlgfact.hxx
+++ b/sc/source/ui/attrdlg/scdlgfact.hxx
@@ -63,6 +63,7 @@ class ScShowTabDlg;
class ScStringInputDlg;
class ScImportOptionsDlg;
class SfxTabDialog;
+class ScSortWarningDlg;
#define DECL_ABSTDLG_BASE(Class,DialogClass) \
DialogClass* pDlg; \
@@ -398,6 +399,9 @@ public:
const String& rStrLabel,
int nId,
BOOL bColDefault = TRUE );
+
+ virtual VclAbstractDialog * CreateScSortWarningDlg( Window* pParent, const String& rExtendText, const String& rCurrentText, int nId );
+
virtual AbstractScDataPilotDatabaseDlg * CreateScDataPilotDatabaseDlg (Window* pParent ,int nId ); //add for ScDataPilotDatabaseDlg
virtual AbstractScDataPilotSourceTypeDlg * CreateScDataPilotSourceTypeDlg ( Window* pParent, BOOL bEnableExternal, int nId ) ; //add for ScDataPilotSourceTypeDlg
diff --git a/sc/source/ui/dbgui/sortdlg.cxx b/sc/source/ui/dbgui/sortdlg.cxx
index 00931de58924..7d1462f62f27 100644
--- a/sc/source/ui/dbgui/sortdlg.cxx
+++ b/sc/source/ui/dbgui/sortdlg.cxx
@@ -34,7 +34,7 @@
#undef SC_DLLIMPLEMENTATION
-
+#include <vcl/msgbox.hxx>
#include "tpsort.hxx"
#include "sortdlg.hxx"
#include "scresid.hxx"
@@ -69,3 +69,42 @@ __EXPORT ScSortDlg::~ScSortDlg()
{
}
+//==================================================================
+ScSortWarningDlg::ScSortWarningDlg( Window* pParent,
+ const String& rExtendText,
+ const String& rCurrentText ):
+ ModalDialog ( pParent, ScResId( RID_SCDLG_SORT_WARNING ) ),
+ aFtText ( this, ScResId( FT_TEXT ) ),
+ aFtTip ( this, ScResId( FT_TIP ) ),
+ aBtnExtSort ( this, ScResId( BTN_EXTSORT ) ),
+ aBtnCurSort ( this, ScResId( BTN_CURSORT ) ),
+ aBtnCancel ( this, ScResId( BTN_CANCEL ) )
+{
+ String sTextName = aFtText.GetText();
+ sTextName.SearchAndReplaceAscii("%1", rExtendText);
+ sTextName.SearchAndReplaceAscii("%2", rCurrentText);
+ aFtText.SetText( sTextName );
+
+ aBtnExtSort .SetClickHdl( LINK( this, ScSortWarningDlg, BtnHdl ) );
+ aBtnCurSort .SetClickHdl( LINK( this, ScSortWarningDlg, BtnHdl ) );
+
+ FreeResource();
+}
+
+ScSortWarningDlg::~ScSortWarningDlg()
+{
+}
+
+IMPL_LINK( ScSortWarningDlg, BtnHdl, PushButton*, pBtn )
+{
+ if ( pBtn == &aBtnExtSort )
+ {
+ EndDialog( BTN_EXTEND_RANGE );
+ }
+ else if( pBtn == &aBtnCurSort )
+ {
+ EndDialog( BTN_CURRENT_SELECTION );
+ }
+ return 0;
+}
+//========================================================================//
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 1e85f3c01f3e..33caccaed815 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -58,6 +58,7 @@
#include "editable.hxx"
#include "attrib.hxx"
#include "drwlayer.hxx"
+#include "dpshttab.hxx"
// -----------------------------------------------------------------
@@ -1299,6 +1300,22 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
BOOL bOverflow = FALSE;
ScRange aNewOut = pDestObj->GetNewOutputRange( bOverflow );
+
+ //! test for overlap with other data pilot tables
+ if( pOldObj )
+ {
+ const ScSheetSourceDesc* pSheetDesc = pOldObj->GetSheetDesc();
+ if( pSheetDesc && pSheetDesc->aSourceRange.Intersects( aNewOut ) )
+ {
+ ScRange aOldRange = pOldObj->GetOutRange();
+ SCsROW nDiff = aOldRange.aStart.Row()-aNewOut.aStart.Row();
+ aNewOut.aStart.SetRow( aOldRange.aStart.Row() );
+ aNewOut.aEnd.SetRow( aNewOut.aEnd.Row()+nDiff );
+ if( !ValidRow( aNewOut.aStart.Row() ) || !ValidRow( aNewOut.aEnd.Row() ) )
+ bOverflow = TRUE;
+ }
+ }
+
if ( bOverflow )
{
// like with STR_PROTECTIONERR, use undo to reverse everything
@@ -1354,9 +1371,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
pDoc->CopyToDocument( aNewOut, IDF_ALL, FALSE, pNewUndoDoc );
}
- //! test for overlap with other data pilot tables
-
- pDestObj->Output();
+ pDestObj->Output( aNewOut.aStart );
rDocShell.PostPaintGridAll(); //! only necessary parts
bDone = TRUE;
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 0383d6758767..ebb080a89cfa 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -93,7 +93,12 @@
#include "editable.hxx"
#include "compiler.hxx"
#include "scui_def.hxx" //CHINA001
+#include "tabprotection.hxx"
+
+#include <memory>
+
using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
// STATIC DATA -----------------------------------------------------------
@@ -955,16 +960,18 @@ BOOL ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
}
-ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText )
+ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
ScTokenArray* pCode = new ScTokenArray;
pCode->AddString( rText );
+ if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
+ pCode->AddString( rFormulaNmsp );
return pCode;
}
ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
- const String& rText, const formula::FormulaGrammar::Grammar eGrammar )
+ const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
ScDocument* pDoc = rDocShell.GetDocument();
ScBaseCell* pNewCell = NULL;
@@ -974,7 +981,7 @@ ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
ScTokenArray* pCode;
if ( pDoc->IsImportingXML() )
{ // temporary formula string as string tokens
- pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText );
+ pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText, rFormulaNmsp, eGrammar );
pDoc->IncXMLImportedFormulaCount( rText.Len() );
}
else
@@ -1011,8 +1018,8 @@ ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
- BOOL bInterpret, BOOL bEnglish, BOOL bApi,
- const formula::FormulaGrammar::Grammar eGrammar )
+ BOOL bInterpret, BOOL bEnglish, BOOL bApi,
+ const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
// SetCellText ruft PutCell oder SetNormalString
@@ -1025,12 +1032,15 @@ BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
// code moved to own method InterpretEnglishString because it is also used in
// ScCellRangeObj::setFormulaArray
- pNewCell = InterpretEnglishString( rPos, rText, eGrammar );
+ pNewCell = InterpretEnglishString( rPos, rText, rFormulaNmsp, eGrammar );
}
// sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
}
else if ( rText.Len() )
+ {
+ OSL_ENSURE( rFormulaNmsp.Len() == 0, "ScDocFunc::SetCellText - formula namespace, but do not interpret?" );
pNewCell = ScBaseCell::CreateTextCell( rText, pDoc ); // immer Text
+ }
if (pNewCell)
return PutCell( rPos, pNewCell, bApi );
@@ -1047,7 +1057,7 @@ bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
// move the caption to internal or hidden layer and create undo action
- pNote->ShowCaption( bShow );
+ pNote->ShowCaption( rPos, bShow );
if( rDoc.IsUndoEnabled() )
rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
@@ -1075,7 +1085,7 @@ bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, BOOL bA
aNewText.ConvertLineEnd(); //! ist das noetig ???
if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote( rPos ) )
- pNote->SetText( aNewText );
+ pNote->SetText( rPos, aNewText );
//! Undo !!!
@@ -1099,23 +1109,26 @@ bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, con
ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
SfxUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
- // collect drawing undo actions for deleting/inserting caption obejcts
- if( pUndoMgr )
- pDrawLayer->BeginCalcUndo();
-
- // delete old note
ScNoteData aOldData;
- if( ScPostIt* pOldNote = rDoc.ReleaseNote( rPos ) )
+ ScPostIt* pOldNote = rDoc.ReleaseNote( rPos );
+ if( pOldNote )
{
+ // ensure existing caption object before draw undo tracking starts
+ pOldNote->GetOrCreateCaption( rPos );
// rescue note data for undo
aOldData = pOldNote->GetNoteData();
- // delete the note (creates drawing undo action for the caption object)
- delete pOldNote;
}
+ // collect drawing undo actions for deleting/inserting caption obejcts
+ if( pUndoMgr )
+ pDrawLayer->BeginCalcUndo();
+
+ // delete the note (creates drawing undo action for the caption object)
+ delete pOldNote;
+
// create new note (creates drawing undo action for the new caption object)
ScNoteData aNewData;
- if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false ) )
+ if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
{
if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
if( pDate ) pNewNote->SetDate( *pDate );
@@ -1340,6 +1353,14 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
}
}
+ ScMarkData aFullMark( aMark ); // including scenario sheets
+ for( i=0; i<nTabCount; i++ )
+ if( aMark.GetTableSelect( i ) )
+ {
+ for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ aFullMark.SelectTable( j, TRUE );
+ }
+
SCTAB nSelCount = aMark.GetSelectCount();
// zugehoerige Szenarien auch anpassen
@@ -1430,8 +1451,8 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
- if(( eCmd == INS_CELLSDOWN && ( nMergeStartX != nMergeTestStartX || nMergeEndX != nMergeTestEndX ))||
- eCmd == INS_CELLSRIGHT && ( nMergeStartY != nMergeTestStartY || nMergeEndY != nMergeTestEndY ) )
+ if(( eCmd == INS_CELLSDOWN && ( nMergeStartX != nMergeTestStartX || nMergeEndX != nMergeTestEndX )) ||
+ (eCmd == INS_CELLSRIGHT && ( nMergeStartY != nMergeTestStartY || nMergeEndY != nMergeTestEndY )) )
{
if (!bApi)
rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
@@ -1543,66 +1564,22 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
switch (eCmd)
{
case INS_CELLSDOWN:
- bSuccess = TRUE;
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- bSuccess &= pDoc->InsertRow( nStartCol, i, nEndCol, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc );
- }
- }
+ bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
nPaintEndY = MAXROW;
break;
case INS_INSROWS:
- bSuccess = TRUE;
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- bSuccess &= pDoc->InsertRow( 0, i, MAXCOL, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc );
- }
- }
+ bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
nPaintStartX = 0;
nPaintEndX = MAXCOL;
nPaintEndY = MAXROW;
nPaintFlags |= PAINT_LEFT;
break;
case INS_CELLSRIGHT:
- bSuccess = TRUE;
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- bSuccess &= pDoc->InsertCol( nStartRow, i, nEndRow, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc );
- }
- }
+ bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
nPaintEndX = MAXCOL;
break;
case INS_INSCOLS:
- bSuccess = TRUE;
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- bSuccess &= pDoc->InsertCol( 0, i, MAXROW, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc );
- }
- }
+ bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
nPaintStartY = 0;
nPaintEndY = MAXROW;
nPaintEndX = MAXCOL;
@@ -1795,6 +1772,14 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
}
}
+ ScMarkData aFullMark( aMark ); // including scenario sheets
+ for( i=0; i<nTabCount; i++ )
+ if( aMark.GetTableSelect( i ) )
+ {
+ for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
+ aFullMark.SelectTable( j, TRUE );
+ }
+
SCTAB nSelCount = aMark.GetSelectCount();
SCCOL nUndoStartX = nStartCol;
@@ -2035,66 +2020,22 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
switch (eCmd)
{
case DEL_CELLSUP:
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
-
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- pDoc->DeleteRow( nStartCol, i, nEndCol, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc );
- }
- }
+ pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
nPaintEndY = MAXROW;
break;
case DEL_DELROWS:
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
-
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- pDoc->DeleteRow( 0, i, MAXCOL, i+nScenarioCount, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline );
- }
- }
+ pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
nPaintStartX = 0;
nPaintEndX = MAXCOL;
nPaintEndY = MAXROW;
nPaintFlags |= PAINT_LEFT;
break;
case DEL_CELLSLEFT:
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
-
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- pDoc->DeleteCol( nStartRow, i, nEndRow, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc );
- }
- }
+ pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
nPaintEndX = MAXCOL;
break;
case DEL_DELCOLS:
- for( i=0; i<nTabCount; i++ )
- {
- if( aMark.GetTableSelect( i ) )
- {
- SCTAB nScenarioCount = 0;
-
- for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
- nScenarioCount ++;
-
- pDoc->DeleteCol( 0, i, MAXROW, i+nScenarioCount, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline );
- }
- }
+ pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
nPaintStartY = 0;
nPaintEndY = MAXROW;
nPaintEndX = MAXCOL;
@@ -2109,8 +2050,9 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
if ( bRecord )
{
- for ( i=nStartTab; i<=nTabCount; i++)
- pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);
+ for( i=0; i<nTabCount; i++ )
+ if( aFullMark.GetTableSelect( i ) )
+ pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);
// alle Tabellen anlegen, damit Formeln kopiert werden koennen:
pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE );
@@ -2136,6 +2078,12 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
nUndoPos ++;
}
}
+
+ if( !bDeletingMerge )
+ {
+ rDocShell.GetUndoManager()->LeaveListAction();
+ }
+
rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
&rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
eCmd, pUndoDoc, pUndoData ) );
@@ -2492,9 +2440,13 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
/* Paste cell notes and drawing objects after adjusting formula references
and row heights. There are no cell notes or drawing objects, if the
- clipdoc does not contain a drawing layer. */
+ clipdoc does not contain a drawing layer.
+ #i102056# Passing IDF_NOTE only would overwrite cell contents with
+ empty note cells, therefore the special modifier IDF_ADDNOTES is passed
+ here too which changes the behaviour of ScColumn::CopyFromClip() to not
+ touch existing cells. */
if ( pClipDoc->GetDrawLayer() )
- pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_OBJECTS,
+ pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS,
pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered );
if (bRecord)
@@ -3193,103 +3145,156 @@ BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
//------------------------------------------------------------------------
-BOOL lcl_ValidPassword( ScDocument* pDoc, SCTAB nTab,
- const String& rPassword,
- uno::Sequence<sal_Int8>* pReturnOld = NULL )
+void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
{
- uno::Sequence<sal_Int8> aOldPassword;
- if ( nTab == TABLEID_DOC )
- {
- if (pDoc->IsDocProtected())
- aOldPassword = pDoc->GetDocPassword();
- }
- else
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ pDoc->SetTabProtection(nTab, &rProtect);
+ if (pDoc->IsUndoEnabled())
{
- if (pDoc->IsTabProtected(nTab))
- aOldPassword = pDoc->GetTabPassword(nTab);
- }
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, p) );
- if (pReturnOld)
- *pReturnOld = aOldPassword;
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
+ }
- return ((aOldPassword.getLength() == 0) || SvPasswordHelper::CompareHashPassword(aOldPassword, rPassword));
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator(rDocShell);
+ aModificator.SetDocumentModified();
}
-BOOL ScDocFunc::Protect( SCTAB nTab, const String& rPassword, BOOL bApi )
+BOOL ScDocFunc::Protect( SCTAB nTab, const String& rPassword, BOOL /*bApi*/ )
{
- ScDocShellModificator aModificator( rDocShell );
-
ScDocument* pDoc = rDocShell.GetDocument();
- BOOL bUndo(pDoc->IsUndoEnabled());
- BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword);
- if ( bOk )
- {
- uno::Sequence<sal_Int8> aPass;
- if (rPassword.Len())
- SvPasswordHelper::GetHashPassword(aPass, rPassword);
-
- if (bUndo)
+ if (nTab == TABLEID_DOC)
+ {
+ // document protection
+ ScDocProtection aProtection;
+ aProtection.setProtected(true);
+ aProtection.setPassword(rPassword);
+ pDoc->SetDocProtection(&aProtection);
+ if (pDoc->IsUndoEnabled())
{
- rDocShell.GetUndoManager()->AddUndoAction(
- new ScUndoProtect( &rDocShell, nTab, TRUE, aPass ) );
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDocProtect(&rDocShell, p) );
+ // ownership of auto_ptr is transferred to ScUndoDocProtect.
+ }
}
-
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( TRUE, aPass );
- else
- pDoc->SetTabProtection( nTab, TRUE, aPass );
-
- rDocShell.PostPaintGridAll();
- aModificator.SetDocumentModified();
}
- else if (!bApi)
+ else
{
- // different password was set before
+ // sheet protection
-//! rDocShell.ErrorMessage(...);
-
- InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
- aBox.Execute();
+ ScTableProtection aProtection;
+ aProtection.setProtected(true);
+ aProtection.setPassword(rPassword);
+ pDoc->SetTabProtection(nTab, &aProtection);
+ if (pDoc->IsUndoEnabled())
+ {
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, p) );
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
+ }
}
- return bOk;
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
}
BOOL ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi )
{
- ScDocShellModificator aModificator( rDocShell );
-
ScDocument* pDoc = rDocShell.GetDocument();
- BOOL bUndo(pDoc->IsUndoEnabled());
- uno::Sequence<sal_Int8> aOldPassword;
- uno::Sequence<sal_Int8> aPass;
- BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword, &aOldPassword );
- if ( bOk )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( FALSE, aEmptyPass );
- else
- pDoc->SetTabProtection( nTab, FALSE, aEmptyPass );
- if (bUndo)
+ if (nTab == TABLEID_DOC)
+ {
+ // document protection
+
+ ScDocProtection* pDocProtect = pDoc->GetDocProtection();
+ if (!pDocProtect || !pDocProtect->isProtected())
+ // already unprotected (should not happen)!
+ return true;
+
+ // save the protection state before unprotect (for undo).
+ ::std::auto_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));
+
+ if (!pDocProtect->verifyPassword(rPassword))
{
- rDocShell.GetUndoManager()->AddUndoAction(
- new ScUndoProtect( &rDocShell, nTab, FALSE, aOldPassword ) );
+ if (!bApi)
+ {
+ InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ return false;
}
- rDocShell.PostPaintGridAll();
- aModificator.SetDocumentModified();
+ pDoc->SetDocProtection(NULL);
+ if (pDoc->IsUndoEnabled())
+ {
+ pProtectCopy->setProtected(false);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDocProtect(&rDocShell, pProtectCopy) );
+ // ownership of auto_ptr now transferred to ScUndoDocProtect.
+ }
}
- else if (!bApi)
+ else
{
-//! rDocShell.ErrorMessage(...);
+ // sheet protection
+
+ ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
+ if (!pTabProtect || !pTabProtect->isProtected())
+ // already unprotected (should not happen)!
+ return true;
+
+ // save the protection state before unprotect (for undo).
+ ::std::auto_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
+ if (!pTabProtect->verifyPassword(rPassword))
+ {
+ if (!bApi)
+ {
+ InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ return false;
+ }
- InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
- aBox.Execute();
+ pDoc->SetTabProtection(nTab, NULL);
+ if (pDoc->IsUndoEnabled())
+ {
+ pProtectCopy->setProtected(false);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, pProtectCopy) );
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
}
- return bOk;
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
}
//------------------------------------------------------------------------
@@ -3516,9 +3521,8 @@ BOOL ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
//------------------------------------------------------------------------
BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
- const ScTokenArray* pTokenArray,
- const String& rString, BOOL bApi, BOOL bEnglish,
- const formula::FormulaGrammar::Grammar eGrammar )
+ const ScTokenArray* pTokenArray, const String& rString, BOOL bApi, BOOL bEnglish,
+ const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
ScDocShellModificator aModificator( rDocShell );
@@ -3565,7 +3569,7 @@ BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
}
else if ( pDoc->IsImportingXML() )
{
- ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString );
+ ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
aMark, EMPTY_STRING, pCode, eGrammar);
delete pCode;
@@ -4495,11 +4499,11 @@ BOOL ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd
if ( DeleteContents( aMark, IDF_CONTENTS, TRUE, bApi ) )
{
// GRAM_PODF_A1 for API compatibility.
- bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, FALSE,formula::FormulaGrammar::GRAM_PODF_A1 );
+ bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
if (!bRet)
{
// versuchen, alten Zustand wiederherzustellen
- EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, FALSE,formula::FormulaGrammar::GRAM_PODF_A1 );
+ EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
}
}
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index e360e93bae5d..c62c2dc41fdf 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -79,11 +79,6 @@
#include <sot/formats.hxx>
#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
-//REMOVE #ifndef SO2_DECL_SVSTORAGESTREAM_DEFINED
-//REMOVE #define SO2_DECL_SVSTORAGESTREAM_DEFINED
-//REMOVE SO2_DECL_REF(SotStorageStream)
-//REMOVE #endif
-
// INCLUDE ---------------------------------------------------------------
#include "cell.hxx"
@@ -97,7 +92,6 @@
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"
-//CHINA001 #include "tpstat.hxx"
#include "scerrors.hxx"
#include "brdcst.hxx"
#include "stlpool.hxx"
@@ -126,6 +120,7 @@
#include "cfgids.hxx"
#include "warnpassword.hxx"
#include "optsolver.hxx"
+#include "tabprotection.hxx"
#include "docsh.hxx"
#include "docshimp.hxx"
@@ -406,7 +401,7 @@ BOOL ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::R
bRet = aImport.Import(sal_True, nError);
if ( nError )
- pLoadMedium->SetError( nError );
+ pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
aDocument.SetXMLFromWrapper( FALSE );
AfterXMLLoading(bRet);
@@ -467,10 +462,10 @@ BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium )
}
if (!bRet && !rMedium.GetError())
- rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
if (rMedium.GetError())
- SetError( rMedium.GetError() );
+ SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
InitItems();
CalcOutputFactor();
@@ -751,7 +746,7 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
}
if ( !bSuccess )
- SetError( ERRCODE_IO_ABORT ); // this error code will produce no error message, but will break the further saving process
+ SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process
}
}
break;
@@ -853,7 +848,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
else
bRet = TRUE;
@@ -884,7 +879,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
bRet = TRUE;
@@ -923,13 +918,13 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError == SCWARN_IMPORT_RANGE_OVERFLOW)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
bRet = TRUE;
}
else if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
else
bRet = TRUE;
@@ -989,12 +984,12 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
else if ( bOverflow )
{
if (!GetError())
- SetError(SCWARN_IMPORT_RANGE_OVERFLOW);
+ SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
bSetColWidths = TRUE;
bSetSimpleTextColWidths = TRUE;
@@ -1024,7 +1019,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW );
}
else
@@ -1068,7 +1063,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
bRet = TRUE;
@@ -1103,7 +1098,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
}
if ( eError != eERR_OK && !GetError() )
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
bSetColWidths = TRUE;
bSetSimpleTextColWidths = TRUE;
bSetRowHeights = TRUE;
@@ -1116,7 +1111,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError( eError );
+ SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
bRet = TRUE;
}
@@ -1142,7 +1137,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
bRet = TRUE;
@@ -1161,7 +1156,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
}
if ( eError != eERR_OK && !GetError() )
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ))
{
@@ -1181,7 +1176,7 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
if (eError != eERR_OK)
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
bRet = TRUE;
@@ -1198,12 +1193,12 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
}
if ( eError != eERR_OK && !GetError() )
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
else
{
if (!GetError())
- SetError(SCERR_IMPORT_NI);
+ SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
if (!bCalc3)
@@ -1327,6 +1322,16 @@ BOOL __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
{
RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" );
+#if ENABLE_SHEET_PROTECTION
+ ScTabViewShell* pViewShell = GetBestViewShell();
+ if (pViewShell && ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_OOO))
+ {
+ if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_OOO))
+ // password re-type cancelled. Don't save the document.
+ return false;
+ }
+#endif
+
ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
PrepareSaveGuard aPrepareGuard( *this);
@@ -1792,7 +1797,6 @@ void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt
rStream.SetNumberFormatInt( nOldNumberFormatInt );
}
-
BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
{
RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
@@ -1846,15 +1850,39 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
- /* #115980 #If the imported document contained an encrypted password -
- determine if we should save without it. */
- ScExtDocSettings& rDocSett = pExtDocOpt->GetDocSettings();
- if( rDocSett.mbEncrypted )
+#if ENABLE_SHEET_PROTECTION
+ bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_XL);
+ if (bNeedRetypePassDlg && !pViewShell->ExecuteRetypePassDlg(PASSHASH_XL))
+ {
+ SetError( ERRCODE_ABORT );
+ return false;
+ }
+#else
+
+ do
{
+ SfxItemSet* pSet = rMed.GetItemSet();
+ if (!pSet)
+ break;
+
+ const SfxPoolItem* pItem = NULL;
+ if (SFX_ITEM_SET != pSet->GetItemState(SID_PASSWORD, sal_True, &pItem))
+ // password is not set.
+ break;
+
+ /* #115980 #If the imported document contained an encrypted password -
+ determine if we should save without it. */
bDoSave = ScWarnPassword::WarningOnPassword( rMed );
- // #i42858# warn only on time
- rDocSett.mbEncrypted = false;
+
+ if (bDoSave)
+ {
+ // #i42858# warn only one time
+ pSet->ClearItem(SID_PASSWORD);
+ }
}
+ while (false);
+
+#endif
}
if( bDoSave )
@@ -1867,7 +1895,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 );
if( eError && !GetError() )
- SetError( eError );
+ SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
// don't return false for warnings
bRet = ((eError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK) || (eError == eERR_OK);
@@ -1875,7 +1903,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
else
{
// export aborted, i.e. "Save without password" warning
- SetError( ERRCODE_ABORT );
+ SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
}
else if (aFltName.EqualsAscii(pFilterAscii))
@@ -1908,7 +1936,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
if (aDocument.GetTableCount() > 1)
if (!rMed.GetError())
- rMed.SetError(SCWARN_EXPORT_ASCII);
+ rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
}
else if (aFltName.EqualsAscii(pFilterDBase))
@@ -1941,11 +1969,11 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) )
{
//! if ( !rMed.GetError() )
-//! rMed.SetError( eError );
+//! rMed.SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
eError = eERR_OK;
}
//! else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() )
-//! rMed.SetError( SCWARN_EXPORT_ASCII );
+//! rMed.SetError( SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE );
if ( bHasMemo )
@@ -1953,7 +1981,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
if ( eError != eERR_OK )
{
if (!GetError())
- SetError(eError);
+ SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
if ( bHasMemo && IsDocument( aTmpFile ) )
KillFile( aTmpFile );
}
@@ -1974,7 +2002,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
{
KillFile( aTmpFile );
if ( !GetError() )
- SetError( SCERR_EXPORT_DATA );
+ SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
}
}
@@ -2008,7 +2036,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
if (aDocument.GetTableCount() > 1)
if (!rMed.GetError())
- rMed.SetError(SCWARN_EXPORT_ASCII);
+ rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
}
}
else if (aFltName.EqualsAscii(pFilterSylk))
@@ -2041,13 +2069,13 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
SetError( *new StringErrorInfo(
SCWARN_EXPORT_NONCONVERTIBLE_CHARS,
aImExport.GetNonConvertibleChars(),
- ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ) );
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
}
else
{
if (GetError())
- SetError(SCERR_IMPORT_NI);
+ SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
}
return bRet;
}
diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx
index fcdfa8612a02..fcbfb648ae14 100644
--- a/sc/source/ui/docshell/docsh3.cxx
+++ b/sc/source/ui/docshell/docsh3.cxx
@@ -1051,8 +1051,8 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheck
aValue.Erase( 0, 1 );
aValue.Erase( aValue.Len()-1, 1 );
GetDocFunc().EnterMatrix( aSourceRange,
- NULL, NULL, aValue, FALSE, FALSE,
- formula::FormulaGrammar::GRAM_DEFAULT );
+ NULL, NULL, aValue, FALSE, FALSE,
+ EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
}
break;
case MM_REFERENCE : // do nothing
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index f73389cb866f..d4df2863eec5 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1842,6 +1842,10 @@ void lcl_GetPrintData( ScDocShell* pDocShell /*in*/,
rOptions = SC_MOD()->GetPrintOptions();
}
+ // update all pending row heights with a single progress bar,
+ // instead of a separate progress for each sheet from ScPrintFunc
+ pDocShell->UpdatePendingRowHeights( MAXTAB, true );
+
// get number of total pages
rnTotalPages = 0;
SCTAB nTabCount = pDocument->GetTableCount();
@@ -2501,10 +2505,14 @@ long __EXPORT ScDocShell::DdeSetData( const String& rItem,
pData->GetSymbol( aPos ); // continue with the name's contents
}
}
+
+ // Address in DDE function must be always parsed as CONV_OOO so that it
+ // would always work regardless of current address convension. We do this
+ // because the address item in a DDE entry is *not* normalized when saved
+ // into ODF.
ScRange aRange;
- formula::FormulaGrammar::AddressConvention eConv = aDocument.GetAddressConvention();
- BOOL bValid = ( ( aRange.Parse( aPos, &aDocument, eConv ) & SCA_VALID ) ||
- ( aRange.aStart.Parse( aPos, &aDocument, eConv ) & SCA_VALID ) );
+ bool bValid = ( (aRange.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO ) & SCA_VALID) ||
+ (aRange.aStart.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO) & SCA_VALID) );
ScServerObject* pObj = NULL; // NULL = error
if ( bValid )
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index d3b6bb55dcdd..281f03ff3622 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -393,13 +393,51 @@ BOOL ScDocShell::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab )
return bChange;
}
-void ScDocShell::UpdateAllRowHeights()
+void ScDocShell::UpdateAllRowHeights( const ScMarkData* pTabMark )
{
// update automatic row heights
ScSizeDeviceProvider aProv(this);
Fraction aZoom(1,1);
- aDocument.UpdateAllRowHeights( aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), aZoom, aZoom );
+ aDocument.UpdateAllRowHeights( aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), aZoom, aZoom, pTabMark );
+}
+
+void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore )
+{
+ BOOL bIsUndoEnabled = aDocument.IsUndoEnabled();
+ aDocument.EnableUndo( FALSE );
+ if ( bBefore ) // check all sheets up to nUpdateTab
+ {
+ SCTAB nTabCount = aDocument.GetTableCount();
+ if ( nUpdateTab >= nTabCount )
+ nUpdateTab = nTabCount-1; // nUpdateTab is inclusive
+
+ ScMarkData aUpdateSheets;
+ SCTAB nTab;
+ for (nTab=0; nTab<=nUpdateTab; ++nTab)
+ if ( aDocument.IsPendingRowHeights( nTab ) )
+ aUpdateSheets.SelectTable( nTab, TRUE );
+
+ if (aUpdateSheets.GetSelectCount())
+ UpdateAllRowHeights(&aUpdateSheets); // update with a single progress bar
+
+ for (nTab=0; nTab<=nUpdateTab; ++nTab)
+ if ( aUpdateSheets.GetTableSelect( nTab ) )
+ {
+ aDocument.UpdatePageBreaks( nTab );
+ aDocument.SetPendingRowHeights( nTab, FALSE );
+ }
+ }
+ else // only nUpdateTab
+ {
+ if ( aDocument.IsPendingRowHeights( nUpdateTab ) )
+ {
+ AdjustRowHeight( 0, MAXROW, nUpdateTab );
+ aDocument.UpdatePageBreaks( nUpdateTab );
+ aDocument.SetPendingRowHeights( nUpdateTab, FALSE );
+ }
+ }
+ aDocument.EnableUndo( bIsUndoEnabled );
}
#if OLD_PIVOT_IMPLEMENTATION
@@ -827,7 +865,7 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec
++nAdjSource; // new position of source table after CopyTab
if ( aDocument.IsTabProtected( nAdjSource ) )
- aDocument.SetTabProtection( nDestTab, TRUE, aDocument.GetTabPassword( nAdjSource ) );
+ aDocument.CopyTabProtection(nAdjSource, nDestTab);
if (bRecord)
{
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 637093275bad..9cc0b274028e 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -143,7 +143,8 @@ private:
// ============================================================================
ScExternalRefCache::Table::Table()
- : mbReferenced( true) // Prevent accidental data loss due to lack of knowledge.
+ : meReferenced( REFERENCED_MARKED )
+ // Prevent accidental data loss due to lack of knowledge.
{
}
@@ -151,14 +152,25 @@ ScExternalRefCache::Table::~Table()
{
}
+void ScExternalRefCache::Table::setReferencedFlag( ScExternalRefCache::Table::ReferencedFlag eFlag )
+{
+ meReferenced = eFlag;
+}
+
void ScExternalRefCache::Table::setReferenced( bool bReferenced )
{
- mbReferenced = bReferenced;
+ if (meReferenced != REFERENCED_PERMANENT)
+ meReferenced = (bReferenced ? REFERENCED_MARKED : UNREFERENCED);
+}
+
+ScExternalRefCache::Table::ReferencedFlag ScExternalRefCache::Table::getReferencedFlag() const
+{
+ return meReferenced;
}
bool ScExternalRefCache::Table::isReferenced() const
{
- return mbReferenced;
+ return meReferenced != UNREFERENCED;
}
void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex)
@@ -737,21 +749,57 @@ bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId )
return areAllCacheTablesReferenced();
}
-bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName )
+bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets, bool bPermanent )
{
- size_t nIndex = 0;
- TableTypeRef pTab = getCacheTable( nFileId, rTabName, false, &nIndex);
- if (pTab.get())
+ DocItem* pDoc = getDocItem(nFileId);
+ if (pDoc)
{
- if (!pTab->isReferenced())
+ size_t nIndex = 0;
+ String aTabNameUpper = ScGlobal::pCharClass->upper( rTabName);
+ if (lcl_getTableDataIndex( pDoc->maTableNameIndex, aTabNameUpper, nIndex))
{
- pTab->setReferenced( true);
- addCacheTableToReferenced( nFileId, nIndex);
+ size_t nStop = ::std::min( nIndex + nSheets, pDoc->maTables.size());
+ for (size_t i = nIndex; i < nStop; ++i)
+ {
+ TableTypeRef pTab = pDoc->maTables[i];
+ if (pTab.get())
+ {
+ Table::ReferencedFlag eNewFlag = (bPermanent ?
+ Table::REFERENCED_PERMANENT :
+ Table::REFERENCED_MARKED);
+ Table::ReferencedFlag eOldFlag = pTab->getReferencedFlag();
+ if (eOldFlag != Table::REFERENCED_PERMANENT && eNewFlag != eOldFlag)
+ {
+ pTab->setReferencedFlag( eNewFlag);
+ addCacheTableToReferenced( nFileId, i);
+ }
+ }
+ }
}
}
return areAllCacheTablesReferenced();
}
+void ScExternalRefCache::setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets )
+{
+ DocItem* pDoc = getDocItem(nFileId);
+ if (pDoc)
+ {
+ size_t nIndex = 0;
+ String aTabNameUpper = ScGlobal::pCharClass->upper( rTabName);
+ if (lcl_getTableDataIndex( pDoc->maTableNameIndex, aTabNameUpper, nIndex))
+ {
+ size_t nStop = ::std::min( nIndex + nSheets, pDoc->maTables.size());
+ for (size_t i = nIndex; i < nStop; ++i)
+ {
+ TableTypeRef pTab = pDoc->maTables[i];
+ if (pTab.get())
+ pTab->setReferencedFlag( Table::REFERENCED_PERMANENT);
+ }
+ }
+ }
+}
+
void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced )
{
if (bReferenced)
@@ -791,9 +839,17 @@ void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced )
TableTypeRef & xTab = rDocItem.maTables[i];
if (xTab.get())
{
- xTab->setReferenced( false);
- rDocReferenced.maTables[i] = false;
- rDocReferenced.mbAllTablesReferenced = false;
+ if (xTab->getReferencedFlag() == Table::REFERENCED_PERMANENT)
+ addCacheTableToReferenced( nFileId, i);
+ else
+ {
+ xTab->setReferencedFlag( Table::UNREFERENCED);
+ rDocReferenced.maTables[i] = false;
+ rDocReferenced.mbAllTablesReferenced = false;
+ // An addCacheTableToReferenced() actually may have
+ // resulted in mbAllReferenced been set. Clear it.
+ maReferenced.mbAllReferenced = false;
+ }
}
}
}
@@ -1317,8 +1373,9 @@ void ScExternalRefManager::RefCells::moveTable(SCTAB nOldTab, SCTAB nNewTab, boo
xNewTab->mnIndex = nNewTab;
maTables.insert(itrNew, xNewTab);
list<TabItemRef>::iterator itr = itrNew, itrEnd = maTables.end();
- for (++itr; itr != itrEnd; ++itr)
- (*itr)->mnIndex += 1;
+ if (itr != itrEnd) // #i99807# check that itr is not at end already
+ for (++itr; itr != itrEnd; ++itr)
+ (*itr)->mnIndex += 1;
}
else
{
@@ -1480,9 +1537,19 @@ bool ScExternalRefManager::setCacheDocReferenced( sal_uInt16 nFileId )
return maRefCache.setCacheDocReferenced( nFileId);
}
-bool ScExternalRefManager::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName )
+bool ScExternalRefManager::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets )
{
- return maRefCache.setCacheTableReferenced( nFileId, rTabName);
+ return maRefCache.setCacheTableReferenced( nFileId, rTabName, nSheets, false);
+}
+
+void ScExternalRefManager::setCacheTableReferencedPermanently( sal_uInt16 nFileId, const String& rTabName, size_t nSheets )
+{
+ if (isInReferenceMarking())
+ // Do all maintenance work.
+ maRefCache.setCacheTableReferenced( nFileId, rTabName, nSheets, true);
+ else
+ // Set only the permanent flag.
+ maRefCache.setCacheTableReferencedPermanently( nFileId, rTabName, nSheets);
}
void ScExternalRefManager::setAllCacheTableReferencedStati( bool bReferenced )
diff --git a/sc/source/ui/drawfunc/drawsh.cxx b/sc/source/ui/drawfunc/drawsh.cxx
index 8b86e0d886ef..63f958763479 100644
--- a/sc/source/ui/drawfunc/drawsh.cxx
+++ b/sc/source/ui/drawfunc/drawsh.cxx
@@ -230,7 +230,7 @@ void ScDrawShell::ExecDrawAttr( SfxRequest& rReq )
{
SdrPageView* pPV = 0;
SdrObject* pHit = 0;
- if ( pView->PickObj( pWin->PixelToLogic( pViewData->GetMousePosPixel() ), pHit, pPV, SDRSEARCH_DEEP ) )
+ if ( pView->PickObj( pWin->PixelToLogic( pViewData->GetMousePosPixel() ), pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
pObj = pHit;
}
diff --git a/sc/source/ui/drawfunc/fudraw.cxx b/sc/source/ui/drawfunc/fudraw.cxx
index 2dccd6edbfe0..fadb8270b6a6 100644
--- a/sc/source/ui/drawfunc/fudraw.cxx
+++ b/sc/source/ui/drawfunc/fudraw.cxx
@@ -795,12 +795,12 @@ void FuDraw::ForcePointer(const MouseEvent* pMEvt)
SdrPageView* pPV;
ScMacroInfo* pInfo = 0;
- if ( pView->PickObj(aPnt, pObj, pPV, SDRSEARCH_ALSOONMASTER) )
+ if ( pView->PickObj(aPnt, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
{
if ( pObj->IsGroupObject() )
{
SdrObject* pHit = 0;
- if ( pView->PickObj(aMDPos, pHit, pPV, SDRSEARCH_DEEP ) )
+ if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
pObj = pHit;
}
pInfo = ScDrawLayer::GetMacroInfo( pObj );
@@ -825,7 +825,7 @@ void FuDraw::ForcePointer(const MouseEvent* pMEvt)
// kann mit ALT unterdrueckt werden
pWindow->SetPointer( Pointer( POINTER_REFHAND ) ); // Text-URL / ImageMap
}
- else if ( !bAlt && pView->PickObj(aPnt, pObj, pPV, SDRSEARCH_PICKMACRO) )
+ else if ( !bAlt && pView->PickObj(aPnt, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
{
// kann mit ALT unterdrueckt werden
SdrObjMacroHitRec aHitRec; //! muss da noch irgendwas gesetzt werden ????
diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx
index 5dff4041bd22..93abbd48c9e7 100644
--- a/sc/source/ui/drawfunc/fuins2.cxx
+++ b/sc/source/ui/drawfunc/fuins2.cxx
@@ -167,8 +167,10 @@ void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScVie
if ( aRangeListRef->Count() )
{
pScDoc->LimitChartIfAll( aRangeListRef ); // limit whole columns/rows to used area
+
+ // update string from modified ranges. The ranges must be in the current formula syntax.
String aTmpStr;
- aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() ); // update string from changed ranges
+ aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() );
aRangeString = aTmpStr;
ScChartPositioner aChartPositioner( pScDoc, aRangeListRef );
diff --git a/sc/source/ui/drawfunc/fupoor.cxx b/sc/source/ui/drawfunc/fupoor.cxx
index c26d3fdcb5fc..23aefe17c71b 100644
--- a/sc/source/ui/drawfunc/fupoor.cxx
+++ b/sc/source/ui/drawfunc/fupoor.cxx
@@ -42,6 +42,7 @@
#include "detfunc.hxx"
#include "document.hxx"
#include <vcl/svapp.hxx>
+#include <svx/sdrhittesthelper.hxx>
/*************************************************************************
|*
@@ -333,8 +334,10 @@ BOOL FuPoor::IsDetectiveHit( const Point& rLogicPos )
{
USHORT nHitLog = (USHORT) pWindow->PixelToLogic(
Size(pView->GetHitTolerancePixel(),0)).Width();
- if ( pObject->IsHit( rLogicPos, nHitLog ) )
+ if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, 0, false))
+ {
bFound = TRUE;
+ }
}
pObject = aIter.Next();
diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx
index 02fc2e38b0f6..79c466f9f2c3 100644
--- a/sc/source/ui/drawfunc/fusel.cxx
+++ b/sc/source/ui/drawfunc/fusel.cxx
@@ -171,7 +171,7 @@ BOOL __EXPORT FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
else
{
BOOL bAlt = rMEvt.IsMod2();
- if ( !bAlt && pView->PickObj(aMDPos, pObj, pPV, SDRSEARCH_PICKMACRO) )
+ if ( !bAlt && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
{
pView->BegMacroObj(aMDPos, pObj, pPV, pWindow);
bReturn = TRUE;
@@ -179,7 +179,7 @@ BOOL __EXPORT FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
else
{
String sURL, sTarget;
- if ( !bAlt && pView->PickObj(aMDPos, pObj, pPV, SDRSEARCH_ALSOONMASTER))
+ if ( !bAlt && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER))
{
// Support for imported Excel docs
// Excel is of course not consistent and allows
@@ -200,7 +200,7 @@ BOOL __EXPORT FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
if ( pObj->IsGroupObject() )
{
SdrObject* pHit = NULL;
- if ( pView->PickObj(aMDPos, pHit, pPV, SDRSEARCH_DEEP ) )
+ if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
pObj = pHit;
}
diff --git a/sc/source/ui/drawfunc/fusel2.cxx b/sc/source/ui/drawfunc/fusel2.cxx
index aa518ee42a81..7c096fd51d71 100644
--- a/sc/source/ui/drawfunc/fusel2.cxx
+++ b/sc/source/ui/drawfunc/fusel2.cxx
@@ -53,6 +53,7 @@
#include "drwlayer.hxx"
#include "docsh.hxx"
#include "drawview.hxx"
+#include <svx/sdrhittesthelper.hxx>
// -----------------------------------------------------------------------
@@ -79,7 +80,7 @@ BOOL FuSelection::TestDetective( SdrPageView* pPV, const Point& rPos )
{
USHORT nHitLog = (USHORT) pWindow->PixelToLogic(
Size(pView->GetHitTolerancePixel(),0)).Width();
- if ( pObject->IsHit( rPos, nHitLog ) )
+ if (SdrObjectPrimitiveHit(*pObject, rPos, nHitLog, *pPV, 0, false))
{
ScViewData* pViewData = pViewShell->GetViewData();
ScSplitPos ePos = pViewShell->FindWindow( pWindow );
diff --git a/sc/source/ui/drawfunc/futext.cxx b/sc/source/ui/drawfunc/futext.cxx
index 302d1c825a2a..ebcb2ad30802 100644
--- a/sc/source/ui/drawfunc/futext.cxx
+++ b/sc/source/ui/drawfunc/futext.cxx
@@ -193,7 +193,7 @@ BOOL __EXPORT FuText::MouseButtonDown(const MouseEvent& rMEvt)
{
if (pHdl == NULL &&
// pView->TakeTextEditObject(aMDPos, pObj, pPV) )
- pView->PickObj(aMDPos, pObj, pPV, SDRSEARCH_PICKTEXTEDIT) )
+ pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKTEXTEDIT) )
{
SdrOutliner* pO = MakeOutliner();
lcl_UpdateHyphenator( *pO, pObj );
@@ -250,7 +250,7 @@ BOOL __EXPORT FuText::MouseButtonDown(const MouseEvent& rMEvt)
BOOL bMacro = FALSE;
// if (bMacro && pView->TakeMacroObject(aMDPos,pObj,pPV))
- if (bMacro && pView->PickObj(aMDPos, pObj, pPV, SDRSEARCH_PICKMACRO) )
+ if (bMacro && pView->PickObj(aMDPos, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
{
pView->BegMacroObj(aMDPos,pObj,pPV,pWindow);
diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx
index 3fc99568e173..701a53aecfcc 100644
--- a/sc/source/ui/drawfunc/futext3.cxx
+++ b/sc/source/ui/drawfunc/futext3.cxx
@@ -130,7 +130,7 @@ void FuText::StopEditMode(BOOL /*bTextDirection*/)
if( pNote )
{
// hide the caption object if it is in hidden state
- pNote->HideCaptionTemp();
+ pNote->ShowCaptionTemp( aNotePos, false );
// update author and date
pNote->AutoStamp();
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index 4544c1ca0792..8d631a9f0609 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -126,7 +126,6 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
m_xParser.set(ScServiceProvider::MakeInstance(SC_SERVICE_FORMULAPARS,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
uno::Reference< beans::XPropertySet> xSet(m_xParser,uno::UNO_QUERY);
xSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COMPILEFAP)),uno::makeAny(sal_True));
- xSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REFERENCEPOS)),uno::makeAny(table::CellAddress(aCursorPos.Tab(),aCursorPos.Col(),aCursorPos.Row())));
m_xOpCodeMapper.set(ScServiceProvider::MakeInstance(SC_SERVICE_OPCODEMAPPER,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
@@ -657,6 +656,12 @@ uno::Reference< sheet::XFormulaOpCodeMapper> ScFormulaDlg::getFormulaOpCodeMappe
{
return m_xOpCodeMapper;
}
+
+table::CellAddress ScFormulaDlg::getReferencePosition() const
+{
+ return table::CellAddress(aCursorPos.Tab(),aCursorPos.Col(),aCursorPos.Row());
+}
+
::std::auto_ptr<formula::FormulaTokenArray> ScFormulaDlg::convertToTokenArray(const uno::Sequence< sheet::FormulaToken >& _aTokenList)
{
::std::auto_ptr<formula::FormulaTokenArray> pArray(new ScTokenArray());
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index ecdaceb55294..21e295a58fa4 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -33,7 +33,6 @@
#include <tools/link.hxx>
#include "global.hxx"
-#include "postit.hxx"
#include "formula/grammar.hxx"
class ScEditEngineDefaulter;
@@ -47,7 +46,7 @@ class ScRangeName;
class ScBaseCell;
class ScTokenArray;
struct ScTabOpParam;
-
+class ScTableProtection;
// ---------------------------------------------------------------------------
@@ -90,11 +89,12 @@ public:
BOOL bInterpret, BOOL bApi );
BOOL SetCellText( const ScAddress& rPos, const String& rText,
BOOL bInterpret, BOOL bEnglish, BOOL bApi,
+ const String& rFormulaNmsp,
const formula::FormulaGrammar::Grammar eGrammar );
// creates a new cell for use with PutCell
ScBaseCell* InterpretEnglishString( const ScAddress& rPos, const String& rText,
- const formula::FormulaGrammar::Grammar eGrammar );
+ const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar );
bool ShowNote( const ScAddress& rPos, bool bShow = true );
inline bool HideNote( const ScAddress& rPos ) { return ShowNote( rPos, false ); }
@@ -135,6 +135,8 @@ public:
BOOL RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
BOOL bRecord, BOOL bSetModified, BOOL bApi );
+ void ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect );
+
BOOL Protect( SCTAB nTab, const String& rPassword, BOOL bApi );
BOOL Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi );
@@ -146,6 +148,7 @@ public:
BOOL EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
const ScTokenArray* pTokenArray,
const String& rString, BOOL bApi, BOOL bEnglish,
+ const String& rFormulaNmsp,
const formula::FormulaGrammar::Grammar );
BOOL TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index df102a54f355..b8b8d10f0c6e 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -290,7 +290,8 @@ public:
BOOL IsEditable() const;
BOOL AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab );
- void UpdateAllRowHeights();
+ void UpdateAllRowHeights( const ScMarkData* pTabMark = NULL );
+ void UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore = false );
#if OLD_PIVOT_IMPLEMENTATION
void PivotUpdate( ScPivot* pOldPivot, ScPivot* pNewPivot,
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index a40a6092fe26..b25811eb9220 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -105,6 +105,7 @@ public:
virtual ::std::auto_ptr<formula::FormulaTokenArray> convertToTokenArray(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& _aTokenList);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser> getFormulaParser() const;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaOpCodeMapper> getFormulaOpCodeMapper() const;
+ virtual ::com::sun::star::table::CellAddress getReferencePosition() const;
virtual BOOL Close();
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 9b31289d13d0..844d88055578 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -116,18 +116,19 @@ namespace sdr
public:
typedef ::std::vector< basegfx::B2DRange > RangeVector;
+ protected:
+ basegfx::B2DPolyPolygon impGetOverlayPolyPolygon() const;
+
private:
ScOverlayType mePaintType;
RangeVector maRectangles;
- virtual void drawGeometry(OutputDevice& rOutputDevice);
- virtual void createBaseRange(OutputDevice& rOutputDevice);
+ // geometry creation for OverlayObject
+ virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence();
public:
OverlayObjectCell( ScOverlayType eType, const Color& rColor, const RangeVector& rRects);
virtual ~OverlayObjectCell();
-
- virtual void transform(const basegfx::B2DHomMatrix& rMatrix);
};
} // end of namespace overlay
diff --git a/sc/source/ui/inc/printfun.hxx b/sc/source/ui/inc/printfun.hxx
index 6a8e43fb2e7c..fd607975ff47 100644
--- a/sc/source/ui/inc/printfun.hxx
+++ b/sc/source/ui/inc/printfun.hxx
@@ -92,7 +92,7 @@ public:
Size aUserSize;
MapMode aUserMapMode;
- Paper ePaper;
+ Paper ePaper;
Orientation eOrientation;
USHORT nPaperBin;
};
diff --git a/sc/source/ui/inc/protectiondlg.hrc b/sc/source/ui/inc/protectiondlg.hrc
new file mode 100644
index 000000000000..79285d3ce125
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hrc
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.hrc,v $
+ * $Revision: 1.1.2.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sc.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define BTN_PROTECT 4
+#define FT_PASSWORD1 5
+#define ED_PASSWORD1 6
+#define FT_PASSWORD2 7
+#define ED_PASSWORD2 8
+#define FL_OPTIONS 9
+#define FT_OPTIONS 10
+#define CLB_OPTIONS 11
+
+#define ST_SELECT_LOCKED_CELLS 50
+#define ST_SELECT_UNLOCKED_CELLS 51
diff --git a/sc/source/ui/inc/protectiondlg.hxx b/sc/source/ui/inc/protectiondlg.hxx
new file mode 100644
index 000000000000..36330498c941
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.hxx,v $
+ * $Revision: 1.1.2.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UI_PROTECTION_DLG_HXX
+#define SC_UI_PROTECTION_DLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <svx/checklbx.hxx>
+
+class Window;
+class ScTableProtection;
+
+class ScTableProtectionDlg : public ModalDialog
+{
+public:
+ explicit ScTableProtectionDlg(Window* pParent);
+ virtual ~ScTableProtectionDlg();
+
+ virtual short Execute();
+
+ void SetDialogData(const ScTableProtection& rData);
+
+ void WriteData(ScTableProtection& rData) const;
+
+private:
+ ScTableProtectionDlg(); // disabled
+
+ void Init();
+
+ void EnableOptionalWidgets(bool bEnable = true);
+
+ CheckBox maBtnProtect;
+
+ FixedText maPassword1Text;
+ Edit maPassword1Edit;
+ FixedText maPassword2Text;
+ Edit maPassword2Edit;
+
+ FixedLine maOptionsLine;
+ FixedText maOptionsText;
+ SvxCheckListBox maOptionsListBox;
+
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ String maSelectLockedCells;
+ String maSelectUnlockedCells;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+ DECL_LINK( PasswordModifyHdl, Edit* );
+};
+
+#endif
diff --git a/sc/source/ui/inc/retypepassdlg.hrc b/sc/source/ui/inc/retypepassdlg.hrc
new file mode 100644
index 000000000000..fe0f7e8a760a
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hrc
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.hrc,v $
+ * $Revision: 1.1.2.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sc.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FT_DESC 10
+#define FL_DOCUMENT 11
+#define FT_DOCSTATUS 12
+#define BTN_RETYPE_DOC 13
+
+#define FL_SHEET 112
+
+#define FT_SHEETNAME1 113
+#define FT_SHEETSTATUS1 114
+#define BTN_RETYPE_SHEET1 115
+
+#define FT_SHEETNAME2 116
+#define FT_SHEETSTATUS2 117
+#define BTN_RETYPE_SHEET2 118
+
+#define FT_SHEETNAME3 119
+#define FT_SHEETSTATUS3 120
+#define BTN_RETYPE_SHEET3 121
+
+#define FT_SHEETNAME4 122
+#define FT_SHEETSTATUS4 123
+#define BTN_RETYPE_SHEET4 124
+
+#define SB_SCROLL 190
+
+#define STR_NOT_PROTECTED 200
+#define STR_NOT_PASS_PROTECTED 201
+#define STR_HASH_BAD 202
+#define STR_HASH_GOOD 203
+#define STR_HASH_REGENERATED 204
+
+#define FT_PASSWORD1 301
+#define ED_PASSWORD1 302
+#define FT_PASSWORD2 303
+#define ED_PASSWORD2 304
+#define BTN_MATCH_OLD_PASSWORD 305
+#define BTN_RETYPE_PASSWORD 306
+#define BTN_REMOVE_PASSWORD 307
diff --git a/sc/source/ui/inc/retypepassdlg.hxx b/sc/source/ui/inc/retypepassdlg.hxx
new file mode 100644
index 000000000000..657773d112f7
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.hxx,v $
+ * $Revision: 1.1.2.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public 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_UI_RETYPEPASS_DLG_HXX
+#define SC_UI_RETYPEPASS_DLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/scrbar.hxx>
+#include <svx/checklbx.hxx>
+#include <svtools/stdctrl.hxx>
+
+#include "tabprotection.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+class Window;
+class ScDocProtection;
+class ScTableProtection;
+class ScDocument;
+
+class ScRetypePassDlg : public ModalDialog
+{
+public:
+ typedef ::boost::shared_ptr<ScDocProtection> DocProtectionPtr;
+ typedef ::boost::shared_ptr<ScTableProtection> TabProtectionPtr;
+
+ explicit ScRetypePassDlg(Window* pParent);
+ virtual ~ScRetypePassDlg();
+
+ virtual short Execute();
+
+ void SetDataFromDocument(const ScDocument& rDoc);
+ void SetDesiredHash(ScPasswordHash eHash);
+
+ /** Write the new set of password data to the document instance to
+ overwrite the current ones. */
+ void WriteNewDataToDocument(ScDocument& rDoc) const;
+
+private:
+ ScRetypePassDlg(); // disabled
+
+ void Init();
+ void PopulateDialog();
+ void SetDocData();
+ void SetTableData(size_t nRowPos, SCTAB nTab);
+ void ResetTableRows();
+
+ /** Check the status of all hash values to see if it's okay to enable
+ the OK button. */
+ void CheckHashStatus();
+
+private:
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ FixedInfo maTextDescription;
+
+ FixedLine maLineDocument;
+ FixedText maTextDocStatus;
+ PushButton maBtnRetypeDoc;
+
+ FixedLine maLineSheet;
+ FixedText maTextSheetName1;
+ FixedText maTextSheetStatus1;
+ PushButton maBtnRetypeSheet1;
+
+ FixedText maTextSheetName2;
+ FixedText maTextSheetStatus2;
+ PushButton maBtnRetypeSheet2;
+
+ FixedText maTextSheetName3;
+ FixedText maTextSheetStatus3;
+ PushButton maBtnRetypeSheet3;
+
+ FixedText maTextSheetName4;
+ FixedText maTextSheetStatus4;
+ PushButton maBtnRetypeSheet4;
+
+ ScrollBar maScrollBar;
+
+ String maTextNotProtected;
+ String maTextNotPassProtected;
+ String maTextHashBad;
+ String maTextHashGood;
+ String maTextHashRegen;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( RetypeBtnHdl, PushButton* );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+ struct TableItem
+ {
+ String maName;
+ TabProtectionPtr mpProtect;
+ };
+ ::std::vector<TableItem> maTableItems;
+
+ DocProtectionPtr mpDocItem;
+ size_t mnCurScrollPos;
+ ScPasswordHash meDesiredHash;
+};
+
+// ============================================================================
+
+class ScRetypePassInputDlg : public ModalDialog
+{
+public:
+ explicit ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected);
+ virtual ~ScRetypePassInputDlg();
+
+ virtual short Execute();
+
+ bool IsRemovePassword() const;
+ String GetNewPassword() const;
+
+private:
+ ScRetypePassInputDlg(); // disabled
+
+ void Init();
+ void CheckPasswordInput();
+
+private:
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ RadioButton maBtnRetypePassword;
+
+ FixedText maPassword1Text;
+ Edit maPassword1Edit;
+ FixedText maPassword2Text;
+ Edit maPassword2Edit;
+
+ CheckBox maBtnMatchOldPass;
+
+ RadioButton maBtnRemovePassword;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( RadioBtnHdl, RadioButton* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+ DECL_LINK( PasswordModifyHdl, Edit* );
+
+ ScPassHashProtectable* mpProtected;
+};
+
+#endif
diff --git a/sc/source/ui/inc/scui_def.hxx b/sc/source/ui/inc/scui_def.hxx
index 231c983db69a..e2a11bb3204c 100644
--- a/sc/source/ui/inc/scui_def.hxx
+++ b/sc/source/ui/inc/scui_def.hxx
@@ -53,6 +53,8 @@
#define BTN_PASTE_NAME 100 // from namepast.hxx
#define BTN_PASTE_LIST 101 // from namepast.hxx
+#define BTN_EXTEND_RANGE 150
+#define BTN_CURRENT_SELECTION 151
#define SCRET_REMOVE 0x42 //from subtdlg.hxx
#endif
diff --git a/sc/source/ui/inc/sortdlg.hrc b/sc/source/ui/inc/sortdlg.hrc
index 902606429596..8f2f641e7574 100644
--- a/sc/source/ui/inc/sortdlg.hrc
+++ b/sc/source/ui/inc/sortdlg.hrc
@@ -32,6 +32,7 @@
#include "sc.hrc" // -> RID_SCDLG_SORT
// -> RID_SCPAGE_SORT_FIELDS
// -> RID_SCPAGE_SORT_OPTIONS
+ // -> RID_SCDLG_SORT_WARNING
// -> SCSTR_NONAME
// -> SCSTR_UNDEFINED
// -> SCSTR_FIELD
@@ -40,6 +41,7 @@
#define RID_SCDLG_SORT 256
#define RID_SCPAGE_SORT_FIELDS 257
#define RID_SCPAGE_SORT_OPTIONS 258
+#define RID_SCDLG_SORT_WARNING
*/
#define TP_FIELDS 1
@@ -80,6 +82,12 @@
#define FT_ALGORITHM 18
#define LB_ALGORITHM 19
+//#define RID_SCDLG_SORT_WARNING
+#define FT_TEXT 1
+#define FT_TIP 2
+#define BTN_EXTSORT 3
+#define BTN_CURSORT 4
+#define BTN_CANCEL 5
diff --git a/sc/source/ui/inc/sortdlg.hxx b/sc/source/ui/inc/sortdlg.hxx
index 3dcb3a08191d..d1ffb8aac0ed 100644
--- a/sc/source/ui/inc/sortdlg.hxx
+++ b/sc/source/ui/inc/sortdlg.hxx
@@ -32,6 +32,10 @@
#define SC_SORTDLG_HXX
#include <sfx2/tabdlg.hxx>
+#include <vcl/button.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include "scui_def.hxx" //CHINA001
#ifndef LAYOUT_SFX_TABDIALOG_BROKEN
#define LAYOUT_SFX_TABDIALOG_BROKEN 1
@@ -65,6 +69,20 @@ inline void ScSortDlg::SetByRows ( BOOL bByRows ) { bIsByRows = bByRows; }
inline BOOL ScSortDlg::GetHeaders() const { return bIsHeaders; }
inline BOOL ScSortDlg::GetByRows () const { return bIsByRows; }
+class ScSortWarningDlg : public ModalDialog
+{
+public:
+ ScSortWarningDlg( Window* pParent, const String& rExtendText,const String& rCurrentText );
+ ~ScSortWarningDlg();
+ DECL_LINK( BtnHdl, PushButton* );
+private:
+ FixedText aFtText;
+ FixedText aFtTip;
+ PushButton aBtnExtSort;
+ PushButton aBtnCurSort;
+ CancelButton aBtnCancel;
+};
+
#if !LAYOUT_SFX_TABDIALOG_BROKEN
#include <layout/layout-post.hxx>
#endif
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 13cd49df6879..10224536bf0b 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -39,6 +39,7 @@
#include "target.hxx"
#include "rangelst.hxx" // ScRangeListRef
#include "shellids.hxx"
+#include "tabprotection.hxx" // for ScPasswordHash
class FmFormShell;
class SbxObject;
@@ -430,6 +431,8 @@ public:
void BroadcastAccessibility( const SfxHint &rHint );
BOOL HasAccessibilityObjects();
+ bool ExecuteRetypePassDlg(ScPasswordHash eDesiredHash);
+
using ScTabView::ShowCursor;
};
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index d357461d0f5e..281f44f4fe82 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -36,6 +36,7 @@
#include "spellparam.hxx"
class ScDocShell;
+class ScBaseCell;
class ScDocument;
class ScOutlineTable;
class ScRangeName;
@@ -592,6 +593,35 @@ private:
void SetChangeTrack();
};
+class ScUndoRefConversion: public ScSimpleUndo
+{
+public:
+ TYPEINFO();
+ ScUndoRefConversion( ScDocShell* pNewDocShell,
+ const ScRange& aMarkRange, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, BOOL bNewMulti, USHORT nNewFlag);
+ virtual ~ScUndoRefConversion();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ ScMarkData aMarkData;
+ ScDocument* pUndoDoc;
+ ScDocument* pRedoDoc;
+ ScRange aRange;
+ BOOL bMulti;
+ USHORT nFlags;
+ ULONG nStartChangeAction;
+ ULONG nEndChangeAction;
+
+ void DoChange( ScDocument* pRefDoc);
+ void SetChangeTrack();
+};
class ScUndoListNames: public ScBlockUndo
{
diff --git a/sc/source/ui/inc/undotab.hxx b/sc/source/ui/inc/undotab.hxx
index ff76ebd16702..1eadf24041db 100644
--- a/sc/source/ui/inc/undotab.hxx
+++ b/sc/source/ui/inc/undotab.hxx
@@ -52,11 +52,15 @@
#include <com/sun/star/uno/Sequence.hxx>
+#include <memory>
+
class ScDocShell;
class ScDocument;
class SdrUndoAction;
class ScPrintRangeSaver;
class SdrObject;
+class ScDocProtection;
+class ScTableProtection;
//----------------------------------------------------------------------------
@@ -335,14 +339,15 @@ private:
void DoChange( BOOL bShow ) const;
};
+// ============================================================================
-class ScUndoProtect : public ScSimpleUndo
+/** This class implements undo & redo of document protect & unprotect
+ operations. */
+class ScUndoDocProtect : public ScSimpleUndo
{
public:
- TYPEINFO();
- ScUndoProtect( ScDocShell* pShell, SCTAB nNewTab,
- BOOL bNewProtect, const com::sun::star::uno::Sequence<sal_Int8>& rNewPassword );
- virtual ~ScUndoProtect();
+ ScUndoDocProtect(ScDocShell* pShell, ::std::auto_ptr<ScDocProtection> pProtectSettings);
+ virtual ~ScUndoDocProtect();
virtual void Undo();
virtual void Redo();
@@ -352,11 +357,34 @@ public:
virtual String GetComment() const;
private:
- SCTAB nTab;
- BOOL bProtect;
- com::sun::star::uno::Sequence<sal_Int8> aPassword;
+ ::std::auto_ptr<ScDocProtection> mpProtectSettings;
+
+ void DoProtect(bool bProtect);
+};
+
+// ============================================================================
+
+/** This class implements undo & redo of both protect and unprotect of
+ sheet. */
+class ScUndoTabProtect : public ScSimpleUndo
+{
+public:
+ ScUndoTabProtect(ScDocShell* pShell, SCTAB nTab,
+ ::std::auto_ptr<ScTableProtection> pProtectSettings);
+ virtual ~ScUndoTabProtect();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB mnTab;
+ ::std::auto_ptr<ScTableProtection> mpProtectSettings;
- void DoProtect( BOOL bDo );
+ void DoProtect(bool bProtect);
};
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index 0759d1fe2893..228c4b4c1489 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -69,6 +69,7 @@ class Exchange;
class ScRangeList;
class SvxHyperlinkItem;
class ScTransferObj;
+class ScTableProtection;
namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } }
@@ -199,6 +200,8 @@ public:
void ChangeIndent( BOOL bIncrement );
+ void ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect );
+
void Protect( SCTAB nTab, const String& rPassword );
BOOL Unprotect( SCTAB nTab, const String& rPassword );
@@ -300,6 +303,7 @@ public:
void SetNoteText( const ScAddress& rPos, const String& rNoteText );
void ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate );
+ void DoRefConversion( BOOL bRecord = TRUE );
//UNUSED2008-05 void DoSpellingChecker( BOOL bRecord = TRUE );
void DoHangulHanjaConversion( BOOL bRecord = TRUE );
diff --git a/sc/source/ui/miscdlgs/makefile.mk b/sc/source/ui/miscdlgs/makefile.mk
index 988b288da625..66e1f33618e2 100644
--- a/sc/source/ui/miscdlgs/makefile.mk
+++ b/sc/source/ui/miscdlgs/makefile.mk
@@ -78,7 +78,9 @@ SLOFILES = \
$(SLO)$/warnbox.obj \
$(SLO)$/scuiautofmt.obj \
$(SLO)$/conflictsdlg.obj \
- $(SLO)$/sharedocdlg.obj
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
EXCEPTIONSFILES = \
$(SLO)$/acredlin.obj \
@@ -87,7 +89,9 @@ EXCEPTIONSFILES = \
$(SLO)$/optsolver.obj \
$(SLO)$/solveroptions.obj \
$(SLO)$/crnrdlg.obj \
- $(SLO)$/solverutil.obj
+ $(SLO)$/solverutil.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
SRS1NAME=$(TARGET)
SRC1FILES = \
@@ -96,7 +100,9 @@ SRC1FILES = \
highred.src \
linkarea.src \
conflictsdlg.src \
- sharedocdlg.src
+ sharedocdlg.src \
+ protectiondlg.src \
+ retypepassdlg.src
LIB1TARGET = $(SLB)$/$(TARGET).lib
@@ -116,7 +122,9 @@ LIB1OBJFILES = \
$(SLO)$/redcom.obj \
$(SLO)$/warnbox.obj \
$(SLO)$/conflictsdlg.obj \
- $(SLO)$/sharedocdlg.obj
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
# --- Tagets -------------------------------------------------------
diff --git a/sc/source/ui/miscdlgs/protectiondlg.cxx b/sc/source/ui/miscdlgs/protectiondlg.cxx
new file mode 100644
index 000000000000..a5116ef61d66
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.cxx,v $
+ * $Revision: 1.1.2.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "protectiondlg.hxx"
+#include "protectiondlg.hrc"
+#include "scresid.hxx"
+#include "tabprotection.hxx"
+
+#include <vcl/msgbox.hxx>
+
+
+// The order must match that of the list box.
+static const ScTableProtection::Option aOptions[] = {
+ ScTableProtection::SELECT_LOCKED_CELLS,
+ ScTableProtection::SELECT_UNLOCKED_CELLS,
+};
+static const USHORT nOptionCount = sizeof(aOptions)/sizeof(aOptions[0]);
+
+
+ScTableProtectionDlg::ScTableProtectionDlg(Window* pParent) :
+ ModalDialog(pParent, ScResId(RID_SCDLG_TABPROTECTION)),
+
+ maBtnProtect (this, ScResId(BTN_PROTECT)),
+ maPassword1Text (this, ScResId(FT_PASSWORD1)),
+ maPassword1Edit (this, ScResId(ED_PASSWORD1)),
+ maPassword2Text (this, ScResId(FT_PASSWORD2)),
+ maPassword2Edit (this, ScResId(ED_PASSWORD2)),
+ maOptionsLine (this, ScResId(FL_OPTIONS)),
+ maOptionsText (this, ScResId(FT_OPTIONS)),
+ maOptionsListBox(this, ScResId(CLB_OPTIONS)),
+
+ maBtnOk (this, ScResId(BTN_OK)),
+ maBtnCancel (this, ScResId(BTN_CANCEL)),
+ maBtnHelp (this, ScResId(BTN_HELP)),
+
+ maSelectLockedCells(ScResId(ST_SELECT_LOCKED_CELLS)),
+ maSelectUnlockedCells(ScResId(ST_SELECT_UNLOCKED_CELLS))
+{
+ Init();
+ FreeResource();
+}
+
+ScTableProtectionDlg::~ScTableProtectionDlg()
+{
+}
+
+short ScTableProtectionDlg::Execute()
+{
+ return ModalDialog::Execute();
+}
+
+void ScTableProtectionDlg::SetDialogData(const ScTableProtection& rData)
+{
+ for (USHORT i = 0; i < nOptionCount; ++i)
+ maOptionsListBox.CheckEntryPos(i, rData.isOptionEnabled(aOptions[i]));
+}
+
+void ScTableProtectionDlg::WriteData(ScTableProtection& rData) const
+{
+ rData.setProtected(maBtnProtect.IsChecked());
+
+ // We assume that the two password texts match.
+ rData.setPassword(maPassword1Edit.GetText());
+
+ for (USHORT i = 0; i < nOptionCount; ++i)
+ rData.setOption(aOptions[i], maOptionsListBox.IsChecked(i));
+}
+
+void ScTableProtectionDlg::Init()
+{
+ Link aLink = LINK( this, ScTableProtectionDlg, CheckBoxHdl );
+ maBtnProtect.SetClickHdl(aLink);
+
+ aLink = LINK( this, ScTableProtectionDlg, OKHdl );
+ maBtnOk.SetClickHdl(aLink);
+
+ aLink = LINK( this, ScTableProtectionDlg, PasswordModifyHdl );
+ maPassword1Edit.SetModifyHdl(aLink);
+ maPassword2Edit.SetModifyHdl(aLink);
+
+ maOptionsListBox.SetUpdateMode(false);
+ maOptionsListBox.Clear();
+
+ maOptionsListBox.InsertEntry(maSelectLockedCells);
+ maOptionsListBox.InsertEntry(maSelectUnlockedCells);
+
+ maOptionsListBox.CheckEntryPos(0, true);
+ maOptionsListBox.CheckEntryPos(1, true);
+
+ maOptionsListBox.SetUpdateMode(true);
+
+ // Set the default state of the dialog.
+ maBtnProtect.Check(true);
+ maPassword1Edit.GrabFocus();
+}
+
+void ScTableProtectionDlg::EnableOptionalWidgets(bool bEnable)
+{
+ maPassword1Text.Enable(bEnable);
+ maPassword1Edit.Enable(bEnable);
+ maPassword2Text.Enable(bEnable);
+ maPassword2Edit.Enable(bEnable);
+ maOptionsLine.Enable(bEnable);
+ maOptionsText.Enable(bEnable);
+
+ maOptionsListBox.Enable(bEnable);
+ maOptionsListBox.Invalidate();
+}
+
+IMPL_LINK( ScTableProtectionDlg, CheckBoxHdl, CheckBox*, pBtn )
+{
+ if (pBtn == &maBtnProtect)
+ {
+ bool bChecked = maBtnProtect.IsChecked();
+ EnableOptionalWidgets(bChecked);
+ maBtnOk.Enable(bChecked);
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScTableProtectionDlg, OKHdl, OKButton*, EMPTYARG )
+{
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK( ScTableProtectionDlg, PasswordModifyHdl, Edit*, EMPTYARG )
+{
+ String aPass1 = maPassword1Edit.GetText();
+ String aPass2 = maPassword2Edit.GetText();
+ maBtnOk.Enable(aPass1.Equals(aPass2));
+ return 0;
+}
diff --git a/sc/source/ui/miscdlgs/protectiondlg.src b/sc/source/ui/miscdlgs/protectiondlg.src
new file mode 100644
index 000000000000..4919f93ca6f4
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.src
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.src,v $
+ * $Revision: 1.1.2.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "protectiondlg.hrc"
+
+ModalDialog RID_SCDLG_TABPROTECTION
+{
+ Text [ en-US ] = "Protect Sheet" ;
+ Size = MAP_APPFONT ( 220 , 135 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+
+ CheckBox BTN_PROTECT
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 150 , 10 );
+
+ Text [ en-US ] = "P~rotect this sheet and the contents of locked cells" ;
+ };
+
+ FixedText FT_PASSWORD1
+ {
+ Pos = MAP_APPFONT ( 11, 23 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Password" ;
+ };
+
+ Edit ED_PASSWORD1
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 56, 22 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedText FT_PASSWORD2
+ {
+ Pos = MAP_APPFONT ( 11, 40 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Confirm" ;
+ };
+
+ Edit ED_PASSWORD2
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 56, 39 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedLine FL_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6, 60 );
+ Size = MAP_APPFONT ( 150, 8 );
+
+ Text [ en-US ] = "Options";
+ };
+
+ FixedText FT_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 11, 74 );
+ Size = MAP_APPFONT ( 140, 8 );
+
+ Text [ en-US ] = "Allow all users of this sheet to:";
+ };
+
+ Control CLB_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 11, 85 );
+ Size = MAP_APPFONT ( 140, 40 );
+ Border = TRUE ;
+ TabStop = TRUE ;
+ };
+
+ String ST_SELECT_LOCKED_CELLS
+ {
+ Text [ en-US ] = "Select locked cells";
+ };
+
+ String ST_SELECT_UNLOCKED_CELLS
+ {
+ Text [ en-US ] = "Select unlocked cells";
+ };
+};
diff --git a/sc/source/ui/miscdlgs/retypepassdlg.cxx b/sc/source/ui/miscdlgs/retypepassdlg.cxx
new file mode 100644
index 000000000000..84a008f68f5f
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.cxx,v $
+ * $Revision: 1.1.2.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "retypepassdlg.hxx"
+#include "retypepassdlg.hrc"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "tabprotection.hxx"
+
+#include <stdio.h>
+
+#include <vcl/msgbox.hxx>
+
+ScRetypePassDlg::ScRetypePassDlg(Window* pParent) :
+ ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS)),
+
+ maBtnOk (this, ScResId(BTN_OK)),
+ maBtnCancel (this, ScResId(BTN_CANCEL)),
+ maBtnHelp (this, ScResId(BTN_HELP)),
+
+ maTextDescription(this, ScResId(FT_DESC)),
+ maLineDocument(this, ScResId(FL_DOCUMENT)),
+ maTextDocStatus(this, ScResId(FT_DOCSTATUS)),
+ maBtnRetypeDoc(this, ScResId(BTN_RETYPE_DOC)),
+
+ maLineSheet(this, ScResId(FL_SHEET)),
+ maTextSheetName1(this, ScResId(FT_SHEETNAME1)),
+ maTextSheetStatus1(this, ScResId(FT_SHEETSTATUS1)),
+ maBtnRetypeSheet1(this, ScResId(BTN_RETYPE_SHEET1)),
+
+ maTextSheetName2(this, ScResId(FT_SHEETNAME2)),
+ maTextSheetStatus2(this, ScResId(FT_SHEETSTATUS2)),
+ maBtnRetypeSheet2(this, ScResId(BTN_RETYPE_SHEET2)),
+
+ maTextSheetName3(this, ScResId(FT_SHEETNAME3)),
+ maTextSheetStatus3(this, ScResId(FT_SHEETSTATUS3)),
+ maBtnRetypeSheet3(this, ScResId(BTN_RETYPE_SHEET3)),
+
+ maTextSheetName4(this, ScResId(FT_SHEETNAME4)),
+ maTextSheetStatus4(this, ScResId(FT_SHEETSTATUS4)),
+ maBtnRetypeSheet4(this, ScResId(BTN_RETYPE_SHEET4)),
+
+ maScrollBar (this, ScResId(SB_SCROLL)),
+
+ maTextNotProtected(ScResId(STR_NOT_PROTECTED)),
+ maTextNotPassProtected(ScResId(STR_NOT_PASS_PROTECTED)),
+ maTextHashBad(ScResId(STR_HASH_BAD)),
+ maTextHashGood(ScResId(STR_HASH_GOOD)),
+ maTextHashRegen(ScResId(STR_HASH_REGENERATED)),
+
+ mpDocItem(static_cast<ScDocProtection*>(NULL)),
+ mnCurScrollPos(0),
+ meDesiredHash(PASSHASH_OOO)
+{
+ Init();
+}
+
+ScRetypePassDlg::~ScRetypePassDlg()
+{
+}
+
+short ScRetypePassDlg::Execute()
+{
+ PopulateDialog();
+ CheckHashStatus();
+ return ModalDialog::Execute();
+}
+
+void ScRetypePassDlg::SetDataFromDocument(const ScDocument& rDoc)
+{
+ const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
+ if (pDocProtect && pDocProtect->isProtected())
+ mpDocItem.reset(new ScDocProtection(*pDocProtect));
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ maTableItems.reserve(nTabCount);
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ TableItem aTabItem;
+ rDoc.GetName(i, aTabItem.maName);
+
+ const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
+ if (pTabProtect && pTabProtect->isProtected())
+ aTabItem.mpProtect.reset(new ScTableProtection(*pTabProtect));
+
+ maTableItems.push_back(aTabItem);
+ }
+}
+
+void ScRetypePassDlg::SetDesiredHash(ScPasswordHash eHash)
+{
+ meDesiredHash = eHash;
+}
+
+void ScRetypePassDlg::WriteNewDataToDocument(ScDocument& rDoc) const
+{
+ if (mpDocItem.get())
+ rDoc.SetDocProtection(mpDocItem.get());
+
+ size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
+ size_t n = maTableItems.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ if (i >= nTabCount)
+ break;
+
+ ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
+ if (pTabProtect)
+ rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
+ }
+}
+
+void ScRetypePassDlg::Init()
+{
+ Link aLink = LINK( this, ScRetypePassDlg, OKHdl );
+ maBtnOk.SetClickHdl(aLink);
+
+ aLink = LINK( this, ScRetypePassDlg, RetypeBtnHdl );
+ maBtnRetypeDoc.SetClickHdl(aLink);
+ maBtnRetypeSheet1.SetClickHdl(aLink);
+ maBtnRetypeSheet2.SetClickHdl(aLink);
+ maBtnRetypeSheet3.SetClickHdl(aLink);
+ maBtnRetypeSheet4.SetClickHdl(aLink);
+
+ maTextDocStatus.SetText(maTextNotProtected);
+ maTextSheetStatus1.SetText(maTextNotProtected);
+ maTextSheetStatus2.SetText(maTextNotProtected);
+ maTextSheetStatus3.SetText(maTextNotProtected);
+ maTextSheetStatus4.SetText(maTextNotProtected);
+ maBtnRetypeDoc.Disable();
+
+ // Make all sheet rows invisible.
+
+ maTextSheetName1.Show(false);
+ maTextSheetStatus1.Show(false);
+ maBtnRetypeSheet1.Show(false);
+ maBtnRetypeSheet1.Disable();
+
+ maTextSheetName2.Show(false);
+ maTextSheetStatus2.Show(false);
+ maBtnRetypeSheet2.Show(false);
+ maBtnRetypeSheet2.Disable();
+
+ maTextSheetName3.Show(false);
+ maTextSheetStatus3.Show(false);
+ maBtnRetypeSheet3.Show(false);
+ maBtnRetypeSheet3.Disable();
+
+ maTextSheetName4.Show(false);
+ maTextSheetStatus4.Show(false);
+ maBtnRetypeSheet4.Show(false);
+ maBtnRetypeSheet4.Disable();
+
+ maScrollBar.Show(false);
+
+ maScrollBar.SetEndScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
+ maScrollBar.SetScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
+
+ maScrollBar.SetPageSize(4);
+ maScrollBar.SetVisibleSize(4);
+ maScrollBar.SetLineSize(1);
+}
+
+void ScRetypePassDlg::PopulateDialog()
+{
+ // Document protection first.
+ SetDocData();
+
+ // Sheet protection next. We're only interested in the first 4 sheets
+ // (or less).
+ size_t n = maTableItems.size();
+ for (size_t i = 0; i < n && i < 4; ++i)
+ SetTableData(i, static_cast< SCTAB >( i ));
+
+ if (n > 4)
+ {
+ maScrollBar.Show(true);
+ maScrollBar.SetRange(Range(0, n));
+ }
+}
+
+void ScRetypePassDlg::SetDocData()
+{
+ bool bBtnEnabled = false;
+ if (mpDocItem.get() && mpDocItem->isProtected())
+ {
+ if (mpDocItem->isPasswordEmpty())
+ maTextDocStatus.SetText(maTextNotPassProtected);
+ else if (mpDocItem->hasPasswordHash(meDesiredHash))
+ maTextDocStatus.SetText(maTextHashGood);
+ else
+ {
+ // incompatible hash
+ maTextDocStatus.SetText(maTextHashBad);
+ bBtnEnabled = true;
+ }
+ }
+ maBtnRetypeDoc.Enable(bBtnEnabled);
+}
+
+void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
+{
+ if (nRowPos >= 4)
+ return;
+
+ FixedText* pName = NULL;
+ FixedText* pStatus = NULL;
+ PushButton* pBtn = NULL;
+ switch (nRowPos)
+ {
+ case 0:
+ pName = &maTextSheetName1;
+ pStatus = &maTextSheetStatus1;
+ pBtn = &maBtnRetypeSheet1;
+ break;
+ case 1:
+ pName = &maTextSheetName2;
+ pStatus = &maTextSheetStatus2;
+ pBtn = &maBtnRetypeSheet2;
+ break;
+ case 2:
+ pName = &maTextSheetName3;
+ pStatus = &maTextSheetStatus3;
+ pBtn = &maBtnRetypeSheet3;
+ break;
+ case 3:
+ pName = &maTextSheetName4;
+ pStatus = &maTextSheetStatus4;
+ pBtn = &maBtnRetypeSheet4;
+ break;
+ default:
+ return;
+ }
+
+ bool bBtnEnabled = false;
+ pName->SetText(maTableItems[nTab].maName);
+ pName->Show(true);
+ const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
+ if (pTabProtect && pTabProtect->isProtected())
+ {
+ if (pTabProtect->isPasswordEmpty())
+ pStatus->SetText(maTextNotPassProtected);
+ else if (pTabProtect->hasPasswordHash(meDesiredHash))
+ pStatus->SetText(maTextHashGood);
+ else
+ {
+ // incompatible hash
+ pStatus->SetText(maTextHashBad);
+ bBtnEnabled = true;
+ }
+ }
+ else
+ pStatus->SetText(maTextNotProtected);
+
+ pStatus->Show(true);
+ pBtn->Show(true);
+ pBtn->Enable(bBtnEnabled);
+}
+
+void ScRetypePassDlg::ResetTableRows()
+{
+ long nScrollPos = maScrollBar.GetThumbPos();
+ mnCurScrollPos = nScrollPos < 0 ? 0 : nScrollPos;
+ size_t nRowCount = maTableItems.size() - nScrollPos;
+ for (size_t i = 0; i < nRowCount; ++i)
+ SetTableData(i, static_cast< SCTAB >( i + nScrollPos ));
+}
+
+bool lcl_IsInGoodStatus(ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
+{
+ if (!pProtected || !pProtected->isProtected())
+ // Not protected.
+ return true;
+
+ if (pProtected->isPasswordEmpty())
+ return true;
+
+ if (pProtected->hasPasswordHash(eDesiredHash))
+ return true;
+
+ return false;
+}
+
+void ScRetypePassDlg::CheckHashStatus()
+{
+ do
+ {
+ if (!lcl_IsInGoodStatus(mpDocItem.get(), meDesiredHash))
+ break;
+
+ bool bStatusGood = true;
+ size_t nTabCount = maTableItems.size();
+ for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
+ {
+ if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
+ bStatusGood = false;
+ }
+ if (!bStatusGood)
+ break;
+
+ maBtnOk.Enable();
+ return;
+ }
+ while (false);
+
+ maBtnOk.Disable();
+}
+
+IMPL_LINK( ScRetypePassDlg, OKHdl, OKButton*, EMPTYARG )
+{
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK( ScRetypePassDlg, RetypeBtnHdl, PushButton*, pBtn )
+{
+ ScPassHashProtectable* pProtected = NULL;
+ if (pBtn == &maBtnRetypeDoc)
+ {
+ // document protection.
+ pProtected = mpDocItem.get();
+ }
+ else
+ {
+ // sheet protection.
+ size_t nTabPos = mnCurScrollPos;
+ if (pBtn == &maBtnRetypeSheet2)
+ nTabPos += 1;
+ else if (pBtn == &maBtnRetypeSheet3)
+ nTabPos += 2;
+ else if (pBtn == &maBtnRetypeSheet4)
+ nTabPos += 3;
+ else if (pBtn != &maBtnRetypeSheet1)
+ // This should never happen !
+ return 0;
+
+ if (nTabPos >= maTableItems.size())
+ // Likewise, this should never happen !
+ return 0;
+
+ pProtected = maTableItems[nTabPos].mpProtect.get();
+ }
+
+ if (!pProtected)
+ // What the ... !?
+ return 0;
+
+ ScRetypePassInputDlg aDlg(this, pProtected);
+ if (aDlg.Execute() == RET_OK)
+ {
+ // OK is pressed. Update the protected item.
+ if (aDlg.IsRemovePassword())
+ {
+ // Remove password from this item.
+ pProtected->setPassword(String());
+ }
+ else
+ {
+ // Set a new password.
+ String aNewPass = aDlg.GetNewPassword();
+ pProtected->setPassword(aNewPass);
+ }
+
+ SetDocData();
+ ResetTableRows();
+ CheckHashStatus();
+ }
+ return 0;
+}
+
+IMPL_LINK( ScRetypePassDlg, ScrollHdl, ScrollBar*, EMPTYARG )
+{
+ ResetTableRows();
+ return 0;
+}
+
+// ============================================================================
+
+ScRetypePassInputDlg::ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected) :
+ ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS_INPUT)),
+
+ maBtnOk (this, ScResId(BTN_OK)),
+ maBtnCancel (this, ScResId(BTN_CANCEL)),
+ maBtnHelp (this, ScResId(BTN_HELP)),
+
+ maBtnRetypePassword(this, ScResId(BTN_RETYPE_PASSWORD)),
+
+ maPassword1Text (this, ScResId(FT_PASSWORD1)),
+ maPassword1Edit (this, ScResId(ED_PASSWORD1)),
+ maPassword2Text (this, ScResId(FT_PASSWORD2)),
+ maPassword2Edit (this, ScResId(ED_PASSWORD2)),
+ maBtnMatchOldPass(this, ScResId(BTN_MATCH_OLD_PASSWORD)),
+
+ maBtnRemovePassword(this, ScResId(BTN_REMOVE_PASSWORD)),
+
+ mpProtected(pProtected)
+{
+ Init();
+}
+
+ScRetypePassInputDlg::~ScRetypePassInputDlg()
+{
+}
+
+short ScRetypePassInputDlg::Execute()
+{
+ return ModalDialog::Execute();
+}
+
+bool ScRetypePassInputDlg::IsRemovePassword() const
+{
+ return maBtnRemovePassword.IsChecked();
+}
+
+String ScRetypePassInputDlg::GetNewPassword() const
+{
+ return maPassword1Edit.GetText();
+}
+
+void ScRetypePassInputDlg::Init()
+{
+ Link aLink = LINK( this, ScRetypePassInputDlg, OKHdl );
+ maBtnOk.SetClickHdl(aLink);
+ aLink = LINK( this, ScRetypePassInputDlg, RadioBtnHdl );
+ maBtnRetypePassword.SetClickHdl(aLink);
+ maBtnRemovePassword.SetClickHdl(aLink);
+ aLink = LINK( this, ScRetypePassInputDlg, CheckBoxHdl );
+ maBtnMatchOldPass.SetClickHdl(aLink);
+ aLink = LINK( this, ScRetypePassInputDlg, PasswordModifyHdl );
+ maPassword1Edit.SetModifyHdl(aLink);
+ maPassword2Edit.SetModifyHdl(aLink);
+
+ maBtnOk.Disable();
+ maBtnRetypePassword.Check(true);
+ maBtnMatchOldPass.Check(true);
+ maPassword1Edit.GrabFocus();
+}
+
+void ScRetypePassInputDlg::CheckPasswordInput()
+{
+ String aPass1 = maPassword1Edit.GetText();
+ String aPass2 = maPassword2Edit.GetText();
+
+ if (!aPass1.Len() || !aPass2.Len())
+ {
+ // Empty password is not allowed.
+ maBtnOk.Disable();
+ return;
+ }
+
+ if (!aPass1.Equals(aPass2))
+ {
+ // The two passwords differ.
+ maBtnOk.Disable();
+ return;
+ }
+
+ if (!maBtnMatchOldPass.IsChecked())
+ {
+ maBtnOk.Enable();
+ return;
+ }
+
+ if (!mpProtected)
+ {
+ // This should never happen!
+ maBtnOk.Disable();
+ return;
+ }
+
+ bool bPassGood = mpProtected->verifyPassword(aPass1);
+ maBtnOk.Enable(bPassGood);
+}
+
+IMPL_LINK( ScRetypePassInputDlg, OKHdl, OKButton*, EMPTYARG )
+{
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK( ScRetypePassInputDlg, RadioBtnHdl, RadioButton*, pBtn )
+{
+ if (pBtn == &maBtnRetypePassword)
+ {
+ maBtnRemovePassword.Check(false);
+ maPassword1Text.Enable();
+ maPassword1Edit.Enable();
+ maPassword2Text.Enable();
+ maPassword2Edit.Enable();
+ maBtnMatchOldPass.Enable();
+ CheckPasswordInput();
+ }
+ else if (pBtn == &maBtnRemovePassword)
+ {
+ maBtnRetypePassword.Check(false);
+ maPassword1Text.Disable();
+ maPassword1Edit.Disable();
+ maPassword2Text.Disable();
+ maPassword2Edit.Disable();
+ maBtnMatchOldPass.Disable();
+ maBtnOk.Enable();
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScRetypePassInputDlg, CheckBoxHdl, CheckBox*, EMPTYARG )
+{
+ CheckPasswordInput();
+ return 0;
+}
+
+IMPL_LINK( ScRetypePassInputDlg, PasswordModifyHdl, Edit*, EMPTYARG )
+{
+ CheckPasswordInput();
+ return 0;
+}
diff --git a/sc/source/ui/miscdlgs/retypepassdlg.src b/sc/source/ui/miscdlgs/retypepassdlg.src
new file mode 100644
index 000000000000..87d436881f69
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.src
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.src,v $
+ * $Revision: 1.1.2.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 "retypepassdlg.hrc"
+
+
+ModalDialog RID_SCDLG_RETYPEPASS
+{
+ Text [ en-US ] = "Re-type Password" ;
+ Size = MAP_APPFONT ( 260 , 165 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 204, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ DefButton = TRUE ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 204, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 204, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ FixedText FT_DESC
+ {
+ Pos = MAP_APPFONT ( 6, 6 ) ;
+ Size = MAP_APPFONT ( 190, 36 );
+
+ WordBreak = TRUE ;
+
+ Text [ en-US ] = "The document you are about to export has one or more protected items with password that cannot be exported. Please re-type your password to be able to export your document." ;
+ };
+
+ FixedLine FL_DOCUMENT
+ {
+ Pos = MAP_APPFONT ( 6, 48 );
+ Size = MAP_APPFONT ( 190, 8 );
+
+ Text [ en-US ] = "Document protection" ;
+ };
+
+ FixedText FT_DOCSTATUS
+ {
+ Pos = MAP_APPFONT ( 10, 62 );
+ Size = MAP_APPFONT ( 140, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_DOC
+ {
+ Pos = MAP_APPFONT ( 158, 59 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedLine FL_SHEET
+ {
+ Pos = MAP_APPFONT ( 6, 83 );
+ Size = MAP_APPFONT ( 190, 8 );
+
+ Text [ en-US ] = "Sheet protection" ;
+ };
+
+ FixedText FT_SHEETNAME1
+ {
+ Pos = MAP_APPFONT ( 10, 97 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet1 has a really long name" ;
+ };
+
+ FixedText FT_SHEETSTATUS1
+ {
+ Pos = MAP_APPFONT ( 82, 97 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET1
+ {
+ Pos = MAP_APPFONT ( 158, 94 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME2
+ {
+ Pos = MAP_APPFONT ( 10, 113 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet2" ;
+ };
+
+ FixedText FT_SHEETSTATUS2
+ {
+ Pos = MAP_APPFONT ( 82, 113 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET2
+ {
+ Pos = MAP_APPFONT ( 158, 110 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME3
+ {
+ Pos = MAP_APPFONT ( 10, 129 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet3" ;
+ };
+
+ FixedText FT_SHEETSTATUS3
+ {
+ Pos = MAP_APPFONT ( 82, 129 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET3
+ {
+ Pos = MAP_APPFONT ( 158, 126 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME4
+ {
+ Pos = MAP_APPFONT ( 10, 145 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet4" ;
+ };
+
+ FixedText FT_SHEETSTATUS4
+ {
+ Pos = MAP_APPFONT ( 82, 145 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET4
+ {
+ Pos = MAP_APPFONT ( 158, 142 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ ScrollBar SB_SCROLL
+ {
+ Pos = MAP_APPFONT ( 190, 94 ) ;
+ Size = MAP_APPFONT ( 8, 61 ) ;
+ VScroll = TRUE ;
+ };
+
+ String STR_NOT_PROTECTED
+ {
+ Text [ en-US ] = "Not protected" ;
+ };
+
+ String STR_NOT_PASS_PROTECTED
+ {
+ Text [ en-US ] = "Not password-protected" ;
+ };
+
+ String STR_HASH_BAD
+ {
+ Text [ en-US ] = "Hash incompatible" ;
+ };
+
+ String STR_HASH_GOOD
+ {
+ Text [ en-US ] = "Hash compatible" ;
+ };
+
+ String STR_HASH_REGENERATED
+ {
+ Text [ en-US ] = "Hash re-generated" ;
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_RETYPEPASS_INPUT
+{
+ Text [ en-US ] = "Re-type Password" ;
+ Size = MAP_APPFONT ( 230 , 110 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 174, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ DefButton = TRUE ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 174, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 174, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ RadioButton BTN_RETYPE_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 11, 10 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "Re-type password" ;
+ };
+
+ FixedText FT_PASSWORD1
+ {
+ Pos = MAP_APPFONT ( 20, 30 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Password" ;
+ };
+
+ Edit ED_PASSWORD1
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 65, 29 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedText FT_PASSWORD2
+ {
+ Pos = MAP_APPFONT ( 20, 45 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Confirm" ;
+ };
+
+ Edit ED_PASSWORD2
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 65, 44 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ CheckBox BTN_MATCH_OLD_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 20, 65 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "New password must match the original password." ;
+ };
+
+ RadioButton BTN_REMOVE_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 11, 90 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "Remove password from this protected item." ;
+ };
+};
+
+
diff --git a/sc/source/ui/src/filter.src b/sc/source/ui/src/filter.src
index 73108b984ebe..2e6a1c330671 100644
--- a/sc/source/ui/src/filter.src
+++ b/sc/source/ui/src/filter.src
@@ -34,7 +34,7 @@ ModelessDialog RID_SCDLG_FILTER
HelpId = SID_FILTER ;
Hide = TRUE ;
SVLook = TRUE ;
- Size = MAP_APPFONT ( 251 , 121 ) ;
+ Size = MAP_APPFONT ( 279 , 121 ) ;
Text [ en-US ] = "Standard Filter" ;
Moveable = TRUE ;
Closeable = FALSE ;
@@ -58,7 +58,7 @@ ModelessDialog RID_SCDLG_FILTER
};
FixedText FT_VAL
{
- Pos = MAP_APPFONT ( 173 , 14 ) ;
+ Pos = MAP_APPFONT ( 201 , 14 ) ;
Size = MAP_APPFONT ( 60 , 8 ) ;
Text [ en-US ] = "Value" ;
};
@@ -150,7 +150,7 @@ ModelessDialog RID_SCDLG_FILTER
{
Border = TRUE ;
Pos = MAP_APPFONT ( 122 , 25 ) ;
- Size = MAP_APPFONT ( 47 , 145 ) ;
+ Size = MAP_APPFONT ( 75 , 145 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
stringlist [ en-US ] =
@@ -165,13 +165,19 @@ ModelessDialog RID_SCDLG_FILTER
< "Smallest" ; Default ; > ;
< "Largest %" ; Default ; > ;
< "Smallest %" ; Default ; > ;
+ < "Contains" ; Default ; > ;
+ < "Does not contain" ; Default ; > ;
+ < "Begins with" ; Default ; > ;
+ < "Does not begin with" ; Default ; > ;
+ < "Ends with" ; Default ; > ;
+ < "Does not end with" ; Default ; > ;
};
};
ListBox LB_COND2
{
Border = TRUE ;
Pos = MAP_APPFONT ( 122 , 41 ) ;
- Size = MAP_APPFONT ( 47 , 145 ) ;
+ Size = MAP_APPFONT ( 75 , 145 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
stringlist [ en-US ] =
@@ -186,13 +192,19 @@ ModelessDialog RID_SCDLG_FILTER
< "Smallest" ; Default ; > ;
< "Largest %" ; Default ; > ;
< "Smallest %" ; Default ; > ;
+ < "Contains" ; Default ; > ;
+ < "Does not contain" ; Default ; > ;
+ < "Begins with" ; Default ; > ;
+ < "Does not begin with" ; Default ; > ;
+ < "Ends with" ; Default ; > ;
+ < "Does not end with" ; Default ; > ;
};
};
ListBox LB_COND3
{
Border = TRUE ;
Pos = MAP_APPFONT ( 122 , 57 ) ;
- Size = MAP_APPFONT ( 47 , 145 ) ;
+ Size = MAP_APPFONT ( 75 , 145 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
stringlist [ en-US ] =
@@ -207,13 +219,19 @@ ModelessDialog RID_SCDLG_FILTER
< "Smallest" ; Default ; > ;
< "Largest %" ; Default ; > ;
< "Smallest %" ; Default ; > ;
+ < "Contains" ; Default ; > ;
+ < "Does not contain" ; Default ; > ;
+ < "Begins with" ; Default ; > ;
+ < "Does not begin with" ; Default ; > ;
+ < "Ends with" ; Default ; > ;
+ < "Does not end with" ; Default ; > ;
};
};
ListBox LB_COND4
{
Border = TRUE ;
Pos = MAP_APPFONT ( 122 , 73 ) ;
- Size = MAP_APPFONT ( 47 , 145 ) ;
+ Size = MAP_APPFONT ( 75 , 145 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
stringlist [ en-US ] =
@@ -228,39 +246,45 @@ ModelessDialog RID_SCDLG_FILTER
< "Smallest" ; Default ; > ;
< "Largest %" ; Default ; > ;
< "Smallest %" ; Default ; > ;
+ < "Contains" ; Default ; > ;
+ < "Does not contain" ; Default ; > ;
+ < "Begins with" ; Default ; > ;
+ < "Does not begin with" ; Default ; > ;
+ < "Ends with" ; Default ; > ;
+ < "Does not end with" ; Default ; > ;
};
};
ComboBox ED_VAL1
{
- Pos = MAP_APPFONT ( 173 , 25 ) ;
+ Pos = MAP_APPFONT ( 201 , 25 ) ;
Size = MAP_APPFONT ( 60 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
};
ComboBox ED_VAL2
{
- Pos = MAP_APPFONT ( 173 , 41 ) ;
+ Pos = MAP_APPFONT ( 201 , 41 ) ;
Size = MAP_APPFONT ( 60 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
};
ComboBox ED_VAL3
{
- Pos = MAP_APPFONT ( 173 , 57 ) ;
+ Pos = MAP_APPFONT ( 201 , 57 ) ;
Size = MAP_APPFONT ( 60 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
};
ComboBox ED_VAL4
{
- Pos = MAP_APPFONT ( 173 , 73 ) ;
+ Pos = MAP_APPFONT ( 201 , 73 ) ;
Size = MAP_APPFONT ( 60 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
};
ScrollBar LB_SCROLL
{
- Pos = MAP_APPFONT ( 237, 25 ) ;
+ Pos = MAP_APPFONT ( 265, 25 ) ;
Size = MAP_APPFONT ( 8 , 60 ) ;
TabStop = TRUE ;
VScroll = TRUE ;
@@ -269,7 +293,7 @@ ModelessDialog RID_SCDLG_FILTER
FixedLine FL_CRITERIA
{
Pos = MAP_APPFONT ( 6 , 3 ) ;
- Size = MAP_APPFONT ( 275 , 8 ) ;
+ Size = MAP_APPFONT ( 267 , 8 ) ;
Text [ en-US ] = "Filter criteria";
};
CheckBox BTN_CASE
@@ -325,7 +349,7 @@ ModelessDialog RID_SCDLG_FILTER
Border = TRUE ;
Hide = TRUE ;
Pos = MAP_APPFONT ( 21 , 170 ) ;
- Size = MAP_APPFONT ( 90 , 90 ) ;
+ Size = MAP_APPFONT ( 110 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
};
@@ -333,13 +357,13 @@ ModelessDialog RID_SCDLG_FILTER
{
Border = TRUE ;
Hide = TRUE ;
- Pos = MAP_APPFONT ( 115 , 170 ) ;
- Size = MAP_APPFONT ( 104 , 12 ) ;
+ Pos = MAP_APPFONT ( 136 , 170 ) ;
+ Size = MAP_APPFONT ( 110 , 12 ) ;
TabStop = TRUE ;
};
ImageButton RB_COPY_AREA
{
- Pos = MAP_APPFONT ( 221 , 169 ) ;
+ Pos = MAP_APPFONT ( 248 , 169 ) ;
Size = MAP_APPFONT ( 13 , 15 ) ;
TabStop = FALSE ;
QuickHelpText [ en-US ] = "Shrink" ;
@@ -348,7 +372,7 @@ ModelessDialog RID_SCDLG_FILTER
{
Hide = TRUE ;
Pos = MAP_APPFONT ( 6 , 118 ) ;
- Size = MAP_APPFONT ( 239 , 8 ) ;
+ Size = MAP_APPFONT ( 267 , 8 ) ;
};
FixedText FT_DBAREA
{
@@ -367,14 +391,14 @@ ModelessDialog RID_SCDLG_FILTER
};
OKButton BTN_OK
{
- Pos = MAP_APPFONT ( 141 , 101 ) ;
+ Pos = MAP_APPFONT ( 169 , 101 ) ;
Size = MAP_APPFONT ( 50 , 14 ) ;
TabStop = TRUE ;
DefButton = TRUE ;
};
CancelButton BTN_CANCEL
{
- Pos = MAP_APPFONT ( 195 , 101 ) ;
+ Pos = MAP_APPFONT ( 223 , 101 ) ;
Size = MAP_APPFONT ( 50 , 14 ) ;
TabStop = TRUE ;
};
@@ -395,7 +419,7 @@ ModelessDialog RID_SCDLG_FILTER
FixedLine FL_SEPARATOR
{
Pos = MAP_APPFONT ( 0 , 91 ) ;
- Size = MAP_APPFONT ( 251 , 6 ) ;
+ Size = MAP_APPFONT ( 279 , 6 ) ;
};
};
//============================================================================
diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src
index 5166340b189e..c5b8cfd1a9e8 100644
--- a/sc/source/ui/src/globstr.src
+++ b/sc/source/ui/src/globstr.src
@@ -438,10 +438,6 @@ Resource RID_GLOBSTR
{
Text [ en-US ] = "Cell merge not possible if cells already merged!" ;
};
- String STR_MSSG_APPLYPATTLINES_0
- {
- Text [ en-US ] = "Cannot apply borders to multiple selection" ;
- };
String STR_MSSG_INSERTCELLS_0
{
Text [ en-US ] = "Inserting into merged ranges not possible" ;
diff --git a/sc/source/ui/src/sortdlg.src b/sc/source/ui/src/sortdlg.src
index 2fed10c6f220..71aa7b594575 100644
--- a/sc/source/ui/src/sortdlg.src
+++ b/sc/source/ui/src/sortdlg.src
@@ -304,4 +304,48 @@ TabDialog RID_SCDLG_SORT
};
};
+ModalDialog RID_SCDLG_SORT_WARNING
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 180 , 91 ) ;
+ Text [ en-US ] = "Sort Range" ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ FixedText FT_TEXT
+ {
+ Pos = MAP_APPFONT ( 8 , 3 ) ;
+ Size = MAP_APPFONT ( 170 , 33 ) ;
+ WordBreak = TRUE;
+ Text [ en-US ] = "The cells next to the current selection also contain data. Do you want to extend the sort range to %1, or sort the currently selected range, %2?";
+ };
+ FixedText FT_TIP
+ {
+ Pos = MAP_APPFONT ( 8 , 55 ) ;
+ Size = MAP_APPFONT ( 170 , 33 ) ;
+ WordBreak = TRUE ;
+ Text [ en-US ] = "Tip: The sort range can be detected automatically. Place the cell cursor inside a list and execute sort. The whole range of neighboring non-empty cells will then be sorted.";
+ };
+ PushButton BTN_EXTSORT
+ {
+ Pos = MAP_APPFONT ( 6 , 39 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ Text [ en-US ] = "Extend selection";
+ };
+ PushButton BTN_CURSORT
+ {
+ Pos = MAP_APPFONT ( 70 , 39 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "Current selection";
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 134 , 39 ) ;
+ Size = MAP_APPFONT ( 40 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index f12dcda35c8f..ea1e303d6ae3 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -74,6 +74,7 @@ TYPEINIT1(ScUndoAutoFormat, SfxUndoAction);
TYPEINIT1(ScUndoReplace, SfxUndoAction);
TYPEINIT1(ScUndoTabOp, SfxUndoAction);
TYPEINIT1(ScUndoConversion, SfxUndoAction);
+TYPEINIT1(ScUndoRefConversion, SfxUndoAction);
TYPEINIT1(ScUndoRefreshLink, SfxUndoAction);
TYPEINIT1(ScUndoInsertAreaLink, SfxUndoAction);
TYPEINIT1(ScUndoRemoveAreaLink, SfxUndoAction);
@@ -1197,14 +1198,10 @@ void __EXPORT ScUndoReplace::Undo()
}
else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
{
- if (ScPostIt* pNote = pDoc->GetNote(aCursorPos))
- {
- pNote->SetText( aUndoStr );
- }
- else
- {
- DBG_ERROR("ScUndoReplace: Hier ist keine Notizzelle");
- }
+ ScPostIt* pNote = pDoc->GetNote( aCursorPos );
+ DBG_ASSERT( pNote, "ScUndoReplace::Undo - cell does not contain a note" );
+ if (pNote)
+ pNote->SetText( aCursorPos, aUndoStr );
if (pViewShell)
pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
SC_FOLLOW_JUMP, FALSE, FALSE );
@@ -1531,6 +1528,98 @@ BOOL ScUndoConversion::CanRepeat(SfxRepeatTarget& rTarget) const
//============================================================================
+// class ScUndoRefConversion
+//
+// cell reference conversion
+
+//----------------------------------------------------------------------------
+
+ScUndoRefConversion::ScUndoRefConversion( ScDocShell* pNewDocShell,
+ const ScRange& aMarkRange, const ScMarkData& rMark,
+ ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, BOOL bNewMulti, USHORT nNewFlag) :
+ScSimpleUndo( pNewDocShell ),
+aMarkData ( rMark ),
+pUndoDoc ( pNewUndoDoc ),
+pRedoDoc ( pNewRedoDoc ),
+aRange ( aMarkRange ),
+bMulti ( bNewMulti ),
+nFlags ( nNewFlag )
+{
+ SetChangeTrack();
+}
+
+__EXPORT ScUndoRefConversion::~ScUndoRefConversion()
+{
+ delete pUndoDoc;
+ delete pRedoDoc;
+}
+
+String __EXPORT ScUndoRefConversion::GetComment() const
+{
+ return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
+}
+
+void ScUndoRefConversion::SetChangeTrack()
+{
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack && (nFlags & IDF_FORMULA) )
+ pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
+ nStartChangeAction, nEndChangeAction );
+ else
+ nStartChangeAction = nEndChangeAction = 0;
+}
+
+void ScUndoRefConversion::DoChange( ScDocument* pRefDoc)
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ ShowTable(aRange);
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ pViewShell->SetMarkData( aMarkData );
+
+ ScRange aCopyRange = aRange;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pRefDoc->CopyToDocument( aCopyRange, nFlags, bMulti, pDoc, &aMarkData );
+ pDocShell->PostPaint( aRange, PAINT_GRID);
+ pDocShell->PostDataChanged();
+ if (pViewShell)
+ pViewShell->CellContentChanged();
+}
+void __EXPORT ScUndoRefConversion::Undo()
+{
+ BeginUndo();
+ if (pUndoDoc)
+ DoChange(pUndoDoc);
+ ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+ EndUndo();
+}
+
+void __EXPORT ScUndoRefConversion::Redo()
+{
+ BeginRedo();
+ if (pRedoDoc)
+ DoChange(pRedoDoc);
+ SetChangeTrack();
+ EndRedo();
+}
+
+void __EXPORT ScUndoRefConversion::Repeat(SfxRepeatTarget& rTarget)
+{
+ if (rTarget.ISA(ScTabViewTarget))
+ ((ScTabViewTarget&)rTarget).GetViewShell()->DoRefConversion();
+}
+
+BOOL __EXPORT ScUndoRefConversion::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+ return (rTarget.ISA(ScTabViewTarget));
+}
+//============================================================================
// class ScUndoRefreshLink
//
// Link aktualisieren / aendern
diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
index d1a59e65fdb0..eb23516cafeb 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -829,6 +829,7 @@ ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rP
mpDrawUndo( pDrawUndo )
{
DBG_ASSERT( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
+ DBG_ASSERT( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
}
ScUndoReplaceNote::~ScUndoReplaceNote()
@@ -883,7 +884,7 @@ void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
{
ScDocument& rDoc = *pDocShell->GetDocument();
DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
- ScPostIt* pNote = new ScPostIt( rDoc, rNoteData );
+ ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
rDoc.TakeNote( maPos, pNote );
}
}
@@ -896,7 +897,9 @@ void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
{
- // forget caption (already handled in drawing undo)
+ /* Forget pointer to caption object to suppress removing the
+ caption object from the drawing layer while deleting pNote
+ (removing the caption is done by a drawing undo action). */
pNote->ForgetCaption();
delete pNote;
}
@@ -920,7 +923,7 @@ void ScUndoShowHideNote::Undo()
{
BeginUndo();
if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
- pNote->ShowCaption( !mbShown );
+ pNote->ShowCaption( maPos, !mbShown );
EndUndo();
}
@@ -928,7 +931,7 @@ void ScUndoShowHideNote::Redo()
{
BeginRedo();
if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
- pNote->ShowCaption( mbShown );
+ pNote->ShowCaption( maPos, mbShown );
EndRedo();
}
diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx
index d3ff10783c27..abd6f815abf9 100644
--- a/sc/source/ui/undo/undotab.cxx
+++ b/sc/source/ui/undo/undotab.cxx
@@ -61,6 +61,7 @@
#include "prnsave.hxx"
#include "printfun.hxx"
#include "chgtrack.hxx"
+#include "tabprotection.hxx"
// for ScUndoRenameObject - might me moved to another file later
#include <svx/svditer.hxx>
@@ -72,6 +73,8 @@
extern BOOL bDrawIsInUndo; //! irgendwo als Member !!!
using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
// STATIC DATA -----------------------------------------------------------
@@ -85,7 +88,6 @@ TYPEINIT1(ScUndoMakeScenario, SfxUndoAction);
TYPEINIT1(ScUndoImportTab, SfxUndoAction);
TYPEINIT1(ScUndoRemoveLink, SfxUndoAction);
TYPEINIT1(ScUndoShowHideTab, SfxUndoAction);
-TYPEINIT1(ScUndoProtect, SfxUndoAction);
TYPEINIT1(ScUndoPrintRange, SfxUndoAction);
TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction);
TYPEINIT1(ScUndoRenameObject, SfxUndoAction);
@@ -112,12 +114,12 @@ ScUndoInsertTab::ScUndoInsertTab( ScDocShell* pNewDocShell,
SetChangeTrack();
}
-__EXPORT ScUndoInsertTab::~ScUndoInsertTab()
+ScUndoInsertTab::~ScUndoInsertTab()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoInsertTab::GetComment() const
+String ScUndoInsertTab::GetComment() const
{
if (bAppend)
return ScGlobal::GetRscString( STR_UNDO_APPEND_TAB );
@@ -138,7 +140,7 @@ void ScUndoInsertTab::SetChangeTrack()
nEndChangeAction = 0;
}
-void __EXPORT ScUndoInsertTab::Undo()
+void ScUndoInsertTab::Undo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo(nTab);
@@ -159,7 +161,7 @@ void __EXPORT ScUndoInsertTab::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoInsertTab::Redo()
+void ScUndoInsertTab::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -180,14 +182,14 @@ void __EXPORT ScUndoInsertTab::Redo()
SetChangeTrack();
}
-void __EXPORT ScUndoInsertTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoInsertTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -211,7 +213,7 @@ ScUndoInsertTables::ScUndoInsertTables( ScDocShell* pNewDocShell,
SetChangeTrack();
}
-__EXPORT ScUndoInsertTables::~ScUndoInsertTables()
+ScUndoInsertTables::~ScUndoInsertTables()
{
String *pStr=NULL;
if(pNameList!=NULL)
@@ -227,7 +229,7 @@ __EXPORT ScUndoInsertTables::~ScUndoInsertTables()
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoInsertTables::GetComment() const
+String ScUndoInsertTables::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
}
@@ -252,7 +254,7 @@ void ScUndoInsertTables::SetChangeTrack()
nStartChangeAction = nEndChangeAction = 0;
}
-void __EXPORT ScUndoInsertTables::Undo()
+void ScUndoInsertTables::Undo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo(nTab);
@@ -282,7 +284,7 @@ void __EXPORT ScUndoInsertTables::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoInsertTables::Redo()
+void ScUndoInsertTables::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -299,14 +301,14 @@ void __EXPORT ScUndoInsertTables::Redo()
SetChangeTrack();
}
-void __EXPORT ScUndoInsertTables::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoInsertTables::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -327,12 +329,12 @@ ScUndoDeleteTab::ScUndoDeleteTab( ScDocShell* pNewDocShell,const SvShorts &aTab,
SetChangeTrack();
}
-__EXPORT ScUndoDeleteTab::~ScUndoDeleteTab()
+ScUndoDeleteTab::~ScUndoDeleteTab()
{
theTabs.Remove(0,theTabs.Count());
}
-String __EXPORT ScUndoDeleteTab::GetComment() const
+String ScUndoDeleteTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_DELETE_TAB );
}
@@ -366,7 +368,7 @@ SCTAB lcl_GetVisibleTabBefore( ScDocument& rDoc, SCTAB nTab )
return nTab;
}
-void __EXPORT ScUndoDeleteTab::Undo()
+void ScUndoDeleteTab::Undo()
{
BeginUndo();
int i=0;
@@ -414,7 +416,7 @@ void __EXPORT ScUndoDeleteTab::Undo()
pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) );
if ( pRefUndoDoc->IsTabProtected( nTab ) )
- pDoc->SetTabProtection( nTab, TRUE, pRefUndoDoc->GetTabPassword( nTab ) );
+ pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab));
// Drawing-Layer passiert beim MoveUndo::EndUndo
// pDoc->TransferDrawPage(pRefUndoDoc, nTab,nTab);
@@ -450,7 +452,7 @@ void __EXPORT ScUndoDeleteTab::Undo()
// EndUndo();
}
-void __EXPORT ScUndoDeleteTab::Redo()
+void ScUndoDeleteTab::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo( lcl_GetVisibleTabBefore( *pDocShell->GetDocument(), theTabs[0] ) );
@@ -469,7 +471,7 @@ void __EXPORT ScUndoDeleteTab::Redo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
{
@@ -478,7 +480,7 @@ void __EXPORT ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
}
}
-BOOL __EXPORT ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -500,11 +502,11 @@ ScUndoRenameTab::ScUndoRenameTab( ScDocShell* pNewDocShell,
sNewName = rNewName;
}
-__EXPORT ScUndoRenameTab::~ScUndoRenameTab()
+ScUndoRenameTab::~ScUndoRenameTab()
{
}
-String __EXPORT ScUndoRenameTab::GetComment() const
+String ScUndoRenameTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_RENAME_TAB );
}
@@ -526,22 +528,22 @@ void ScUndoRenameTab::DoChange( SCTAB nTabP, const String& rName ) const
pViewShell->UpdateInputHandler();
}
-void __EXPORT ScUndoRenameTab::Undo()
+void ScUndoRenameTab::Undo()
{
DoChange(nTab, sOldName);
}
-void __EXPORT ScUndoRenameTab::Redo()
+void ScUndoRenameTab::Redo()
{
DoChange(nTab, sNewName);
}
-void __EXPORT ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// Repeat macht keinen Sinn
}
-BOOL __EXPORT ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -565,13 +567,13 @@ ScUndoMoveTab::ScUndoMoveTab( ScDocShell* pNewDocShell,
theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
}
-__EXPORT ScUndoMoveTab::~ScUndoMoveTab()
+ScUndoMoveTab::~ScUndoMoveTab()
{
theNewTabs.Remove(0,theNewTabs.Count());
theOldTabs.Remove(0,theOldTabs.Count());
}
-String __EXPORT ScUndoMoveTab::GetComment() const
+String ScUndoMoveTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_MOVE_TAB );
}
@@ -618,22 +620,22 @@ void ScUndoMoveTab::DoChange( BOOL bUndo ) const
pDocShell->PostDataChanged();
}
-void __EXPORT ScUndoMoveTab::Undo()
+void ScUndoMoveTab::Undo()
{
DoChange( TRUE );
}
-void __EXPORT ScUndoMoveTab::Redo()
+void ScUndoMoveTab::Redo()
{
DoChange( FALSE );
}
-void __EXPORT ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// kein Repeat ! ? !
}
-BOOL __EXPORT ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -660,12 +662,12 @@ ScUndoCopyTab::ScUndoCopyTab( ScDocShell* pNewDocShell,
theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
}
-__EXPORT ScUndoCopyTab::~ScUndoCopyTab()
+ScUndoCopyTab::~ScUndoCopyTab()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoCopyTab::GetComment() const
+String ScUndoCopyTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_COPY_TAB );
}
@@ -684,7 +686,7 @@ void ScUndoCopyTab::DoChange() const
pDocShell->PostDataChanged();
}
-void __EXPORT ScUndoCopyTab::Undo()
+void ScUndoCopyTab::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -717,7 +719,7 @@ void __EXPORT ScUndoCopyTab::Undo()
DoChange();
}
-void __EXPORT ScUndoCopyTab::Redo()
+void ScUndoCopyTab::Redo()
{
ScDocument* pDoc = pDocShell->GetDocument();
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -756,7 +758,7 @@ void __EXPORT ScUndoCopyTab::Redo()
}
if ( pDoc->IsTabProtected( nAdjSource ) )
- pDoc->SetTabProtection( nNewTab, TRUE, pDoc->GetTabPassword( nAdjSource ) );
+ pDoc->CopyTabProtection(nAdjSource, nNewTab);
}
RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
@@ -767,12 +769,12 @@ void __EXPORT ScUndoCopyTab::Redo()
}
-void __EXPORT ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// kein Repeat ! ? !
}
-BOOL __EXPORT ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -801,17 +803,17 @@ ScUndoMakeScenario::ScUndoMakeScenario( ScDocShell* pNewDocShell,
pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
}
-__EXPORT ScUndoMakeScenario::~ScUndoMakeScenario()
+ScUndoMakeScenario::~ScUndoMakeScenario()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoMakeScenario::GetComment() const
+String ScUndoMakeScenario::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_MAKESCENARIO );
}
-void __EXPORT ScUndoMakeScenario::Undo()
+void ScUndoMakeScenario::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -836,7 +838,7 @@ void __EXPORT ScUndoMakeScenario::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoMakeScenario::Redo()
+void ScUndoMakeScenario::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
@@ -858,7 +860,7 @@ void __EXPORT ScUndoMakeScenario::Redo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
{
@@ -866,7 +868,7 @@ void __EXPORT ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
}
}
-BOOL __EXPORT ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -889,13 +891,13 @@ ScUndoImportTab::ScUndoImportTab( ScDocShell* pShell,
pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
}
-__EXPORT ScUndoImportTab::~ScUndoImportTab()
+ScUndoImportTab::~ScUndoImportTab()
{
delete pRedoDoc;
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoImportTab::GetComment() const
+String ScUndoImportTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
}
@@ -922,7 +924,7 @@ void ScUndoImportTab::DoChange() const
PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
}
-void __EXPORT ScUndoImportTab::Undo()
+void ScUndoImportTab::Undo()
{
//! eingefuegte Bereichsnamen etc.
@@ -958,7 +960,7 @@ void __EXPORT ScUndoImportTab::Undo()
}
if ( pDoc->IsTabProtected( nTabPos ) )
- pRedoDoc->SetTabProtection( nTabPos, TRUE, pDoc->GetTabPassword( nTabPos ) );
+ pRedoDoc->SetTabProtection(nTabPos, pDoc->GetTabProtection(nTabPos));
}
}
@@ -973,7 +975,7 @@ void __EXPORT ScUndoImportTab::Undo()
DoChange();
}
-void __EXPORT ScUndoImportTab::Redo()
+void ScUndoImportTab::Redo()
{
if (!pRedoDoc)
{
@@ -1012,7 +1014,7 @@ void __EXPORT ScUndoImportTab::Redo()
}
if ( pRedoDoc->IsTabProtected( nTabPos ) )
- pDoc->SetTabProtection( nTabPos, TRUE, pRedoDoc->GetTabPassword( nTabPos ) );
+ pDoc->SetTabProtection(nTabPos, pRedoDoc->GetTabProtection(nTabPos));
}
RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
@@ -1020,14 +1022,14 @@ void __EXPORT ScUndoImportTab::Redo()
DoChange();
}
-void __EXPORT ScUndoImportTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoImportTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -1075,14 +1077,14 @@ ScUndoRemoveLink::ScUndoRemoveLink( ScDocShell* pShell, const String& rDoc ) :
}
}
-__EXPORT ScUndoRemoveLink::~ScUndoRemoveLink()
+ScUndoRemoveLink::~ScUndoRemoveLink()
{
delete pTabs;
delete pModes;
delete[] pTabNames;
}
-String __EXPORT ScUndoRemoveLink::GetComment() const
+String ScUndoRemoveLink::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_REMOVELINK );
}
@@ -1099,22 +1101,22 @@ void ScUndoRemoveLink::DoChange( BOOL bLink ) const
pDocShell->UpdateLinks();
}
-void __EXPORT ScUndoRemoveLink::Undo()
+void ScUndoRemoveLink::Undo()
{
DoChange( TRUE );
}
-void __EXPORT ScUndoRemoveLink::Redo()
+void ScUndoRemoveLink::Redo()
{
DoChange( FALSE );
}
-void __EXPORT ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -1132,7 +1134,7 @@ ScUndoShowHideTab::ScUndoShowHideTab( ScDocShell* pShell, SCTAB nNewTab, BOOL bN
{
}
-__EXPORT ScUndoShowHideTab::~ScUndoShowHideTab()
+ScUndoShowHideTab::~ScUndoShowHideTab()
{
}
@@ -1149,17 +1151,17 @@ void ScUndoShowHideTab::DoChange( BOOL bShowP ) const
pDocShell->SetDocumentModified();
}
-void __EXPORT ScUndoShowHideTab::Undo()
+void ScUndoShowHideTab::Undo()
{
DoChange(!bShow);
}
-void __EXPORT ScUndoShowHideTab::Redo()
+void ScUndoShowHideTab::Redo()
{
DoChange(bShow);
}
-void __EXPORT ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
@@ -1167,53 +1169,44 @@ void __EXPORT ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoShowHideTab::GetComment() const
+String ScUndoShowHideTab::GetComment() const
{
USHORT nId = bShow ? STR_UNDO_SHOWTAB : STR_UNDO_HIDETAB;
return ScGlobal::GetRscString( nId );
}
-// -----------------------------------------------------------------------
-//
-// Tabelle/Dokument schuetzen oder Schutz aufheben
-//
+// ============================================================================
-ScUndoProtect::ScUndoProtect( ScDocShell* pShell, SCTAB nNewTab,
- BOOL bNewProtect, const uno::Sequence<sal_Int8>& rNewPassword ) :
- ScSimpleUndo( pShell ),
- nTab( nNewTab ),
- bProtect( bNewProtect ),
- aPassword( rNewPassword )
+ScUndoDocProtect::ScUndoDocProtect(ScDocShell* pShell, auto_ptr<ScDocProtection> pProtectSettings) :
+ ScSimpleUndo(pShell),
+ mpProtectSettings(pProtectSettings)
{
}
-__EXPORT ScUndoProtect::~ScUndoProtect()
+ScUndoDocProtect::~ScUndoDocProtect()
{
}
-void ScUndoProtect::DoProtect( BOOL bDo )
+void ScUndoDocProtect::DoProtect(bool bProtect)
{
ScDocument* pDoc = pDocShell->GetDocument();
- if (bDo)
+ if (bProtect)
{
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( TRUE, aPassword );
- else
- pDoc->SetTabProtection( nTab, TRUE, aPassword );
+ // set protection.
+ auto_ptr<ScDocProtection> pCopy(new ScDocProtection(*mpProtectSettings));
+ pCopy->setProtected(true);
+ pDoc->SetDocProtection(pCopy.get());
}
else
{
- uno::Sequence<sal_Int8> aEmptyPass;
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( FALSE, aEmptyPass );
- else
- pDoc->SetTabProtection( nTab, FALSE, aEmptyPass );
+ // remove protection.
+ pDoc->SetDocProtection(NULL);
}
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -1226,37 +1219,103 @@ void ScUndoProtect::DoProtect( BOOL bDo )
pDocShell->PostPaintGridAll();
}
-void __EXPORT ScUndoProtect::Undo()
+void ScUndoDocProtect::Undo()
{
BeginUndo();
- DoProtect( !bProtect );
+ DoProtect(!mpProtectSettings->isProtected());
EndUndo();
}
-void __EXPORT ScUndoProtect::Redo()
+void ScUndoDocProtect::Redo()
{
BeginRedo();
- DoProtect( bProtect );
+ DoProtect(mpProtectSettings->isProtected());
EndRedo();
}
-void __EXPORT ScUndoProtect::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoDocProtect::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoDocProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE; // gippsnich
}
-String __EXPORT ScUndoProtect::GetComment() const
+String ScUndoDocProtect::GetComment() const
{
- USHORT nId;
- if ( nTab == TABLEID_DOC )
- nId = bProtect ? STR_UNDO_PROTECT_DOC : STR_UNDO_UNPROTECT_DOC;
+ USHORT nId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_DOC : STR_UNDO_UNPROTECT_DOC;
+ return ScGlobal::GetRscString( nId );
+}
+
+// ============================================================================
+
+ScUndoTabProtect::ScUndoTabProtect(ScDocShell* pShell, SCTAB nTab, auto_ptr<ScTableProtection> pProtectSettings) :
+ ScSimpleUndo(pShell),
+ mnTab(nTab),
+ mpProtectSettings(pProtectSettings)
+{
+}
+
+ScUndoTabProtect::~ScUndoTabProtect()
+{
+}
+
+void ScUndoTabProtect::DoProtect(bool bProtect)
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ if (bProtect)
+ {
+ // set protection.
+ auto_ptr<ScTableProtection> pCopy(new ScTableProtection(*mpProtectSettings));
+ pCopy->setProtected(true);
+ pDoc->SetTabProtection(mnTab, pCopy.get());
+ }
else
- nId = bProtect ? STR_UNDO_PROTECT_TAB : STR_UNDO_UNPROTECT_TAB;
+ {
+ // remove protection.
+ pDoc->SetTabProtection(mnTab, NULL);
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->UpdateLayerLocks();
+ pViewShell->UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
+ }
+
+ pDocShell->PostPaintGridAll();
+}
+
+void ScUndoTabProtect::Undo()
+{
+ BeginUndo();
+ DoProtect(!mpProtectSettings->isProtected());
+ EndUndo();
+}
+
+void ScUndoTabProtect::Redo()
+{
+ BeginRedo();
+ DoProtect(mpProtectSettings->isProtected());
+ EndRedo();
+}
+
+void ScUndoTabProtect::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL ScUndoTabProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // gippsnich
+}
+
+String ScUndoTabProtect::GetComment() const
+{
+ USHORT nId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_TAB : STR_UNDO_UNPROTECT_TAB;
return ScGlobal::GetRscString( nId );
}
@@ -1274,7 +1333,7 @@ ScUndoPrintRange::ScUndoPrintRange( ScDocShell* pShell, SCTAB nNewTab,
{
}
-__EXPORT ScUndoPrintRange::~ScUndoPrintRange()
+ScUndoPrintRange::~ScUndoPrintRange()
{
delete pOldRanges;
delete pNewRanges;
@@ -1297,31 +1356,31 @@ void ScUndoPrintRange::DoChange(BOOL bUndo)
pDocShell->PostPaint( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab), PAINT_GRID );
}
-void __EXPORT ScUndoPrintRange::Undo()
+void ScUndoPrintRange::Undo()
{
BeginUndo();
DoChange( TRUE );
EndUndo();
}
-void __EXPORT ScUndoPrintRange::Redo()
+void ScUndoPrintRange::Redo()
{
BeginRedo();
DoChange( FALSE );
EndRedo();
}
-void __EXPORT ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE; // gippsnich
}
-String __EXPORT ScUndoPrintRange::GetComment() const
+String ScUndoPrintRange::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_PRINTRANGES );
}
@@ -1350,16 +1409,16 @@ ScUndoScenarioFlags::ScUndoScenarioFlags( ScDocShell* pNewDocShell, SCTAB nT,
{
}
-__EXPORT ScUndoScenarioFlags::~ScUndoScenarioFlags()
+ScUndoScenarioFlags::~ScUndoScenarioFlags()
{
}
-String __EXPORT ScUndoScenarioFlags::GetComment() const
+String ScUndoScenarioFlags::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_EDITSCENARIO );
}
-void __EXPORT ScUndoScenarioFlags::Undo()
+void ScUndoScenarioFlags::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -1376,7 +1435,7 @@ void __EXPORT ScUndoScenarioFlags::Undo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoScenarioFlags::Redo()
+void ScUndoScenarioFlags::Redo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -1393,12 +1452,12 @@ void __EXPORT ScUndoScenarioFlags::Redo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
{
// Repeat macht keinen Sinn
}
-BOOL __EXPORT ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -1498,7 +1557,7 @@ ScUndoLayoutRTL::ScUndoLayoutRTL( ScDocShell* pShell, SCTAB nNewTab, BOOL bNewRT
{
}
-__EXPORT ScUndoLayoutRTL::~ScUndoLayoutRTL()
+ScUndoLayoutRTL::~ScUndoLayoutRTL()
{
}
@@ -1518,29 +1577,29 @@ void ScUndoLayoutRTL::DoChange( BOOL bNew )
pDocShell->SetInUndo( FALSE );
}
-void __EXPORT ScUndoLayoutRTL::Undo()
+void ScUndoLayoutRTL::Undo()
{
DoChange(!bRTL);
}
-void __EXPORT ScUndoLayoutRTL::Redo()
+void ScUndoLayoutRTL::Redo()
{
DoChange(bRTL);
}
-void __EXPORT ScUndoLayoutRTL::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoLayoutRTL::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute( FID_TAB_RTL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoLayoutRTL::GetComment() const
+String ScUndoLayoutRTL::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_TAB_RTL );
}
@@ -1560,7 +1619,7 @@ ScUndoSetGrammar::ScUndoSetGrammar( ScDocShell* pShell,
meOldGrammar = pDocShell->GetDocument()->GetGrammar();
}
-__EXPORT ScUndoSetGrammar::~ScUndoSetGrammar()
+ScUndoSetGrammar::~ScUndoSetGrammar()
{
}
@@ -1573,17 +1632,17 @@ void ScUndoSetGrammar::DoChange( formula::FormulaGrammar::Grammar eGrammar )
pDocShell->SetInUndo( FALSE );
}
-void __EXPORT ScUndoSetGrammar::Undo()
+void ScUndoSetGrammar::Undo()
{
DoChange( meOldGrammar );
}
-void __EXPORT ScUndoSetGrammar::Redo()
+void ScUndoSetGrammar::Redo()
{
DoChange( meNewGrammar );
}
-void __EXPORT ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
{
#if 0
// erAck: 2006-09-07T23:00+0200 commented out in CWS scr1c1
@@ -1593,12 +1652,12 @@ void __EXPORT ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
#endif
}
-BOOL __EXPORT ScUndoSetGrammar::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoSetGrammar::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoSetGrammar::GetComment() const
+String ScUndoSetGrammar::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_TAB_R1C1 );
}
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index c73f56dc55a4..cfe51aed6edc 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -1170,8 +1170,8 @@ BOOL lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange,
}
BOOL lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
- const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
- const formula::FormulaGrammar::Grammar eGrammar )
+ const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
+ const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
// BOOL bApi = TRUE;
@@ -1226,7 +1226,7 @@ BOOL lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
{
String aText(pColArr[nCol]);
ScAddress aPos( nDocCol, nDocRow, nTab );
- ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, eGrammar );
+ ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, rFormulaNmsp, eGrammar );
pDoc->PutCell( aPos, pNewCell );
++nDocCol;
@@ -5052,15 +5052,14 @@ rtl::OUString SAL_CALL ScCellRangeObj::getArrayFormula() throw(uno::RuntimeExcep
return aFormula;
}
-void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& aFormula,
- const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
+void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
{
ScDocShell* pDocSh = GetDocShell();
if (pDocSh)
{
- String aString(aFormula);
ScDocFunc aFunc(*pDocSh);
- if ( aString.Len() )
+ if ( rFormula.getLength() )
{
if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
{
@@ -5068,7 +5067,7 @@ void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& aFormula,
throw uno::RuntimeException();
}
- aFunc.EnterMatrix( aRange, NULL, NULL, aString, TRUE, TRUE, eGrammar );
+ aFunc.EnterMatrix( aRange, NULL, NULL, rFormula, TRUE, TRUE, rFormulaNmsp, eGrammar );
}
else
{
@@ -5086,14 +5085,14 @@ void SAL_CALL ScCellRangeObj::setArrayFormula( const rtl::OUString& aFormula )
{
ScUnoGuard aGuard;
// GRAM_PODF_A1 for API compatibility.
- SetArrayFormula_Impl( aFormula,formula::FormulaGrammar::GRAM_PODF_A1);
+ SetArrayFormula_Impl( aFormula, ::rtl::OUString(), formula::FormulaGrammar::GRAM_PODF_A1);
}
-void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& aFormula,
- const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
+void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& rFormula,
+ const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
- SetArrayFormula_Impl( aFormula, eGrammar);
+ SetArrayFormula_Impl( rFormula, rFormulaNmsp, eGrammar);
}
// XArrayFormulaTokens
@@ -5153,7 +5152,7 @@ void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::Formula
// Actually GRAM_PODF_A1 is a don't-care here because of the token
// array being set, it fits with other API compatibility grammars
// though.
- aFunc.EnterMatrix( aRange, NULL, &aTokenArray, EMPTY_STRING, TRUE, TRUE,formula::FormulaGrammar::GRAM_PODF_A1 );
+ aFunc.EnterMatrix( aRange, NULL, &aTokenArray, EMPTY_STRING, TRUE, TRUE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
}
else
{
@@ -5269,7 +5268,7 @@ void SAL_CALL ScCellRangeObj::setFormulaArray(
if (pDocSh)
{
// GRAM_PODF_A1 for API compatibility.
- bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray,formula::FormulaGrammar::GRAM_PODF_A1 );
+ bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
}
if (!bDone)
@@ -5439,7 +5438,7 @@ void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection,
if ( pDocSh && nSourceCount )
{
ScRange aSourceRange(aRange);
- SCCOLROW nCount = 0; // "Dest-Count"
+ SCsCOLROW nCount = 0; // "Dest-Count"
FillDir eDir = FILL_TO_BOTTOM;
BOOL bError = FALSE;
switch (nFillDirection)
@@ -5467,7 +5466,7 @@ void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection,
default:
bError = TRUE;
}
- if (nCount > MAXROW) // Ueberlauf
+ if (nCount < 0 || nCount > MAXROW) // overflow
bError = TRUE;
if (!bError)
@@ -5633,7 +5632,15 @@ void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDe
ScDocShell* pDocSh = GetDocShell();
ScFilterDescriptor aImpl(pDocSh);
- aImpl.setFilterFields( xDescriptor->getFilterFields() );
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xDescriptor2( xDescriptor, uno::UNO_QUERY );
+ if ( xDescriptor2.is() )
+ {
+ aImpl.setFilterFields2( xDescriptor2->getFilterFields2() );
+ }
+ else
+ {
+ aImpl.setFilterFields( xDescriptor->getFilterFields() );
+ }
// Rest sind jetzt Properties...
uno::Reference<beans::XPropertySet> xPropSet( xDescriptor, uno::UNO_QUERY );
@@ -6198,7 +6205,7 @@ void ScCellObj::SetString_Impl(const String& rString, BOOL bInterpret, BOOL bEng
{
ScDocFunc aFunc(*pDocSh);
// GRAM_PODF_A1 for API compatibility.
- (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, TRUE,formula::FormulaGrammar::GRAM_PODF_A1 );
+ (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, TRUE, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
}
}
@@ -6246,13 +6253,13 @@ void ScCellObj::SetFormulaResultDouble( double fResult )
}
void ScCellObj::SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
- const formula::FormulaGrammar::Grammar eGrammar )
+ const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
ScDocShell* pDocSh = GetDocShell();
if ( pDocSh )
{
ScDocFunc aFunc(*pDocSh);
- aFunc.SetCellText( aCellPos, String( rFormula), TRUE, TRUE, TRUE, eGrammar);
+ aFunc.SetCellText( aCellPos, rFormula, TRUE, TRUE, TRUE, rFormulaNmsp, eGrammar);
}
}
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 083dfc3f9374..ccd1b558342b 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -1051,7 +1051,7 @@ void lcl_SeperateOneRowRange(ScRange aR, const ScAddress& rPos, ScRangeListRef&
}
vector<ScSharedTokenRef> aTokens;
- ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument);
+ ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
return !aTokens.empty();
}
@@ -1445,7 +1445,7 @@ ScChart2DataProvider::createDataSource(
}
vector<ScSharedTokenRef> aRefTokens;
- ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument);
+ ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
if (aRefTokens.empty())
// Invalid range representation. Bail out.
throw lang::IllegalArgumentException();
@@ -2180,7 +2180,7 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum
return false;
vector<ScSharedTokenRef> aTokens;
- ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument);
+ ScRefTokenHelper::compileRangeRepresentation(aTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
return !aTokens.empty();
}
@@ -2197,6 +2197,12 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL
if(!m_pDocument || (aRangeRepresentation.getLength() == 0))
return xResult;
+ // Note: the range representation must be in Calc A1 format. The import
+ // filters use this method to pass data ranges, and they have no idea what
+ // the current formula syntax is. In the future we should add another
+ // method to allow the client code to directly pass tokens representing
+ // ranges.
+
vector<ScSharedTokenRef> aRefTokens;
ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument);
if (aRefTokens.empty())
@@ -2242,7 +2248,7 @@ rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const rtl::OUStr
return aRet;
vector<ScSharedTokenRef> aRefTokens;
- ScRefTokenHelper::compileRangeRepresentation(aRefTokens, sRangeRepresentation, m_pDocument);
+ ScRefTokenHelper::compileRangeRepresentation(aRefTokens, sRangeRepresentation, m_pDocument, m_pDocument->GetGrammar());
if (aRefTokens.empty())
throw lang::IllegalArgumentException();
@@ -2483,7 +2489,7 @@ void ScChart2DataProvider::detectRangesFromDataSource(vector<ScSharedTokenRef>&
{
const OUString& rRangeRep = *itr;
vector<ScSharedTokenRef> aTokens;
- ScRefTokenHelper::compileRangeRepresentation(aTokens, rRangeRep, m_pDocument);
+ ScRefTokenHelper::compileRangeRepresentation(aTokens, rRangeRep, m_pDocument, m_pDocument->GetGrammar());
CollectRefTokens func;
func = for_each(aTokens.begin(), aTokens.end(), func);
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 98a8a8551d6c..13f2c26c6e47 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -45,6 +45,8 @@
#include <com/sun/star/table/TableOrientation.hpp>
#include <com/sun/star/table/CellRangeAddress.hpp>
#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
#include "datauno.hxx"
#include "dapiuno.hxx"
@@ -1106,7 +1108,7 @@ void ScFilterDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
}
}
-// XSheetFilterDescriptor
+// XSheetFilterDescriptor and XSheetFilterDescriptor2
uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilterFields()
throw(uno::RuntimeException)
@@ -1177,6 +1179,80 @@ uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilte
return aSeq;
}
+uno::Sequence<sheet::TableFilterField2> SAL_CALL ScFilterDescriptorBase::getFilterFields2()
+throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScQueryParam aParam;
+ GetData(aParam);
+
+ SCSIZE nEntries = aParam.GetEntryCount(); // allozierte Eintraege im Param
+ SCSIZE nCount = 0; // aktive
+ while ( nCount < nEntries &&
+ aParam.GetEntry(nCount).bDoQuery )
+ ++nCount;
+
+ sheet::TableFilterField2 aField;
+ uno::Sequence<sheet::TableFilterField2> aSeq(static_cast<sal_Int32>(nCount));
+ sheet::TableFilterField2* pAry = aSeq.getArray();
+ for (SCSIZE i=0; i<nCount; i++)
+ {
+ const ScQueryEntry& rEntry = aParam.GetEntry(i);
+
+ rtl::OUString aStringValue;
+ if (rEntry.pStr)
+ aStringValue = *rEntry.pStr;
+
+ aField.Connection = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
+ aField.Field = rEntry.nField;
+ aField.IsNumeric = !rEntry.bQueryByString;
+ aField.StringValue = aStringValue;
+ aField.NumericValue = rEntry.nVal;
+
+ switch (rEntry.eOp) // ScQueryOp
+ {
+ case SC_EQUAL:
+ {
+ aField.Operator = sheet::FilterOperator2::EQUAL;
+ if (!rEntry.bQueryByString && *rEntry.pStr == EMPTY_STRING)
+ {
+ if (rEntry.nVal == SC_EMPTYFIELDS)
+ {
+ aField.Operator = sheet::FilterOperator2::EMPTY;
+ aField.NumericValue = 0;
+ }
+ else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+ {
+ aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
+ aField.NumericValue = 0;
+ }
+ }
+ }
+ break;
+ case SC_LESS: aField.Operator = sheet::FilterOperator2::LESS; break;
+ case SC_GREATER: aField.Operator = sheet::FilterOperator2::GREATER; break;
+ case SC_LESS_EQUAL: aField.Operator = sheet::FilterOperator2::LESS_EQUAL; break;
+ case SC_GREATER_EQUAL: aField.Operator = sheet::FilterOperator2::GREATER_EQUAL; break;
+ case SC_NOT_EQUAL: aField.Operator = sheet::FilterOperator2::NOT_EQUAL; break;
+ case SC_TOPVAL: aField.Operator = sheet::FilterOperator2::TOP_VALUES; break;
+ case SC_BOTVAL: aField.Operator = sheet::FilterOperator2::BOTTOM_VALUES; break;
+ case SC_TOPPERC: aField.Operator = sheet::FilterOperator2::TOP_PERCENT; break;
+ case SC_BOTPERC: aField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT; break;
+ case SC_CONTAINS: aField.Operator = sheet::FilterOperator2::CONTAINS; break;
+ case SC_DOES_NOT_CONTAIN: aField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN; break;
+ case SC_BEGINS_WITH: aField.Operator = sheet::FilterOperator2::BEGINS_WITH; break;
+ case SC_DOES_NOT_BEGIN_WITH: aField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH; break;
+ case SC_ENDS_WITH: aField.Operator = sheet::FilterOperator2::ENDS_WITH; break;
+ case SC_DOES_NOT_END_WITH: aField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH; break;
+ default:
+ DBG_ERROR("Falscher Filter-enum");
+ aField.Operator = sheet::FilterOperator2::EMPTY;
+ }
+ pAry[i] = aField;
+ }
+ return aSeq;
+}
+
void SAL_CALL ScFilterDescriptorBase::setFilterFields(
const uno::Sequence<sheet::TableFilterField>& aFilterFields )
throw(uno::RuntimeException)
@@ -1251,6 +1327,86 @@ void SAL_CALL ScFilterDescriptorBase::setFilterFields(
PutData(aParam);
}
+void SAL_CALL ScFilterDescriptorBase::setFilterFields2(
+ const uno::Sequence<sheet::TableFilterField2>& aFilterFields )
+ throw(uno::RuntimeException)
+{
+ ScUnoGuard aGuard;
+ ScQueryParam aParam;
+ GetData(aParam);
+
+ SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
+ DBG_ASSERT( nCount <= MAXQUERY, "setFilterFields: zu viele" );
+
+ aParam.Resize( nCount );
+
+ const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
+ SCSIZE i;
+ for (i=0; i<nCount; i++)
+ {
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (!rEntry.pStr)
+ rEntry.pStr = new String; // sollte nicht sein (soll immer initialisiert sein)
+
+ rEntry.bDoQuery = TRUE;
+ rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+ rEntry.nField = pAry[i].Field;
+ rEntry.bQueryByString = !pAry[i].IsNumeric;
+ *rEntry.pStr = String( pAry[i].StringValue );
+ rEntry.nVal = pAry[i].NumericValue;
+
+ if (!rEntry.bQueryByString && pDocSh)
+ {
+ pDocSh->GetDocument()->GetFormatTable()->GetInputLineString(rEntry.nVal, 0, *rEntry.pStr);
+ }
+
+ switch (pAry[i].Operator) // FilterOperator
+ {
+ case sheet::FilterOperator2::EQUAL: rEntry.eOp = SC_EQUAL; break;
+ case sheet::FilterOperator2::LESS: rEntry.eOp = SC_LESS; break;
+ case sheet::FilterOperator2::GREATER: rEntry.eOp = SC_GREATER; break;
+ case sheet::FilterOperator2::LESS_EQUAL: rEntry.eOp = SC_LESS_EQUAL; break;
+ case sheet::FilterOperator2::GREATER_EQUAL: rEntry.eOp = SC_GREATER_EQUAL; break;
+ case sheet::FilterOperator2::NOT_EQUAL: rEntry.eOp = SC_NOT_EQUAL; break;
+ case sheet::FilterOperator2::TOP_VALUES: rEntry.eOp = SC_TOPVAL; break;
+ case sheet::FilterOperator2::BOTTOM_VALUES: rEntry.eOp = SC_BOTVAL; break;
+ case sheet::FilterOperator2::TOP_PERCENT: rEntry.eOp = SC_TOPPERC; break;
+ case sheet::FilterOperator2::BOTTOM_PERCENT: rEntry.eOp = SC_BOTPERC; break;
+ case sheet::FilterOperator2::CONTAINS: rEntry.eOp = SC_CONTAINS; break;
+ case sheet::FilterOperator2::DOES_NOT_CONTAIN: rEntry.eOp = SC_DOES_NOT_CONTAIN; break;
+ case sheet::FilterOperator2::BEGINS_WITH: rEntry.eOp = SC_BEGINS_WITH; break;
+ case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH: rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
+ case sheet::FilterOperator2::ENDS_WITH: rEntry.eOp = SC_ENDS_WITH; break;
+ case sheet::FilterOperator2::DOES_NOT_END_WITH: rEntry.eOp = SC_DOES_NOT_END_WITH; break;
+ case sheet::FilterOperator2::EMPTY:
+ {
+ rEntry.eOp = SC_EQUAL;
+ rEntry.nVal = SC_EMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ *rEntry.pStr = EMPTY_STRING;
+ }
+ break;
+ case sheet::FilterOperator2::NOT_EMPTY:
+ {
+ rEntry.eOp = SC_EQUAL;
+ rEntry.nVal = SC_NONEMPTYFIELDS;
+ rEntry.bQueryByString = FALSE;
+ *rEntry.pStr = EMPTY_STRING;
+ }
+ break;
+ default:
+ DBG_ERROR("Falscher Query-enum");
+ rEntry.eOp = SC_EQUAL;
+ }
+ }
+
+ SCSIZE nParamCount = aParam.GetEntryCount(); // Param wird nicht unter 8 resized
+ for (i=nCount; i<nParamCount; i++)
+ aParam.GetEntry(i).bDoQuery = FALSE; // ueberzaehlige Felder zuruecksetzen
+
+ PutData(aParam);
+}
+
// Rest sind Properties
// XPropertySet
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index f25d4a41980a..c924205bdce5 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -271,10 +271,10 @@ SfxObjectShell* ScModelObj::GetEmbeddedObject() const
return pDocShell;
}
-void ScModelObj::UpdateAllRowHeights()
+void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark)
{
if (pDocShell)
- pDocShell->UpdateAllRowHeights();
+ pDocShell->UpdateAllRowHeights(pTabMark);
}
ScDrawLayer* ScModelObj::MakeDrawLayer()
@@ -2791,7 +2791,26 @@ void SAL_CALL ScTableRowsObj::setPropertyValue(
nRowArr[1] = nEndRow;
String aNameString(aPropertyName);
- if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
+ if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
+ {
+ sal_Int32 nNewHeight = 0;
+ if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
+ {
+ // used to set the stored row height for rows with optimal height when loading
+ pDoc->SetRowHeightRange( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) );
+ }
+ else
+ {
+ BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
+ if (bOpt)
+ aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE );
+ else
+ {
+ //! manually set old heights again?
+ }
+ }
+ }
+ else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
{
sal_Int32 nNewHeight = 0;
if ( aValue >>= nNewHeight )
@@ -2813,16 +2832,6 @@ void SAL_CALL ScTableRowsObj::setPropertyValue(
else
pDoc->GetRowFlagsArrayModifiable( nTab).AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) );
}
- else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
- {
- BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
- if (bOpt)
- aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE );
- else
- {
- //! manually set old heights again?
- }
- }
else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
{
//! single function to set/remove all breaks?
diff --git a/sc/source/ui/unoobj/editsrc.cxx b/sc/source/ui/unoobj/editsrc.cxx
index 80f77998fe44..476409fa5113 100644
--- a/sc/source/ui/unoobj/editsrc.cxx
+++ b/sc/source/ui/unoobj/editsrc.cxx
@@ -51,6 +51,7 @@
#include "unoguard.hxx"
#include "drwlayer.hxx"
#include "userdat.hxx"
+#include "postit.hxx"
#include "AccessibleText.hxx"
//------------------------------------------------------------------------
@@ -223,7 +224,7 @@ SvxEditSource* ScAnnotationEditSource::Clone() const
SdrObject* ScAnnotationEditSource::GetCaptionObj()
{
ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos );
- return pNote ? pNote->GetCaption() : 0;
+ return pNote ? pNote->GetOrCreateCaption( aCellPos ) : 0;
}
SvxTextForwarder* ScAnnotationEditSource::GetTextForwarder()
diff --git a/sc/source/ui/unoobj/fmtuno.cxx b/sc/source/ui/unoobj/fmtuno.cxx
index 14fdb958a180..f9407b544f76 100644
--- a/sc/source/ui/unoobj/fmtuno.cxx
+++ b/sc/source/ui/unoobj/fmtuno.cxx
@@ -42,7 +42,6 @@
#include "fmtuno.hxx"
#include "miscuno.hxx"
-#include "conditio.hxx"
#include "validat.hxx"
#include "document.hxx"
#include "unoguard.hxx"
@@ -51,7 +50,8 @@
#include "tokenarray.hxx"
#include "tokenuno.hxx"
-using namespace com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::formula;
//------------------------------------------------------------------------
@@ -130,12 +130,17 @@ ScConditionMode lcl_ConditionOperatorToMode( sheet::ConditionOperator eOper )
//------------------------------------------------------------------------
-//UNUSED2008-05 ScTableConditionalFormat::ScTableConditionalFormat()
-//UNUSED2008-05 {
-//UNUSED2008-05 }
+ScCondFormatEntryItem::ScCondFormatEntryItem() :
+ meGrammar1( FormulaGrammar::GRAM_UNSPECIFIED ),
+ meGrammar2( FormulaGrammar::GRAM_UNSPECIFIED ),
+ meMode( SC_COND_NONE )
+{
+}
+
+//------------------------------------------------------------------------
-ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
- const formula::FormulaGrammar::Grammar eGrammar)
+ScTableConditionalFormat::ScTableConditionalFormat(
+ ScDocument* pDoc, ULONG nKey, FormulaGrammar::Grammar eGrammar)
{
// Eintrag aus dem Dokument lesen...
@@ -156,11 +161,11 @@ ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
{
ScCondFormatEntryItem aItem;
const ScCondFormatEntry* pFormatEntry = pFormat->GetEntry(i);
- aItem.mnMode = sal::static_int_cast<USHORT>(pFormatEntry->GetOperation());
+ aItem.meMode = pFormatEntry->GetOperation();
aItem.maPos = pFormatEntry->GetValidSrcPos();
aItem.maExpr1 = pFormatEntry->GetExpression(aItem.maPos, 0, 0, eGrammar);
aItem.maExpr2 = pFormatEntry->GetExpression(aItem.maPos, 1, 0, eGrammar);
- aItem.meGrammar = eGrammar;
+ aItem.meGrammar1 = aItem.meGrammar2 = eGrammar;
aItem.maStyle = pFormatEntry->GetStyle();
AddEntry_Impl(aItem);
@@ -170,8 +175,20 @@ ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
}
}
+namespace {
+
+FormulaGrammar::Grammar lclResolveGrammar( FormulaGrammar::Grammar eExtGrammar, FormulaGrammar::Grammar eIntGrammar )
+{
+ if( eExtGrammar != FormulaGrammar::GRAM_UNSPECIFIED )
+ return eExtGrammar;
+ OSL_ENSURE( eIntGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "lclResolveGrammar - unspecified grammar, using GRAM_PODF_A1" );
+ return (eIntGrammar == FormulaGrammar::GRAM_UNSPECIFIED) ? FormulaGrammar::GRAM_PODF_A1 : eIntGrammar;
+}
+
+} // namespace
+
void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
- ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar ) const
+ ScDocument* pDoc, FormulaGrammar::Grammar eGrammar) const
{
// ScConditionalFormat = Core-Struktur, muss leer sein
@@ -185,15 +202,12 @@ void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
ScCondFormatEntryItem aData;
pEntry->GetData(aData);
- if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
- eGrammar = aData.meGrammar;
- if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
- {
- DBG_ERRORFILE("FillFormat: unspecified grammar, using GRAM_PODF_A1");
- eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
- }
- ScCondFormatEntry aCoreEntry( static_cast<ScConditionMode>(aData.mnMode),
- aData.maExpr1, aData.maExpr2, pDoc, aData.maPos, aData.maStyle, eGrammar );
+
+ FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, aData.meGrammar1 );
+ FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, aData.meGrammar2 );
+
+ ScCondFormatEntry aCoreEntry( aData.meMode, aData.maExpr1, aData.maExpr2,
+ pDoc, aData.maPos, aData.maStyle, aData.maExprNmsp1, aData.maExprNmsp2, eGrammar1, eGrammar2 );
if ( aData.maPosStr.Len() )
aCoreEntry.SetSrcString( aData.maPosStr );
@@ -248,69 +262,86 @@ void SAL_CALL ScTableConditionalFormat::addNew(
{
ScUnoGuard aGuard;
ScCondFormatEntryItem aEntry;
- aEntry.mnMode = sal::static_int_cast<USHORT>(SC_COND_NONE);
+ aEntry.meMode = SC_COND_NONE;
const beans::PropertyValue* pPropArray = aConditionalEntry.getConstArray();
long nPropCount = aConditionalEntry.getLength();
for (long i = 0; i < nPropCount; i++)
{
const beans::PropertyValue& rProp = pPropArray[i];
- String aPropName(rProp.Name);
- if ( aPropName.EqualsAscii( SC_UNONAME_OPERATOR ) )
+ if ( rProp.Name.equalsAscii( SC_UNONAME_OPERATOR ) )
{
sheet::ConditionOperator eOper = (sheet::ConditionOperator)
ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
- aEntry.mnMode = sal::static_int_cast<USHORT>(lcl_ConditionOperatorToMode( eOper ));
+ aEntry.meMode = lcl_ConditionOperatorToMode( eOper );
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_FORMULA1 ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA1 ) )
{
rtl::OUString aStrVal;
uno::Sequence<sheet::FormulaToken> aTokens;
if ( rProp.Value >>= aStrVal )
- aEntry.maExpr1 = String( aStrVal );
+ aEntry.maExpr1 = aStrVal;
else if ( rProp.Value >>= aTokens )
{
aEntry.maExpr1.Erase();
aEntry.maTokens1 = aTokens;
}
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_FORMULA2 ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULA2 ) )
{
rtl::OUString aStrVal;
uno::Sequence<sheet::FormulaToken> aTokens;
if ( rProp.Value >>= aStrVal )
- aEntry.maExpr2 = String( aStrVal );
+ aEntry.maExpr2 = aStrVal;
else if ( rProp.Value >>= aTokens )
{
aEntry.maExpr2.Erase();
aEntry.maTokens2 = aTokens;
}
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_SOURCEPOS ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_SOURCEPOS ) )
{
table::CellAddress aAddress;
if ( rProp.Value >>= aAddress )
aEntry.maPos = ScAddress( (SCCOL)aAddress.Column, (SCROW)aAddress.Row, aAddress.Sheet );
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_SOURCESTR ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_SOURCESTR ) )
{
rtl::OUString aStrVal;
if ( rProp.Value >>= aStrVal )
aEntry.maPosStr = String( aStrVal );
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_STYLENAME ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_STYLENAME ) )
{
rtl::OUString aStrVal;
if ( rProp.Value >>= aStrVal )
aEntry.maStyle = ScStyleNameConversion::ProgrammaticToDisplayName(
aStrVal, SFX_STYLE_FAMILY_PARA );
}
- else if ( aPropName.EqualsAscii( SC_UNONAME_GRAMMAR ) )
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULANMSP1 ) )
+ {
+ rtl::OUString aStrVal;
+ if ( rProp.Value >>= aStrVal )
+ aEntry.maExprNmsp1 = aStrVal;
+ }
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_FORMULANMSP2 ) )
+ {
+ rtl::OUString aStrVal;
+ if ( rProp.Value >>= aStrVal )
+ aEntry.maExprNmsp2 = aStrVal;
+ }
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_GRAMMAR1 ) )
{
sal_Int32 nVal = 0;
if ( rProp.Value >>= nVal )
- aEntry.meGrammar = static_cast<formula::FormulaGrammar::Grammar>(nVal);
+ aEntry.meGrammar1 = static_cast< FormulaGrammar::Grammar >( nVal );
+ }
+ else if ( rProp.Name.equalsAscii( SC_UNONAME_GRAMMAR2 ) )
+ {
+ sal_Int32 nVal = 0;
+ if ( rProp.Value >>= nVal )
+ aEntry.meGrammar2 = static_cast< FormulaGrammar::Grammar >( nVal );
}
else
{
@@ -523,14 +554,14 @@ sheet::ConditionOperator SAL_CALL ScTableConditionalEntry::getOperator()
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
- return lcl_ConditionModeToOperator( static_cast<ScConditionMode>(aData.mnMode) );
+ return lcl_ConditionModeToOperator( aData.meMode );
}
void SAL_CALL ScTableConditionalEntry::setOperator( sheet::ConditionOperator nOperator )
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
- aData.mnMode = sal::static_int_cast<USHORT>( lcl_ConditionOperatorToMode( nOperator ) );
+ aData.meMode = lcl_ConditionOperatorToMode( nOperator );
if (pParent)
pParent->DataChanged();
}
@@ -619,7 +650,7 @@ ScTableValidationObj::ScTableValidationObj(ScDocument* pDoc, ULONG nKey,
aSrcPos = pData->GetValidSrcPos(); // #b4974740# valid pos for expressions
aExpr1 = pData->GetExpression( aSrcPos, 0, 0, eGrammar );
aExpr2 = pData->GetExpression( aSrcPos, 1, 0, eGrammar );
- meGrammar = eGrammar;
+ meGrammar1 = meGrammar2 = eGrammar;
nValMode = sal::static_int_cast<USHORT>( pData->GetDataMode() );
bIgnoreBlank = pData->IsIgnoreBlank();
nShowList = pData->GetListType();
@@ -647,18 +678,14 @@ ScValidationData* ScTableValidationObj::CreateValidationData( ScDocument* pDoc,
{
// ScValidationData = Core-Struktur
- if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
- eGrammar = meGrammar;
- if (eGrammar == formula::FormulaGrammar::GRAM_UNSPECIFIED)
- {
- DBG_ERRORFILE("CreateValidationData: unspecified grammar, using GRAM_PODF_A1");
- eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
- }
+ FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, meGrammar1 );
+ FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, meGrammar2 );
ScValidationData* pRet = new ScValidationData( (ScValidationMode)nValMode,
(ScConditionMode)nMode,
aExpr1, aExpr2, pDoc, aSrcPos,
- eGrammar );
+ maExprNmsp1, maExprNmsp2,
+ eGrammar1, eGrammar2 );
pRet->SetIgnoreBlank(bIgnoreBlank);
pRet->SetListType(nShowList);
@@ -702,7 +729,9 @@ void ScTableValidationObj::ClearData_Impl()
aSrcPos.Set(0,0,0);
aExpr1.Erase();
aExpr2.Erase();
- meGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED; // will be overriden when needed
+ maExprNmsp1.Erase();
+ maExprNmsp2.Erase();
+ meGrammar1 = meGrammar2 = FormulaGrammar::GRAM_UNSPECIFIED; // will be overriden when needed
aInputTitle.Erase();
aInputMessage.Erase();
aErrorTitle.Erase();
@@ -905,13 +934,37 @@ void SAL_CALL ScTableValidationObj::setPropertyValue(
if ( aValue >>= aStrVal )
aPosString = String( aStrVal );
}
- else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR ) )
+ else if ( aString.EqualsAscii( SC_UNONAME_FORMULANMSP1 ) )
+ {
+ // internal - only for XML filter, not in PropertySetInfo, only set
+
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ maExprNmsp1 = aStrVal;
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_FORMULANMSP2 ) )
+ {
+ // internal - only for XML filter, not in PropertySetInfo, only set
+
+ rtl::OUString aStrVal;
+ if ( aValue >>= aStrVal )
+ maExprNmsp2 = aStrVal;
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR1 ) )
+ {
+ // internal - only for XML filter, not in PropertySetInfo, only set
+
+ sal_Int32 nVal = 0;
+ if ( aValue >>= nVal )
+ meGrammar1 = static_cast< FormulaGrammar::Grammar >(nVal);
+ }
+ else if ( aString.EqualsAscii( SC_UNONAME_GRAMMAR2 ) )
{
// internal - only for XML filter, not in PropertySetInfo, only set
sal_Int32 nVal = 0;
if ( aValue >>= nVal )
- meGrammar = static_cast<formula::FormulaGrammar::Grammar>(nVal);
+ meGrammar2 = static_cast< FormulaGrammar::Grammar >(nVal);
}
DataChanged();
diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx
index 4a9cd420f5de..e44dab865d46 100644
--- a/sc/source/ui/unoobj/notesuno.cxx
+++ b/sc/source/ui/unoobj/notesuno.cxx
@@ -220,14 +220,14 @@ rtl::OUString SAL_CALL ScAnnotationObj::getAuthor() throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
const ScPostIt* pNote = ImplGetNote();
- return pNote ? pNote->GetAuthor() : EMPTY_STRING;
+ return pNote ? pNote->GetAuthor() : rtl::OUString();
}
rtl::OUString SAL_CALL ScAnnotationObj::getDate() throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
const ScPostIt* pNote = ImplGetNote();
- return pNote ? pNote->GetDate() : EMPTY_STRING;
+ return pNote ? pNote->GetDate() : rtl::OUString();
}
sal_Bool SAL_CALL ScAnnotationObj::getIsVisible() throw(uno::RuntimeException)
@@ -298,7 +298,7 @@ uno::Reference < drawing::XShape > ScAnnotationShapeObj::GetXShape()
{
if (!xShape.is())
if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos ) )
- if( SdrObject* pCaption = pNote->GetCaption() )
+ if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) )
xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY );
return xShape;
}
diff --git a/sc/source/ui/unoobj/scdetect.cxx b/sc/source/ui/unoobj/scdetect.cxx
index 1e735cc77866..1b17c2e130ac 100644
--- a/sc/source/ui/unoobj/scdetect.cxx
+++ b/sc/source/ui/unoobj/scdetect.cxx
@@ -356,7 +356,7 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter )
// error during storage creation means _here_ that the medium
// is broken, but we can not handle it in medium since unpossibility
// to create a storage does not _always_ means that the medium is broken
- aMedium.SetError( aMedium.GetLastStorageCreationState() );
+ aMedium.SetError( aMedium.GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
if ( xInteraction.is() )
{
OUString empty;
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
index dfb0f42702a8..e6e194d7eb75 100644
--- a/sc/source/ui/unoobj/tokenuno.cxx
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -51,17 +51,16 @@
#include "docsh.hxx"
#include "rangeseq.hxx"
#include "externalrefmgr.hxx"
-using namespace formula;
-using namespace com::sun::star;
+using namespace ::formula;
+using namespace ::com::sun::star;
-//------------------------------------------------------------------------
+// ============================================================================
const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
{
static SfxItemPropertyMapEntry aFormulaParserMap_Impl[] =
{
- {MAP_CHAR_LEN(SC_UNO_REFERENCEPOS), 0, &getCppuType((table::CellAddress*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_COMPILEFAP), 0, &getBooleanCppuType(), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_COMPILEENGLISH), 0, &getBooleanCppuType(), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_IGNORELEADING), 0, &getBooleanCppuType(), 0, 0 },
@@ -74,7 +73,7 @@ const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
SC_SIMPLE_SERVICE_INFO( ScFormulaParserObj, "ScFormulaParserObj", SC_SERVICENAME_FORMULAPARS )
-//------------------------------------------------------------------------
+// ============================================================================
ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) :
mpDocShell( pDocSh ),
@@ -135,7 +134,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
rCompiler.SetExternalLinks( maExternalLinks);
}
-uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( const rtl::OUString& aFormula )
+uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula(
+ const rtl::OUString& aFormula, const table::CellAddress& rReferencePos )
throw (uno::RuntimeException)
{
ScUnoGuard aGuard;
@@ -143,8 +143,10 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( co
if (mpDocShell)
{
+ ScAddress aRefPos( ScAddress::UNINITIALIZED );
+ ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
ScDocument* pDoc = mpDocShell->GetDocument();
- ScCompiler aCompiler( pDoc, maRefPos);
+ ScCompiler aCompiler( pDoc, aRefPos);
aCompiler.SetGrammar(pDoc->GetGrammar());
SetCompilerFlags( aCompiler );
@@ -156,7 +158,8 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( co
return aRet;
}
-rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( const uno::Sequence<sheet::FormulaToken>& aTokens )
+rtl::OUString SAL_CALL ScFormulaParserObj::printFormula(
+ const uno::Sequence<sheet::FormulaToken>& aTokens, const table::CellAddress& rReferencePos )
throw (uno::RuntimeException)
{
ScUnoGuard aGuard;
@@ -167,7 +170,9 @@ rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( const uno::Sequence<she
ScDocument* pDoc = mpDocShell->GetDocument();
ScTokenArray aCode;
(void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens );
- ScCompiler aCompiler( pDoc, maRefPos, aCode);
+ ScAddress aRefPos( ScAddress::UNINITIALIZED );
+ ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
+ ScCompiler aCompiler( pDoc, aRefPos, aCode);
aCompiler.SetGrammar(pDoc->GetGrammar());
SetCompilerFlags( aCompiler );
@@ -197,13 +202,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
{
ScUnoGuard aGuard;
String aString(aPropertyName);
- if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
- {
- table::CellAddress aAddress;
- aValue >>= aAddress;
- ScUnoConversion::FillScAddress( maRefPos, aAddress );
- } // if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
- else if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+ if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
{
aValue >>= mbCompileFAP;
}
@@ -218,7 +217,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
if (mxOpCodeMap.get() && mbEnglish != bOldEnglish)
{
ScDocument* pDoc = mpDocShell->GetDocument();
- ScCompiler aCompiler( pDoc, maRefPos);
+ ScCompiler aCompiler( pDoc, ScAddress());
aCompiler.SetGrammar(pDoc->GetGrammar());
mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
}
@@ -239,7 +238,7 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
if (aValue >>= maOpCodeMapping)
{
ScDocument* pDoc = mpDocShell->GetDocument();
- ScCompiler aCompiler( pDoc, maRefPos);
+ ScCompiler aCompiler( pDoc, ScAddress());
aCompiler.SetGrammar(pDoc->GetGrammar());
mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
}
@@ -262,13 +261,7 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
ScUnoGuard aGuard;
uno::Any aRet;
String aString(aPropertyName);
- if ( aString.EqualsAscii( SC_UNO_REFERENCEPOS ) )
- {
- table::CellAddress aAddress;
- ScUnoConversion::FillApiAddress( aAddress, maRefPos );
- aRet <<= aAddress;
- }
- else if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
+ if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
{
aRet <<= mbCompileFAP;
}
@@ -299,7 +292,7 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj )
-//------------------------------------------------------------------------
+// ============================================================================
void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
{
@@ -345,7 +338,7 @@ void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rR
bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc,
ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence )
{
- return rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager());
+ return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager());
}
// static
@@ -463,9 +456,13 @@ bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
return !bError;
}
-// -----------------------------------------------------------------------------
+
+// ============================================================================
+
ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)
: formula::FormulaOpCodeMapperObj(_pCompiler)
{
}
+// ============================================================================
+
diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx
index fa27b94a9956..c1af5ac9bb99 100644
--- a/sc/source/ui/unoobj/viewuno.cxx
+++ b/sc/source/ui/unoobj/viewuno.cxx
@@ -71,6 +71,7 @@
#include "gridwin.hxx"
#include <com/sun/star/view/DocumentZoomType.hpp>
#include "AccessibilityHints.hxx"
+#include <svx/sdrhittesthelper.hxx>
using namespace com::sun::star;
@@ -1169,7 +1170,7 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP
SdrView* pDrawView = GetViewShell()->GetSdrView();
- if (pDrawPage && pDrawView)
+ if (pDrawPage && pDrawView && pDrawView->GetSdrPageView())
{
Window* pActiveWin = pData->GetActiveWin();
Point aPos = pActiveWin->PixelToLogic(rPoint);
@@ -1183,7 +1184,7 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP
while (i < nCount && !bFound)
{
SdrObject* pObj = pDrawPage->GetObj(i);
- if (pObj && pObj->IsHit(aPos, nHitLog))
+ if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, nHitLog, *pDrawView->GetSdrPageView(), 0, false))
{
xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
bFound = sal_True;
diff --git a/sc/source/ui/unoobj/warnpassword.cxx b/sc/source/ui/unoobj/warnpassword.cxx
index 6453bcbd0de7..6b11ac7c6641 100644
--- a/sc/source/ui/unoobj/warnpassword.cxx
+++ b/sc/source/ui/unoobj/warnpassword.cxx
@@ -95,3 +95,4 @@ bool ScWarnPassword::WarningOnPassword( SfxMedium& rMedium )
}
return bReturn;
}
+
diff --git a/sc/source/ui/vba/vbacontrol.cxx b/sc/source/ui/vba/vbacontrol.cxx
index ddb4b39a91a5..eaf9365016ec 100644
--- a/sc/source/ui/vba/vbacontrol.cxx
+++ b/sc/source/ui/vba/vbacontrol.cxx
@@ -185,14 +185,15 @@ void SAL_CALL ScVbaControl::setEnabled( sal_Bool bVisible ) throw (uno::RuntimeE
sal_Bool SAL_CALL ScVbaControl::getVisible() throw (uno::RuntimeException)
{
- uno::Reference< awt::XWindow2 > xWindow2( getWindowPeer(), uno::UNO_QUERY_THROW );
- return xWindow2->isVisible();
+ sal_Bool bVisible = sal_False;
+ m_xProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableVisible" ) ) ) >>= bVisible;
+ return bVisible;
}
void SAL_CALL ScVbaControl::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException)
{
- uno::Reference< awt::XWindow2 > xWindow2( getWindowPeer(), uno::UNO_QUERY_THROW );
- xWindow2->setVisible( bVisible );
+ m_xProps->setPropertyValue
+ (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableVisible" ) ), uno::makeAny( bVisible ) );
}
double SAL_CALL ScVbaControl::getHeight() throw (uno::RuntimeException)
{
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index 5019167b4374..d1ac4504ce96 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -77,7 +77,10 @@
#include <com/sun/star/sheet/XCellRangeMovement.hpp>
#include <com/sun/star/sheet/XCellRangeData.hpp>
#include <com/sun/star/sheet/FormulaResult.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
#include <com/sun/star/sheet/TableFilterField.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
#include <com/sun/star/sheet/XSheetFilterable.hpp>
#include <com/sun/star/sheet/FilterConnection.hpp>
#include <com/sun/star/util/CellProtection.hpp>
@@ -4027,7 +4030,7 @@ void lcl_SetAllQueryForField( ScDocShell* pDocShell, SCCOLROW nField, sal_Int16
}
// Modifies sCriteria, and nOp depending on the value of sCriteria
-void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference< beans::XPropertySet >& xDescProps, sheet::TableFilterField& rFilterField )
+void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference< beans::XPropertySet >& xDescProps, sheet::TableFilterField2& rFilterField )
{
// #TODO make this more efficient and cycle through
// sCriteria1 character by character to pick up <,<>,=, * etc.
@@ -4047,10 +4050,10 @@ void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference<
if ( ( nPos = sCriteria1.indexOf( EQUALS ) ) == 0 )
{
if ( sCriteria1.getLength() == EQUALS.getLength() )
- rFilterField.Operator = sheet::FilterOperator_EMPTY;
+ rFilterField.Operator = sheet::FilterOperator2::EMPTY;
else
{
- rFilterField.Operator = sheet::FilterOperator_EQUAL;
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
sCriteria1 = sCriteria1.copy( EQUALS.getLength() );
sCriteria1 = VBAToRegexp( sCriteria1 );
// UseRegularExpressions
@@ -4062,10 +4065,10 @@ void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference<
else if ( ( nPos = sCriteria1.indexOf( NOTEQUALS ) ) == 0 )
{
if ( sCriteria1.getLength() == NOTEQUALS.getLength() )
- rFilterField.Operator = sheet::FilterOperator_NOT_EMPTY;
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EMPTY;
else
{
- rFilterField.Operator = sheet::FilterOperator_NOT_EQUAL;
+ rFilterField.Operator = sheet::FilterOperator2::NOT_EQUAL;
sCriteria1 = sCriteria1.copy( NOTEQUALS.getLength() );
sCriteria1 = VBAToRegexp( sCriteria1 );
// UseRegularExpressions
@@ -4079,12 +4082,12 @@ void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference<
if ( ( nPos = sCriteria1.indexOf( GREATERTHANEQUALS ) ) == 0 )
{
sCriteria1 = sCriteria1.copy( GREATERTHANEQUALS.getLength() );
- rFilterField.Operator = sheet::FilterOperator_GREATER_EQUAL;
+ rFilterField.Operator = sheet::FilterOperator2::GREATER_EQUAL;
}
else
{
sCriteria1 = sCriteria1.copy( GREATERTHAN.getLength() );
- rFilterField.Operator = sheet::FilterOperator_GREATER;
+ rFilterField.Operator = sheet::FilterOperator2::GREATER;
}
}
@@ -4094,17 +4097,17 @@ void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference<
if ( ( nPos = sCriteria1.indexOf( LESSTHANEQUALS ) ) == 0 )
{
sCriteria1 = sCriteria1.copy( LESSTHANEQUALS.getLength() );
- rFilterField.Operator = sheet::FilterOperator_LESS_EQUAL;
+ rFilterField.Operator = sheet::FilterOperator2::LESS_EQUAL;
}
else
{
sCriteria1 = sCriteria1.copy( LESSTHAN.getLength() );
- rFilterField.Operator = sheet::FilterOperator_LESS;
+ rFilterField.Operator = sheet::FilterOperator2::LESS;
}
}
else
- rFilterField.Operator = sheet::FilterOperator_EQUAL;
+ rFilterField.Operator = sheet::FilterOperator2::EQUAL;
if ( bIsNumeric )
{
@@ -4213,13 +4216,16 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
bool bAll = false;;
if ( ( Field >>= nField ) )
{
- uno::Sequence< sheet::TableFilterField > sTabFilts;
- uno::Reference< sheet::XSheetFilterDescriptor > xDesc = xDataBaseRange->getFilterDescriptor();
- uno::Reference< beans::XPropertySet > xDescProps( xDesc, uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xDesc(
+ xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if ( xDesc.is() )
+ {
+ uno::Sequence< sheet::TableFilterField2 > sTabFilts;
+ uno::Reference< beans::XPropertySet > xDescProps( xDesc, uno::UNO_QUERY_THROW );
if ( Criteria1.hasValue() )
{
sTabFilts.realloc( 1 );
- sTabFilts[0].Operator = sheet::FilterOperator_EQUAL;// sensible default
+ sTabFilts[0].Operator = sheet::FilterOperator2::EQUAL;// sensible default
if ( !bCritHasNumericValue )
{
Criteria1 >>= sCriteria1;
@@ -4252,16 +4258,16 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
switch ( nOperator )
{
case excel::XlAutoFilterOperator::xlBottom10Items:
- sTabFilts[0].Operator = sheet::FilterOperator_BOTTOM_VALUES;
+ sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_VALUES;
break;
case excel::XlAutoFilterOperator::xlBottom10Percent:
- sTabFilts[0].Operator = sheet::FilterOperator_BOTTOM_PERCENT;
+ sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_PERCENT;
break;
case excel::XlAutoFilterOperator::xlTop10Items:
- sTabFilts[0].Operator = sheet::FilterOperator_TOP_VALUES;
+ sTabFilts[0].Operator = sheet::FilterOperator2::TOP_VALUES;
break;
case excel::XlAutoFilterOperator::xlTop10Percent:
- sTabFilts[0].Operator = sheet::FilterOperator_TOP_PERCENT;
+ sTabFilts[0].Operator = sheet::FilterOperator2::TOP_PERCENT;
break;
case excel::XlAutoFilterOperator::xlOr:
nConn = sheet::FilterConnection_OR;
@@ -4300,12 +4306,12 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
{
Criteria2 >>= sTabFilts[1].NumericValue;
sTabFilts[1].IsNumeric = sal_True;
- sTabFilts[1].Operator = sheet::FilterOperator_EQUAL;
+ sTabFilts[1].Operator = sheet::FilterOperator2::EQUAL;
}
}
}
- xDesc->setFilterFields( sTabFilts );
+ xDesc->setFilterFields2( sTabFilts );
if ( !bAll )
{
xDataBaseRange->refresh();
@@ -4313,6 +4319,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
else
// was 0 based now seems to be 1
lcl_SetAllQueryForField( pShell, nField, nSheet );
+ }
}
else
{
@@ -4333,7 +4340,10 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
lcl_SetAllQueryForField( pShell, rEntry.nField, nSheet );
}
// remove exising filters
- xDataBaseRange->getFilterDescriptor()->setFilterFields( uno::Sequence< sheet::TableFilterField >() );
+ uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
+ xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
+ if( xSheetFilterDescriptor.is() )
+ xSheetFilterDescriptor->setFilterFields2( uno::Sequence< sheet::TableFilterField2 >() );
}
xDBRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ), uno::Any(!bHasAuto) );
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 6446d023fe9b..e5bb702402d8 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -103,6 +103,7 @@
#include "dpsave.hxx"
#include "dpgroup.hxx" // for ScDPNumGroupInfo
#include "spellparam.hxx"
+#include "postit.hxx"
#include "globstr.hrc"
#include "scui_def.hxx" //CHINA001
@@ -1708,32 +1709,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
break;
case SID_TOGGLE_REL:
- {
- BOOL bOk = FALSE;
- SCCOL nCol = GetViewData()->GetCurX();
- SCROW nRow = GetViewData()->GetCurY();
- SCTAB nTab = GetViewData()->GetTabNo();
- ScDocument* pDoc = GetViewData()->GetDocument();
- CellType eType;
- pDoc->GetCellType( nCol, nRow, nTab, eType );
- if (eType == CELLTYPE_FORMULA)
- {
- String aOld;
- pDoc->GetFormula( nCol, nRow, nTab, aOld );
- xub_StrLen nLen = aOld.Len();
- ScRefFinder aFinder( aOld, pDoc );
- aFinder.ToggleRel( 0, nLen );
- if (aFinder.GetFound())
- {
- String aNew = aFinder.GetText();
- pTabViewShell->EnterData( nCol, nRow, nTab, aNew );
- pTabViewShell->UpdateInputHandler();
- bOk = TRUE;
- }
- }
- if (!bOk)
- pTabViewShell->ErrorMessage(STR_ERR_NOREF);
- }
+ pTabViewShell->DoRefConversion();
break;
case SID_DEC_INDENT:
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index 564053a937ef..eabf33f3defc 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -138,6 +138,77 @@ bool lcl_GetTextToColumnsRange( const ScViewData* pData, ScRange& rRange )
return bRet;
}
+BOOL lcl_GetSortParam( const ScViewData* pData, ScSortParam& rSortParam )
+{
+ ScTabViewShell* pTabViewShell = pData->GetViewShell();
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScDocument* pDoc = pData->GetDocument();
+ SCTAB nTab = pData->GetTabNo();
+ ScDirection eFillDir = DIR_TOP;
+ BOOL bSort = TRUE;
+ ScRange aExternalRange;
+
+ if( rSortParam.nCol1 != rSortParam.nCol2 )
+ eFillDir = DIR_LEFT;
+ if( rSortParam.nRow1 != rSortParam.nRow2 )
+ eFillDir = DIR_TOP;
+
+ SCSIZE nCount = pDoc->GetEmptyLinesInBlock( rSortParam.nCol1, rSortParam.nRow1, nTab, rSortParam.nCol2, rSortParam.nRow2, nTab, eFillDir );
+
+ if( rSortParam.nRow2 == MAXROW )
+ aExternalRange = ScRange( rSortParam.nCol1,sal::static_int_cast<SCROW>( nCount ), nTab );
+ else
+ aExternalRange = ScRange( pData->GetCurX(), pData->GetCurY(), nTab );
+
+ SCROW nStartRow = aExternalRange.aStart.Row();
+ SCCOL nStartCol = aExternalRange.aStart.Col();
+ SCROW nEndRow = aExternalRange.aEnd.Row();
+ SCCOL nEndCol = aExternalRange.aEnd.Col();
+ pDoc->GetDataArea( aExternalRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow, FALSE );
+ aExternalRange.aStart.SetRow( nStartRow );
+ aExternalRange.aStart.SetCol( nStartCol );
+ aExternalRange.aEnd.SetRow( nEndRow );
+ aExternalRange.aEnd.SetCol( nEndCol );
+
+ if(( rSortParam.nCol1 == rSortParam.nCol2 && aExternalRange.aStart.Col() != aExternalRange.aEnd.Col() ) ||
+ ( rSortParam.nRow1 == rSortParam.nRow2 && aExternalRange.aStart.Row() != aExternalRange.aEnd.Row() ) )
+ {
+ USHORT nFmt = SCA_VALID;
+ String aExtendStr,aCurrentStr;
+
+ pTabViewShell->AddHighlightRange( aExternalRange,Color( COL_LIGHTBLUE ) );
+ ScRange rExtendRange( aExternalRange.aStart.Col(), aExternalRange.aStart.Row(), nTab, aExternalRange.aEnd.Col(), aExternalRange.aEnd.Row(), nTab );
+ rExtendRange.Format( aExtendStr, nFmt, pDoc );
+
+ ScRange rCurrentRange( rSortParam.nCol1, rSortParam.nRow1, nTab, rSortParam.nCol2, rSortParam.nRow2, nTab );
+ rCurrentRange.Format( aCurrentStr, nFmt, pDoc );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ VclAbstractDialog* pWarningDlg = pFact->CreateScSortWarningDlg( pTabViewShell->GetDialogParent(),aExtendStr,aCurrentStr,RID_SCDLG_SORT_WARNING );
+ DBG_ASSERT(pWarningDlg, "Dialog create fail!");//CHINA001
+ short bResult = pWarningDlg->Execute();
+ if( bResult == BTN_EXTEND_RANGE || bResult == BTN_CURRENT_SELECTION )
+ {
+ if( bResult == BTN_EXTEND_RANGE )
+ {
+ pTabViewShell->MarkRange( aExternalRange, FALSE );
+ pDBData->SetArea( nTab, aExternalRange.aStart.Col(), aExternalRange.aStart.Row(), aExternalRange.aEnd.Col(), aExternalRange.aEnd.Row() );
+ }
+ }
+ else
+ {
+ bSort = FALSE;
+ pData->GetDocShell()->CancelAutoDBRange();
+ }
+
+ delete pWarningDlg;
+ pTabViewShell->ClearHighlightRanges();
+ }
+ return bSort;
+}
+
void ScCellShell::ExecuteDB( SfxRequest& rReq )
{
ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
@@ -332,40 +403,47 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
case SID_SORT_DESCENDING:
case SID_SORT_ASCENDING:
{
- SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+ //#i60401 ux-ctest: Calc does not support all users' strategies regarding sorting data
+ //the patch comes from maoyg
ScSortParam aSortParam;
ScDBData* pDBData = pTabViewShell->GetDBData();
- SCCOL nCol = GetViewData()->GetCurX();
- SCCOL nTab = GetViewData()->GetTabNo();
- ScDocument* pDoc = GetViewData()->GetDocument();
- BOOL bHasHeader = FALSE;
+ ScViewData* pData = GetViewData();
pDBData->GetSortParam( aSortParam );
- bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, nTab );
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCCOL nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
- if( nCol < aSortParam.nCol1 )
- nCol = aSortParam.nCol1;
- else if( nCol > aSortParam.nCol2 )
- nCol = aSortParam.nCol2;
+ pDBData->GetSortParam( aSortParam );
+ BOOL bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, nTab );
- aSortParam.bHasHeader = bHasHeader;
- aSortParam.bByRow = TRUE;
- aSortParam.bCaseSens = FALSE;
- aSortParam.bIncludePattern = TRUE;
- aSortParam.bInplace = TRUE;
- aSortParam.bDoSort[0] = TRUE;
- aSortParam.nField[0] = nCol;
- aSortParam.bAscending[0] = (nSlotId == SID_SORT_ASCENDING);
+ if( nCol < aSortParam.nCol1 )
+ nCol = aSortParam.nCol1;
+ else if( nCol > aSortParam.nCol2 )
+ nCol = aSortParam.nCol2;
- for ( USHORT i=1; i<MAXSORT; i++ )
- aSortParam.bDoSort[i] = FALSE;
+ aSortParam.bHasHeader = bHasHeader;
+ aSortParam.bByRow = TRUE;
+ aSortParam.bCaseSens = FALSE;
+ aSortParam.bIncludePattern = TRUE;
+ aSortParam.bInplace = TRUE;
+ aSortParam.bDoSort[0] = TRUE;
+ aSortParam.nField[0] = nCol;
+ aSortParam.bAscending[0] = (nSlotId == SID_SORT_ASCENDING);
- aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
+ for ( USHORT i=1; i<MAXSORT; i++ )
+ aSortParam.bDoSort[i] = FALSE;
- pTabViewShell->UISort( aSortParam ); // Teilergebnisse bei Bedarf neu
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
- rReq.Done();
+ pTabViewShell->UISort( aSortParam ); // Teilergebnisse bei Bedarf neu
+
+ rReq.Done();
+ }
}
break;
@@ -373,141 +451,155 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
{
const SfxItemSet* pArgs = rReq.GetArgs();
+ //#i60401 ux-ctest: Calc does not support all users' strategies regarding sorting data
+ //the patch comes from maoyg
+
if ( pArgs ) // Basic
{
ScSortParam aSortParam;
- ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
pDBData->GetSortParam( aSortParam );
- aSortParam.bInplace = TRUE; // von Basic immer
-
- const SfxPoolItem* pItem;
- if ( pArgs->GetItemState( SID_SORT_BYROW, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bByRow = ((const SfxBoolItem*)pItem)->GetValue();
- if ( pArgs->GetItemState( SID_SORT_HASHEADER, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bHasHeader = ((const SfxBoolItem*)pItem)->GetValue();
- if ( pArgs->GetItemState( SID_SORT_CASESENS, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bCaseSens = ((const SfxBoolItem*)pItem)->GetValue();
- if ( pArgs->GetItemState( SID_SORT_ATTRIBS, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bIncludePattern = ((const SfxBoolItem*)pItem)->GetValue();
- if ( pArgs->GetItemState( SID_SORT_USERDEF, TRUE, &pItem ) == SFX_ITEM_SET )
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
{
- USHORT nUserIndex = ((const SfxUInt16Item*)pItem)->GetValue();
- aSortParam.bUserDef = ( nUserIndex != 0 );
- if ( nUserIndex )
- aSortParam.nUserIndex = nUserIndex - 1; // Basic: 1-basiert
- }
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ pDBData->GetSortParam( aSortParam );
+ BOOL bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, pData->GetTabNo() );
+ if( bHasHeader )
+ aSortParam.bHasHeader = bHasHeader;
+
+ aSortParam.bInplace = TRUE; // von Basic immer
+
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_SORT_BYROW, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bByRow = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_HASHEADER, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bHasHeader = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_CASESENS, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bCaseSens = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_ATTRIBS, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bIncludePattern = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_USERDEF, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ USHORT nUserIndex = ((const SfxUInt16Item*)pItem)->GetValue();
+ aSortParam.bUserDef = ( nUserIndex != 0 );
+ if ( nUserIndex )
+ aSortParam.nUserIndex = nUserIndex - 1; // Basic: 1-basiert
+ }
- SCCOLROW nField0 = 0;
- if ( pArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
- nField0 = ((const SfxInt32Item*)pItem)->GetValue();
- aSortParam.bDoSort[0] = ( nField0 != 0 );
- aSortParam.nField[0] = nField0 > 0 ? (nField0-1) : 0;
- if ( pArgs->GetItemState( FN_PARAM_2, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bAscending[0] = ((const SfxBoolItem*)pItem)->GetValue();
- SCCOLROW nField1 = 0;
- if ( pArgs->GetItemState( FN_PARAM_3, TRUE, &pItem ) == SFX_ITEM_SET )
- nField1 = ((const SfxInt32Item*)pItem)->GetValue();
- aSortParam.bDoSort[1] = ( nField1 != 0 );
- aSortParam.nField[1] = nField1 > 0 ? (nField1-1) : 0;
- if ( pArgs->GetItemState( FN_PARAM_4, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bAscending[1] = ((const SfxBoolItem*)pItem)->GetValue();
- SCCOLROW nField2 = 0;
- if ( pArgs->GetItemState( FN_PARAM_5, TRUE, &pItem ) == SFX_ITEM_SET )
- nField2 = ((const SfxInt32Item*)pItem)->GetValue();
- aSortParam.bDoSort[2] = ( nField2 != 0 );
- aSortParam.nField[2] = nField2 > 0 ? (nField2-1) : 0;
- if ( pArgs->GetItemState( FN_PARAM_6, TRUE, &pItem ) == SFX_ITEM_SET )
- aSortParam.bAscending[2] = ((const SfxBoolItem*)pItem)->GetValue();
-
- // Teilergebnisse bei Bedarf neu
- pTabViewShell->UISort( aSortParam );
- rReq.Done();
+ SCCOLROW nField0 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
+ nField0 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[0] = ( nField0 != 0 );
+ aSortParam.nField[0] = nField0 > 0 ? (nField0-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_2, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[0] = ((const SfxBoolItem*)pItem)->GetValue();
+ SCCOLROW nField1 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_3, TRUE, &pItem ) == SFX_ITEM_SET )
+ nField1 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[1] = ( nField1 != 0 );
+ aSortParam.nField[1] = nField1 > 0 ? (nField1-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_4, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[1] = ((const SfxBoolItem*)pItem)->GetValue();
+ SCCOLROW nField2 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_5, TRUE, &pItem ) == SFX_ITEM_SET )
+ nField2 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[2] = ( nField2 != 0 );
+ aSortParam.nField[2] = nField2 > 0 ? (nField2-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_6, TRUE, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[2] = ((const SfxBoolItem*)pItem)->GetValue();
+
+ // Teilergebnisse bei Bedarf neu
+ pTabViewShell->UISort( aSortParam );
+ rReq.Done();
+ }
}
else
{
- //CHINA001 ScSortDlg* pDlg = NULL;
- SfxAbstractTabDialog* pDlg = NULL;
ScSortParam aSortParam;
- SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
- ScDBData* pDBData = pTabViewShell->GetDBData();
pDBData->GetSortParam( aSortParam );
- aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
- //CHINA001 pDlg = new ScSortDlg( pTabViewShell->GetDialogParent(), &aArgSet );
- ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
- DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxAbstractTabDialog* pDlg = NULL;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
- pDlg = pFact->CreateScSortDlg( pTabViewShell->GetDialogParent(), &aArgSet, RID_SCDLG_SORT );
- DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
- pDlg->SetCurPageId(1);
+ pDBData->GetSortParam( aSortParam );
+ BOOL bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, pData->GetTabNo() );
+ if( bHasHeader )
+ aSortParam.bHasHeader = bHasHeader;
- if ( pDlg->Execute() == RET_OK )
- {
- const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
- const ScSortParam& rOutParam = ((const ScSortItem&)
- pOutSet->Get( SCITEM_SORTDATA )).GetSortData();
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
- // Teilergebnisse bei Bedarf neu
- pTabViewShell->UISort( rOutParam );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScSortDlg( pTabViewShell->GetDialogParent(), &aArgSet, RID_SCDLG_SORT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetCurPageId(1);
- if ( rOutParam.bInplace )
+ if ( pDlg->Execute() == RET_OK )
{
- rReq.AppendItem( SfxBoolItem( SID_SORT_BYROW,
- rOutParam.bByRow ) );
- rReq.AppendItem( SfxBoolItem( SID_SORT_HASHEADER,
- rOutParam.bHasHeader ) );
- rReq.AppendItem( SfxBoolItem( SID_SORT_CASESENS,
- rOutParam.bCaseSens ) );
- rReq.AppendItem( SfxBoolItem( SID_SORT_ATTRIBS,
- rOutParam.bIncludePattern ) );
- USHORT nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 ) : 0;
- rReq.AppendItem( SfxUInt16Item( SID_SORT_USERDEF, nUser ) );
- if ( rOutParam.bDoSort[0] )
- {
- rReq.AppendItem( SfxInt32Item( FN_PARAM_1,
- rOutParam.nField[0] + 1 ) );
- rReq.AppendItem( SfxBoolItem( FN_PARAM_2,
- rOutParam.bAscending[0] ) );
- }
- if ( rOutParam.bDoSort[1] )
- {
- rReq.AppendItem( SfxInt32Item( FN_PARAM_3,
- rOutParam.nField[1] + 1 ) );
- rReq.AppendItem( SfxBoolItem( FN_PARAM_4,
- rOutParam.bAscending[1] ) );
- }
- if ( rOutParam.bDoSort[2] )
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ const ScSortParam& rOutParam = ((const ScSortItem&)
+ pOutSet->Get( SCITEM_SORTDATA )).GetSortData();
+
+ // Teilergebnisse bei Bedarf neu
+ pTabViewShell->UISort( rOutParam );
+
+ if ( rOutParam.bInplace )
{
- rReq.AppendItem( SfxInt32Item( FN_PARAM_5,
- rOutParam.nField[2] + 1 ) );
- rReq.AppendItem( SfxBoolItem( FN_PARAM_6,
- rOutParam.bAscending[2] ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_BYROW,
+ rOutParam.bByRow ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_HASHEADER,
+ rOutParam.bHasHeader ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_CASESENS,
+ rOutParam.bCaseSens ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_ATTRIBS,
+ rOutParam.bIncludePattern ) );
+ USHORT nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 ) : 0;
+ rReq.AppendItem( SfxUInt16Item( SID_SORT_USERDEF, nUser ) );
+ if ( rOutParam.bDoSort[0] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_1,
+ rOutParam.nField[0] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2,
+ rOutParam.bAscending[0] ) );
+ }
+ if ( rOutParam.bDoSort[1] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_3,
+ rOutParam.nField[1] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_4,
+ rOutParam.bAscending[1] ) );
+ }
+ if ( rOutParam.bDoSort[2] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_5,
+ rOutParam.nField[2] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_6,
+ rOutParam.bAscending[2] ) );
+ }
}
+
+ rReq.Done();
}
+ else
+ GetViewData()->GetDocShell()->CancelAutoDBRange();
- rReq.Done();
+ delete pDlg;
}
- else
- GetViewData()->GetDocShell()->CancelAutoDBRange();
-
- delete pDlg;
}
}
break;
-/*
- {
-
- USHORT nId = ScPivotLayoutWrapper::GetChildWindowId();
- SfxChildWindow* pWnd = pSfxApp->GetChildWindow( nId );
-
- pScMod->SetRefDialog( nId, pWnd ? FALSE : TRUE );
-
- }
- break;
-*/
-
case SID_FILTER:
{
const SfxItemSet* pArgs = rReq.GetArgs();
@@ -1242,6 +1334,10 @@ void __EXPORT ScCellShell::GetDBState( SfxItemSet& rSet )
{
rSet.DisableItem( nWhich );
}
+ else if (pDoc->GetDPAtBlock(aDummy))
+ {
+ rSet.DisableItem( nWhich );
+ }
else
rSet.Put( SfxBoolItem( nWhich, bAutoFilter ) );
}
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index 4bb33a4c7855..dd79bb52a112 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -950,16 +950,12 @@ void ScCellShell::Execute( SfxRequest& rReq )
DBG_ERROR("Execute von InputLine-Status");
break;
-
case SID_STATUS_DOCPOS:
- {
- //! Navigator an-/ausschalten (wie im Writer) ???
- //!pViewData->GetDispatcher().Execute( SID_NAVIGATOR,
- //! SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
- }
+ // Launch navigator.
+ GetViewData()->GetDispatcher().Execute(
+ SID_NAVIGATOR, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
break;
-
case SID_MARKAREA:
// called from Basic at the hidden view to select a range in the visible view
DBG_ERROR("old slot SID_MARKAREA");
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 8dcb47c927a2..36667ee43c0f 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -1898,7 +1898,13 @@ void ScDBFunc::RepeatDB( BOOL bRecord )
pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben
ScRange aAdvSource;
if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ {
+ pDoc->CreateQueryParam(
+ aAdvSource.aStart.Col(), aAdvSource.aStart.Row(),
+ aAdvSource.aEnd.Col(), aAdvSource.aEnd.Row(),
+ aAdvSource.aStart.Tab(), aQueryParam );
Query( aQueryParam, &aAdvSource, FALSE );
+ }
else
Query( aQueryParam, NULL, FALSE );
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 5591a2a496be..5397377b69cc 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -119,6 +119,8 @@
#include "drwlayer.hxx"
#include "attrib.hxx"
#include "validat.hxx"
+#include "tabprotection.hxx"
+#include "postit.hxx"
// #114409#
#include <vcl/salbtype.hxx> // FRound
@@ -128,6 +130,11 @@
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <vcl/svapp.hxx>
+#include <drawinglayer/primitive2d/invertprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
using namespace com::sun::star;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
@@ -1139,6 +1146,13 @@ void ScGridWindow::ExecFilter( ULONG nSel,
if (SC_AUTOFILTER_CUSTOM == nSel)
{
+ SCTAB nAreaTab;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow );
+ pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab));
pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ??
pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
}
@@ -2020,8 +2034,9 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
Point aPos = rMEvt.GetPosPixel();
SCsCOL nPosX;
SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
- ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, pViewData->GetTabNo() );
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
{
ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
@@ -2063,16 +2078,34 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
return;
}
- // edit cell contents
- pViewData->GetViewShell()->UpdateInputHandler();
- pScMod->SetInputMode( SC_INPUT_TABLE );
- if (pViewData->HasEditView(eWhich))
+ // Check for cell protection attribute.
+ ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
+ bool bEditAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ bEditAllowed = false;
+ else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ bEditAllowed = false;
+ }
+
+ if ( bEditAllowed )
{
- // Text-Cursor gleich an die geklickte Stelle setzen
- EditView* pEditView = pViewData->GetEditView( eWhich );
- MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
- pEditView->MouseButtonDown( aEditEvt );
- pEditView->MouseButtonUp( aEditEvt );
+ // edit cell contents
+ pViewData->GetViewShell()->UpdateInputHandler();
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ if (pViewData->HasEditView(eWhich))
+ {
+ // Text-Cursor gleich an die geklickte Stelle setzen
+ EditView* pEditView = pViewData->GetEditView( eWhich );
+ MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+ pEditView->MouseButtonDown( aEditEvt );
+ pEditView->MouseButtonUp( aEditEvt );
+ }
}
return;
}
@@ -5662,112 +5695,107 @@ namespace sdr
mePaintType( eType ),
maRectangles( rRects )
{
+ // no AA for selection overlays
+ allowAntiAliase(false);
}
OverlayObjectCell::~OverlayObjectCell()
{
}
- void OverlayObjectCell::drawGeometry(OutputDevice& rOutputDevice)
+ drawinglayer::primitive2d::Primitive2DSequence OverlayObjectCell::createOverlayObjectPrimitive2DSequence()
{
- // safe original AA and switch off for selection
- const sal_uInt16 nOriginalAA(rOutputDevice.GetAntialiasing());
- rOutputDevice.SetAntialiasing(0);
-
- // set colors
- rOutputDevice.SetLineColor();
- rOutputDevice.SetFillColor(getBaseColor());
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+ const basegfx::BColor aRGBColor(getBaseColor().getBColor());
+ const sal_uInt32 nCount(maRectangles.size());
- if ( mePaintType == SC_OVERLAY_BORDER_TRANSPARENT )
- {
- // to draw the border, all rectangles have to be collected into a PolyPolygon
-
- PolyPolygon aPolyPoly;
- sal_uInt32 nRectCount = maRectangles.size();
- for(sal_uInt32 nRect=0; nRect < nRectCount; ++nRect)
- {
- const basegfx::B2DRange& rRange(maRectangles[nRect]);
- Rectangle aRectangle(FRound(rRange.getMinX()), FRound(rRange.getMinY()), FRound(rRange.getMaxX()), FRound(rRange.getMaxY()));
- if ( nRectCount == 1 || nRect+1 < nRectCount )
- {
- // simply add for all except the last rect
- aPolyPoly.Insert( Polygon( aRectangle ) );
- }
- else
- {
- PolyPolygon aTemp( aPolyPoly );
- aTemp.GetUnion( PolyPolygon( Polygon( aRectangle ) ), aPolyPoly );
- }
- }
-
- rOutputDevice.DrawTransparent(aPolyPoly, 75);
-
- rOutputDevice.SetLineColor(getBaseColor());
- rOutputDevice.SetFillColor();
-
- rOutputDevice.DrawPolyPolygon(aPolyPoly);
- }
- else
+ if(nCount)
{
- if ( mePaintType == SC_OVERLAY_INVERT )
+ // create fill primities for all rectangles
+ // These ranges are meant as rectangles, so it is not sufficient to replace them
+ // using the derived polygon. That would leave out the bottom and right lines
+ // in a discrete width/height due to polygon painting conventions of leaving off those.
+ // To solve, it is either possible to create a view-dependent rectangle primitive
+ // handling this internally or to additionally create a hairline primitive to
+ // cover these areas (which i will do here)
+ const bool bIsTransparent(SC_OVERLAY_BORDER_TRANSPARENT == mePaintType);
+ aRetval.realloc(nCount * 2);
+
+ for(sal_uInt32 a(0);a < nCount; a++)
{
- rOutputDevice.Push();
- rOutputDevice.SetRasterOp( ROP_XOR );
- rOutputDevice.SetFillColor( COL_WHITE );
+ const basegfx::B2DRange& rRange(maRectangles[a]);
+ const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(rRange));
+
+ aRetval[a * 2] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ aRGBColor));
+ aRetval[(a * 2) + 1] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ aRGBColor));
}
- for(sal_uInt32 a(0L);a < maRectangles.size(); a++)
+ if(SC_OVERLAY_INVERT == mePaintType)
{
- const basegfx::B2DRange& rRange(maRectangles[a]);
- const Rectangle aRectangle(FRound(rRange.getMinX()), FRound(rRange.getMinY()), FRound(rRange.getMaxX()), FRound(rRange.getMaxY()));
+ // embed all in invert primitive
+ const drawinglayer::primitive2d::Primitive2DReference aInvert(
+ new drawinglayer::primitive2d::InvertPrimitive2D(
+ aRetval));
- switch(mePaintType)
- {
- case SC_OVERLAY_INVERT :
- {
- rOutputDevice.DrawRect( aRectangle );
- break;
- }
- case SC_OVERLAY_SOLID :
- {
- rOutputDevice.DrawRect(aRectangle);
- break;
- }
- default:
- {
- // SC_OVERLAY_BORDER_TRANSPARENT is handled separately
- }
- }
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1);
}
-
- if ( mePaintType == SC_OVERLAY_INVERT )
+ else if(bIsTransparent)
{
- rOutputDevice.Pop();
+ // embed all rectangles in 75% transparent paint
+ const drawinglayer::primitive2d::Primitive2DReference aUnifiedAlpha(
+ new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D(
+ aRetval,
+ 0.75));
+
+ // prepare merged PolyPoygon selection outline
+ const basegfx::B2DPolyPolygon aPolyPolygon(impGetOverlayPolyPolygon());
+ const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ aPolyPolygon,
+ aRGBColor));
+
+ // add both to result
+ aRetval.realloc(2);
+ aRetval[0] = aUnifiedAlpha;
+ aRetval[1] = aSelectionOutline;
}
}
- // restore original AA
- rOutputDevice.SetAntialiasing(nOriginalAA);
+ return aRetval;
}
- void OverlayObjectCell::createBaseRange(OutputDevice& /* rOutputDevice */)
+ basegfx::B2DPolyPolygon OverlayObjectCell::impGetOverlayPolyPolygon() const
{
- maBaseRange.reset();
+ PolyPolygon aPolyPoly;
+ const sal_uInt32 nRectCount(maRectangles.size());
- for(sal_uInt32 a(0L); a < maRectangles.size(); a++)
+ for(sal_uInt32 nRect(0); nRect < nRectCount; ++nRect)
{
- maBaseRange.expand(maRectangles[a]);
- }
- }
+ const basegfx::B2DRange& rRange(maRectangles[nRect]);
+ const Rectangle aRectangle(
+ FRound(rRange.getMinX()), FRound(rRange.getMinY()),
+ FRound(rRange.getMaxX()), FRound(rRange.getMaxY()));
- void OverlayObjectCell::transform(const basegfx::B2DHomMatrix& rMatrix)
- {
- for(sal_uInt32 a(0L); a < maRectangles.size(); a++)
- {
- maRectangles[a].transform(rMatrix);
+ if ( nRectCount == 1 || nRect+1 < nRectCount )
+ {
+ // simply add for all except the last rect
+ aPolyPoly.Insert( Polygon( aRectangle ) );
+ }
+ else
+ {
+ PolyPolygon aTemp( aPolyPoly );
+ aTemp.GetUnion( PolyPolygon( Polygon( aRectangle ) ), aPolyPoly );
+ }
}
- }
+ return aPolyPoly.getB2DPolyPolygon();
+ }
} // end of namespace overlay
} // end of namespace sdr
diff --git a/sc/source/ui/view/gridwin5.cxx b/sc/source/ui/view/gridwin5.cxx
index 8739ee2b0b91..f3d5b2781607 100644
--- a/sc/source/ui/view/gridwin5.cxx
+++ b/sc/source/ui/view/gridwin5.cxx
@@ -338,12 +338,12 @@ void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
SdrObject* pObj = 0;
SdrPageView* pPV = 0;
Point aMDPos = PixelToLogic( aPosPixel );
- if ( pDrView->PickObj(aMDPos, pObj, pPV, SDRSEARCH_ALSOONMASTER) )
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
{
if ( pObj->IsGroupObject() )
{
SdrObject* pHit = 0;
- if ( pDrView->PickObj(aMDPos, pHit, pPV, SDRSEARCH_DEEP ) )
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
pObj = pHit;
}
#ifdef ISSUE66550_HLINK_FOR_SHAPES
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index dd76058756a1..e41bd4941d9c 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1358,13 +1358,11 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic )
}
if (bDoCell && !bNeedEdit)
{
- BOOL bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
- if ( bFormulaCell )
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
lcl_CreateInterpretProgress( bProgress, pDoc, (ScFormulaCell*)pCell );
if ( aVars.SetText(pCell) )
pOldPattern = NULL;
- bNeedEdit = aVars.HasEditCharacters() ||
- (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
+ bNeedEdit = aVars.HasEditCharacters();
}
if (bDoCell && !bNeedEdit)
{
diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx
index 2906440d7e5a..b94837fc1793 100644
--- a/sc/source/ui/view/preview.cxx
+++ b/sc/source/ui/view/preview.cxx
@@ -244,6 +244,10 @@ void ScPreview::CalcPages( SCTAB /*nToWhichTab*/ )
nTabsTested = 0;
}
+ // update all pending row heights with a single progress bar,
+ // instead of a separate progress for each sheet from ScPrintFunc
+ pDocShell->UpdatePendingRowHeights( nAnz-1, true );
+
// PrintOptions is passed to PrintFunc for SkipEmpty flag,
// but always all sheets are used (there is no selected sheet)
ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index 4324b610dd0b..b7b8b9fbadf6 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -185,6 +185,7 @@ long lcl_LineTotal(const SvxBorderLine* pLine)
void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
{
+ pDocShell->UpdatePendingRowHeights( nPrintTab );
pDoc = pDocShell->GetDocument();
SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
@@ -886,7 +887,7 @@ void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
if ( !aPageSize.Width() || !aPageSize.Height() )
{
DBG_ERROR("PageSize Null ?!?!?");
- aPageSize = SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 );
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
}
pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
@@ -2677,7 +2678,7 @@ void ScPrintFunc::ApplyPrintSettings()
aEnumSize.Width() = aEnumSize.Height();
aEnumSize.Height() = nTemp;
}
- Paper ePaper = SvxPaperInfo::GetSvPaper( aEnumSize, MAP_TWIP, TRUE );
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, TRUE );
USHORT nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
pPrinter->SetPaper( ePaper );
diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx
index 15b4329fb00e..e6b4a3d0c20e 100644
--- a/sc/source/ui/view/scextopt.cxx
+++ b/sc/source/ui/view/scextopt.cxx
@@ -42,9 +42,7 @@ ScExtDocSettings::ScExtDocSettings() :
maOleSize( ScAddress::INITIALIZE_INVALID ),
mfTabBarWidth( -1.0 ),
mnLinkCnt( 0 ),
- mnDisplTab( 0 ),
- mbWinProtected( false ),
- mbEncrypted( false )
+ mnDisplTab( 0 )
{
}
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx
index 288b50daed19..b8d0da840db7 100644
--- a/sc/source/ui/view/select.cxx
+++ b/sc/source/ui/view/select.cxx
@@ -47,6 +47,7 @@
//#include "dataobj.hxx"
#include "transobj.hxx"
#include "docsh.hxx"
+#include "tabprotection.hxx"
extern USHORT nScFillModeMouseModifier; // global.cxx
@@ -322,6 +323,26 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
{
ScTabView* pView = pViewData->GetView();
SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ if (nPosX < 0 || nPosY < 0)
+ return false;
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return FALSE;
+
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ // Don't select this cell!
+ return FALSE;
+ }
+
ScModule* pScMod = SC_MOD();
ScTabViewShell* pViewShell = pViewData->GetViewShell();
bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
@@ -375,7 +396,6 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
ScRange aDelRange;
BOOL bOldDelMark = pViewData->GetDelMark( aDelRange );
- ScDocument* pDoc = pViewData->GetDocument();
if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX &&
nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY &&
@@ -511,7 +531,6 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
BYTE nMode = pViewData->GetFillMode();
if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB )
{
- ScDocument* pDoc = pViewData->GetDocument();
DBG_ASSERT( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" );
ScRange aRange;
pDoc->GetEmbedded( aRange);
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 1be33a37cd26..608658024d2b 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -79,6 +79,7 @@
#include "AccessibilityHints.hxx"
#include "rangeutl.hxx"
#include "client.hxx"
+#include "tabprotection.hxx"
#include <com/sun/star/chart2/data/HighlightedRange.hpp>
@@ -946,6 +947,17 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
ScDocument* pDoc = aViewData.GetDocument();
SCTAB nTab = aViewData.GetTabNo();
+ bool bSkipProtected = false, bSkipUnprotected = false;
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+ }
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return;
+
SCsCOL nOldX;
SCsROW nOldY;
SCsCOL nCurX;
@@ -965,7 +977,7 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
}
- BOOL bHidden;
+ BOOL bSkipCell = FALSE;
aViewData.ResetOldCursor();
if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
@@ -974,15 +986,20 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
do
{
BYTE nColFlags = pDoc->GetColFlags( nCurX, nTab );
- bHidden = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
- if (bHidden)
+ bSkipCell = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
+ if (bSkipProtected && !bSkipCell)
+ bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+ if (bSkipUnprotected && !bSkipCell)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
{
if ( nCurX<=0 || nCurX>=MAXCOL )
{
if (bHFlip)
{
nCurX = nOldX;
- bHidden = FALSE;
+ bSkipCell = FALSE;
}
else
{
@@ -995,7 +1012,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
if (nMovX > 0) ++nCurX; else --nCurX;
}
}
- while (bHidden);
+ while (bSkipCell);
+
if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
{
aViewData.SetOldCursor( nCurX,nCurY );
@@ -1010,15 +1028,20 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
do
{
BYTE nRowFlags = pDoc->GetRowFlags( nCurY, nTab );
- bHidden = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
- if (bHidden)
+ bSkipCell = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
+ if (bSkipProtected && !bSkipCell)
+ bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+ if (bSkipUnprotected && !bSkipCell)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
{
if ( nCurY<=0 || nCurY>=MAXROW )
{
if (bVFlip)
{
nCurY = nOldY;
- bHidden = FALSE;
+ bSkipCell = FALSE;
}
else
{
@@ -1031,7 +1054,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
if (nMovY > 0) ++nCurY; else --nCurY;
}
}
- while (bHidden);
+ while (bSkipCell);
+
if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
{
aViewData.SetOldCursor( nCurX,nCurY );
@@ -1571,6 +1595,10 @@ void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection )
ScDocument* pDoc = aViewData.GetDocument();
pDoc->MakeTable( nTab );
+ // Update pending row heights before switching the sheet, so Reschedule from the progress bar
+ // doesn't paint the new sheet with old heights
+ aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
+
SCTAB nTabCount = pDoc->GetTableCount();
SCTAB nOldPos = nTab;
while (!pDoc->IsVisible(nTab)) // naechste sichtbare suchen
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
index 7461d884c5b2..525ea1f14578 100644
--- a/sc/source/ui/view/tabvwsh3.cxx
+++ b/sc/source/ui/view/tabvwsh3.cxx
@@ -75,6 +75,8 @@
#include "autofmt.hxx"
#include "dwfunctr.hxx"
#include "shtabdlg.hxx"
+#include "tabprotection.hxx"
+#include "protectiondlg.hxx"
#include <svtools/ilstitem.hxx>
#define _SVSTDARR_ULONGS
@@ -85,6 +87,10 @@
#include <svx/dialogs.hrc> //CHINA001
#include "scabstdlg.hxx" //CHINA001
+#include <memory>
+
+using ::std::auto_ptr;
+
#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
#define IS_AVAILABLE(WhichId,ppItem) \
(pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
@@ -985,14 +991,6 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
}
break;
- case SID_STATUS_DOCPOS:
- {
- //! Navigator an-/ausschalten (wie im Writer) ???
- //!GetViewData()->GetDispatcher().Execute( SID_NAVIGATOR,
- //! SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
- }
- break;
-
case FID_PROTECT_DOC:
{
ScDocument* pDoc = GetViewData()->GetDocument();
@@ -1009,12 +1007,13 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
}
}
- if (pDoc->IsDocProtected())
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ if (pProtect && pProtect->isProtected())
{
BOOL bCancel = FALSE;
String aPassword;
- if (pDoc->GetDocPassword().getLength())
+ if (pProtect->isProtectedWithPass())
{
String aText( ScResId(SCSTR_PASSWORD) );
@@ -1064,89 +1063,164 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
case FID_PROTECT_TABLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bool bOldProtection = pDoc->IsTabProtected(nTab);
+
+#if ENABLE_SHEET_PROTECTION
+
+ if( pReqArgs )
{
- ScDocument* pDoc = GetViewData()->GetDocument();
- SCTAB nTab = GetViewData()->GetTabNo();
- SfxPasswordDialog* pDlg;
- String aPassword;
- BOOL bCancel = FALSE;
- BOOL bOldProtection = pDoc->IsTabProtected(nTab);
- BOOL bNewProtection = ! bOldProtection;
+ const SfxPoolItem* pItem;
+ bool bNewProtection = !bOldProtection;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
- if( pReqArgs )
+ if (bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
{
- const SfxPoolItem* pItem;
- if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
- bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
- if( bNewProtection == bOldProtection )
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ auto_ptr<SfxPasswordDialog> pDlg(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
{
- rReq.Ignore();
- break;
+ String aPassword = pDlg->GetPassword();
+ Unprotect(nTab, aPassword);
}
}
+ else
+ // this sheet is not password-protected.
+ Unprotect(nTab, String());
- if ( bOldProtection)
- {
- if (pDoc->GetTabPassword(nTab).getLength())
- {
- String aText( ScResId(SCSTR_PASSWORD) );
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // Protect a current sheet.
- pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
- pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
- pDlg->SetMinLen( 0 );
- pDlg->SetHelpId( FID_PROTECT_TABLE );
- pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+ auto_ptr<ScTableProtectionDlg> pDlg(new ScTableProtectionDlg(GetDialogParent()));
- if (pDlg->Execute() == RET_OK)
- aPassword = pDlg->GetPassword();
- else
- bCancel = TRUE;
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect)
+ pDlg->SetDialogData(*pProtect);
- delete pDlg;
- }
- }
- else
- {
- String aText( ScResId(SCSTR_PASSWORDOPT) );
+ if (pDlg->Execute() == RET_OK)
+ {
+ pScMod->InputEnterHandler();
- pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
- pDlg->SetText( ScResId(SCSTR_PROTECTTAB) );
- pDlg->SetMinLen( 0 );
- pDlg->SetHelpId( FID_PROTECT_TABLE );
- pDlg->SetEditHelpId( HID_PASSWD_TABLE );
- pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+ ScTableProtection aNewProtect;
+ pDlg->WriteData(aNewProtect);
+ ProtectSheet(nTab, aNewProtect);
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, true) );
+ rReq.Done();
+ }
+ }
+ }
+#else
+ auto_ptr<SfxPasswordDialog> pDlg;
+ String aPassword;
+ BOOL bCancel = FALSE;
+ bool bNewProtection = ! bOldProtection;
- if (pDlg->Execute() == RET_OK)
- aPassword = pDlg->GetPassword();
- else
- bCancel = TRUE;
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
- delete pDlg;
- }
+ if ( bOldProtection)
+ {
+ // Unprotect a protected sheet.
- if( !bCancel )
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
{
- if ( bOldProtection )
- Unprotect( nTab, aPassword );
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
else
- {
- pScMod->InputEnterHandler();
+ bCancel = TRUE;
+ }
- Protect( nTab, aPassword );
- }
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
- if( !pReqArgs )
- {
- rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
- rReq.Done();
- }
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_PROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = TRUE;
+ }
+
+ if( !bCancel )
+ {
+ if ( bOldProtection )
+ Unprotect( nTab, aPassword );
+ else
+ {
+ pScMod->InputEnterHandler();
+
+ Protect( nTab, aPassword );
}
- TabChanged();
- UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
- SelectionChanged();
+ if( !pReqArgs )
+ {
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
+ rReq.Done();
+ }
}
- break;
+#endif
+ TabChanged();
+ UpdateInputHandler(true); // damit sofort wieder eingegeben werden kann
+ SelectionChanged();
+ }
+ break;
case SID_OPT_LOCALE_CHANGED :
{ // locale changed, SYSTEM number formats changed => repaint cell contents
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
index 2b9ef68b1f8a..d8449ebc3699 100644
--- a/sc/source/ui/view/tabvwsh4.cxx
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -1190,6 +1190,10 @@ PrintDialog* __EXPORT ScTabViewShell::CreatePrintDialog( Window *pParent )
bool bAllTabs = SC_MOD()->GetPrintOptions().GetAllSheets();
pDlg->CheckSheetRange( bAllTabs ? PRINTSHEETS_ALL : PRINTSHEETS_SELECTED_SHEETS );
+ // update all pending row heights with a single progress bar,
+ // instead of a separate progress for each sheet from ScPrintFunc
+ pDocShell->UpdatePendingRowHeights( MAXTAB, true );
+
for ( SCTAB i=0; i<nTabCount; i++ )
{
ScPrintFunc aPrintFunc( pDocShell, pPrinter, i );
diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx
index 36c0c0694d18..92cf03cdf5d6 100644
--- a/sc/source/ui/view/tabvwsh5.cxx
+++ b/sc/source/ui/view/tabvwsh5.cxx
@@ -47,6 +47,7 @@
#include "tabvwsh.hxx"
#include "sc.hrc"
#include "global.hxx"
+#include "docsh.hxx"
#include "document.hxx"
#include "cell.hxx"
#include "globstr.hrc"
@@ -160,6 +161,10 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint
if (PaintExtras())
nParts = PAINT_ALL;
+ // if the current sheet has pending row height updates (sheet links refreshed),
+ // execute them before invalidating the window
+ GetViewData()->GetDocShell()->UpdatePendingRowHeights( GetViewData()->GetTabNo() );
+
if (nParts & PAINT_SIZE)
RepeatResize(); //! InvalidateBorder ???
if (nParts & PAINT_GRID)
diff --git a/sc/source/ui/view/tabvwshh.cxx b/sc/source/ui/view/tabvwshh.cxx
index 5c6ca6843833..7526a3de19bd 100644
--- a/sc/source/ui/view/tabvwshh.cxx
+++ b/sc/source/ui/view/tabvwshh.cxx
@@ -43,6 +43,7 @@
#include <sfx2/request.hxx>
#include <basic/sbxcore.hxx>
#include <svtools/whiter.hxx>
+#include <vcl/msgbox.hxx>
#include "tabvwsh.hxx"
#include "client.hxx"
@@ -50,6 +51,10 @@
#include "docsh.hxx"
#include "sc.hrc"
#include "drwlayer.hxx" // GetVisibleName
+#include "retypepassdlg.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
using namespace com::sun::star;
@@ -270,6 +275,22 @@ BOOL ScTabViewShell::HasAccessibilityObjects()
return pAccessibilityBroadcaster != NULL;
}
+bool ScTabViewShell::ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
+{
+ using ::std::auto_ptr;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ auto_ptr<ScRetypePassDlg> pDlg(new ScRetypePassDlg(GetDialogParent()));
+ pDlg->SetDataFromDocument(*pDoc);
+ pDlg->SetDesiredHash(eDesiredHash);
+ if (pDlg->Execute() != RET_OK)
+ return false;
+
+ pDlg->WriteNewDataToDocument(*pDoc);
+ return true;
+}
+
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index a7b2f634bd6c..50ede74ab06b 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -2197,7 +2197,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
if ( pDoc->IsTabProtected( nTab ) )
- pUndoDoc->SetTabProtection( nTab, TRUE, pDoc->GetTabPassword( nTab ) );
+ pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
// Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
// pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
@@ -2612,7 +2612,7 @@ void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy )
}
if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
- pDestDoc->SetTabProtection( nDestTab1, TRUE, pDoc->GetTabPassword( TheTabs[i] ) );
+ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
nDestTab1++;
}
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
index 57fef68c5f83..0f3a1c812802 100644
--- a/sc/source/ui/view/viewfun4.cxx
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -81,6 +81,9 @@
#include "impex.hxx"
#include "editutil.hxx"
#include "editable.hxx"
+#include "dociter.hxx"
+#include "reffind.hxx"
+#include "compiler.hxx"
using namespace com::sun::star;
@@ -187,7 +190,128 @@ void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
ShowAllCursors();
}
}
+void ScViewFunc::DoRefConversion( BOOL bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = FALSE;
+ ScRange aMarkRange;
+ rMark.MarkToSimple();
+ BOOL bMulti = rMark.IsMultiMarked();
+ if (bMulti)
+ rMark.GetMultiMarkArea( aMarkRange );
+ else if (rMark.IsMarked())
+ rMark.GetMarkArea( aMarkRange );
+ else
+ {
+ aMarkRange = ScRange( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ }
+ ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ BOOL bOk = FALSE;
+
+ ScDocument* pUndoDoc = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ pUndoDoc->AddUndoTab( i, i );
+ }
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pUndoDoc, &rMark );
+ }
+
+ ScRangeListRef xRanges;
+ GetViewData()->GetMultiArea( xRanges );
+ ULONG nCount = xRanges->Count();
+
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if (rMark.GetTableSelect(i))
+ {
+ for (ULONG j=0; j<nCount; j++)
+ {
+ ScRange aRange = *xRanges->GetObject(j);
+ aRange.aStart.SetTab(i);
+ aRange.aEnd.SetTab(i);
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ String aOld;
+ ((ScFormulaCell*)pCell)->GetFormula(aOld);
+ xub_StrLen nLen = aOld.Len();
+ ScRefFinder aFinder( aOld, pDoc );
+ aFinder.ToggleRel( 0, nLen );
+ if (aFinder.GetFound())
+ {
+ ScAddress aPos = ((ScFormulaCell*)pCell)->aPos;
+ String aNew = aFinder.GetText();
+ ScCompiler aComp( pDoc, aPos);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ ScTokenArray* pArr = aComp.CompileString( aNew );
+ ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aPos,
+ pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
+ pDoc->PutCell( aPos, pNewCell );
+ bOk = TRUE;
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+ }
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ pRedoDoc->AddUndoTab( i, i );
+ }
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pRedoDoc, &rMark );
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRefConversion( pDocSh,
+ aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, IDF_ALL) );
+ }
+
+ pDocSh->PostPaint( aMarkRange, PAINT_GRID );
+ pDocSh->UpdateOle(GetViewData());
+ pDocSh->SetDocumentModified();
+ CellContentChanged();
+
+ if (!bOk)
+ ErrorMessage(STR_ERR_NOREF);
+}
// Thesaurus - Undo ok
void ScViewFunc::DoThesaurus( BOOL bRecord )
{
@@ -537,11 +661,13 @@ BOOL ScViewFunc::PasteFile( const Point& rPos, const String& rFile, BOOL bLink )
SfxDispatcher &rDispatcher = GetViewData()->GetDispatcher();
SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL );
SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() );
+ // #i69524# add target, as in SfxApplication when the Open dialog is used
+ SfxStringItem aTargetItem( SID_TARGETNAME, String::CreateFromAscii("_default") );
// Asynchron oeffnen, kann naemlich auch aus D&D heraus passieren
// und das bekommt dem MAC nicht so gut ...
return BOOL( 0 != rDispatcher.Execute( SID_OPENDOC,
- SFX_CALLMODE_ASYNCHRON, &aFileNameItem, &aFilterItem, 0L) );
+ SFX_CALLMODE_ASYNCHRON, &aFileNameItem, &aFilterItem, &aTargetItem, 0L) );
}
}
diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx
index cb9d4eb0da72..ceb852354c7e 100644
--- a/sc/source/ui/view/viewfun6.cxx
+++ b/sc/source/ui/view/viewfun6.cxx
@@ -175,9 +175,11 @@ void ScViewFunc::EditNote()
// hide temporary note caption
HideNoteMarker();
// show caption object without changing internal visibility state
- pNote->ShowCaptionTemp();
+ pNote->ShowCaptionTemp( aPos );
- // drawing object has been created in ScDocument::GetOrCreateNote
+ /* Drawing object has been created in ScDocument::GetOrCreateNote() or
+ in ScPostIt::ShowCaptionTemp(), so ScPostIt::GetCaption() should
+ return a caption object. */
if( SdrCaptionObj* pCaption = pNote->GetCaption() )
{
// #i33764# enable the resize handles before starting edit mode
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 9df9dc5f5246..79343c31f85b 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -599,6 +599,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rS
}
else
{
+ DELETEZ(pUndoData);
ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
if ( nError )
{
@@ -751,12 +752,13 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextOb
ScPatternAttr* pCellAttrs = NULL;
EditTextObject* pNewData = NULL;
String aString;
+
+ const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
+ aEngine.SetText(*pData);
+
if (bTestSimple) // Testen, ob einfacher String ohne Attribute
{
- const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
- ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
- aEngine.SetText(*pData);
-
ScEditAttrTester aAttrTester( &aEngine );
bSimple = !aAttrTester.NeedsObject();
bCommon = aAttrTester.NeedsCellAttr();
@@ -777,11 +779,11 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextOb
pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
//! remove common attributes from EditEngine?
}
-
- if (bSimple)
- aString = aEngine.GetText();
}
+ // #i97726# always get text for "repeat" of undo action
+ aString = ScEditUtil::GetSpaceDelimitedString(aEngine);
+
//
// Undo
//
@@ -838,7 +840,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextOb
{ // wg. ChangeTrack erst jetzt
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nPos, pTabs,
- ppOldCells, NULL, NULL, String(),
+ ppOldCells, NULL, NULL, aString,
pUndoData ) );
}
@@ -924,7 +926,7 @@ void ScViewFunc::EnterMatrix( const String& rString )
if (pData->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
{
ScDocShell* pDocSh = pData->GetDocShell();
- BOOL bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, FALSE, FALSE,formula::FormulaGrammar::GRAM_DEFAULT );
+ BOOL bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, FALSE, FALSE, EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
if (bSuccess)
pDocSh->UpdateOle(GetViewData());
}
@@ -1179,103 +1181,69 @@ void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem
const SvxBoxInfoItem* pNewInner, BOOL bRecord )
{
ScDocument* pDoc = GetViewData()->GetDocument();
- ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = FALSE;
- SCCOL nStartCol;
- SCROW nStartRow;
- SCTAB nStartTab;
- SCCOL nEndCol;
- SCROW nEndRow;
- SCTAB nEndTab;
-
- ScMarkType eMarkType = GetViewData()->GetSimpleArea( nStartCol, nStartRow,
- nStartTab, nEndCol, nEndRow, nEndTab);
- if (eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED)
+ ScRange aMarkRange;
+ aFuncMark.MarkToSimple();
+ BOOL bMulti = aFuncMark.IsMultiMarked();
+ if (bMulti)
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ else if (aFuncMark.IsMarked())
+ aFuncMark.GetMarkArea( aMarkRange );
+ else
{
- bool bChangeSelection = false;
- ScRange aMarkRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
- if ( eMarkType == SC_MARK_SIMPLE_FILTERED )
- {
- ScMarkData aVisibleMark( rMark );
- ScViewUtil::UnmarkFiltered( aVisibleMark, pDoc );
- ScRangeList aRangeList;
- aVisibleMark.FillRangeListWithMarks( &aRangeList, FALSE );
- if ( aRangeList.Count() > 0 )
- {
- // use the first range of visible cells
- // (might also show an error message instead, or, later, allow multiple ranges)
-
- aMarkRange = *aRangeList.GetObject(0);
- }
- else // all hidden -> cursor position
- {
- aMarkRange.aStart.SetCol(GetViewData()->GetCurX());
- aMarkRange.aStart.SetRow(GetViewData()->GetCurY());
- aMarkRange.aStart.SetTab(GetViewData()->GetTabNo());
- aMarkRange.aEnd = aMarkRange.aStart;
- }
- aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
- bChangeSelection = true; // change the selection to only the affected cells
- }
-
- rMark.MarkToSimple(); // not done by GetSimpleArea anymore
+ aMarkRange = ScRange( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ DoneBlockMode();
+ InitOwnBlockMode();
+ aFuncMark.SetMarkArea(aMarkRange);
+ MarkDataChanged();
+ }
- ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
- ScDocShellModificator aModificator( *pDocSh );
+ ScDocShellModificator aModificator( *pDocSh );
- if (!rMark.IsMarked() || bChangeSelection)
- {
- DoneBlockMode();
- InitOwnBlockMode();
- rMark.SetMarkArea( ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
- MarkDataChanged();
- }
+ if (bRecord)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
- if (bRecord)
- {
- SCTAB nTabCount = pDoc->GetTableCount();
- ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
- pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
- for (SCTAB i=0; i<nTabCount; i++)
- if (i != nStartTab && rMark.GetTableSelect(i))
- pUndoDoc->AddUndoTab( i, i );
- pDoc->CopyToDocument( nStartCol, nStartRow, 0, nEndCol, nEndRow, nTabCount-1,
- IDF_ATTRIB, FALSE, pUndoDoc );
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &aFuncMark );
- pDocSh->GetUndoManager()->AddUndoAction(
- new ScUndoSelectionAttr( pDocSh, rMark,
- nStartCol, nStartRow, nStartTab,
- nEndCol, nEndRow, nEndTab,
- pUndoDoc, FALSE, &rAttr, pNewOuter, pNewInner ) );
- }
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionAttr(
+ pDocSh, aFuncMark,
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
+ pUndoDoc, bMulti, &rAttr, pNewOuter, pNewInner ) );
+ }
- USHORT nExt = SC_PF_TESTMERGE;
- pDocSh->UpdatePaintExt( nExt, nStartCol, nStartRow, nStartTab,
- nEndCol, nEndRow, nEndTab ); // content before the change
+ USHORT nExt = SC_PF_TESTMERGE;
+ pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content before the change
- pDoc->ApplySelectionFrame( rMark, pNewOuter, pNewInner );
+ pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner );
- pDocSh->UpdatePaintExt( nExt, nStartCol, nStartRow, nStartTab,
- nEndCol, nEndRow, nEndTab ); // content after the change
+ pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change
- rMark.MarkToMulti();
- pDoc->ApplySelectionPattern( rAttr, rMark );
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionPattern( rAttr, aFuncMark );
- pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
- nEndCol, nEndRow, nEndTab,
- PAINT_GRID, nExt );
- pDocSh->UpdateOle(GetViewData());
- aModificator.SetDocumentModified();
- CellContentChanged();
- rMark.MarkToSimple();
- }
- else
- { // "Rahmen nicht auf Mehrfachselektion"
- ErrorMessage(STR_MSSG_APPLYPATTLINES_0);
- }
+ pDocSh->PostPaint( aMarkRange, PAINT_GRID, nExt );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
StartFormatArea();
}
@@ -2215,6 +2183,7 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR
const SCCOLROW* pTabRanges = pRanges;
pDoc->IncSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+ pDoc->InitializeNoteCaptions( nTab );
for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
{
SCCOLROW nStartNo = *(pTabRanges++);
@@ -2580,6 +2549,36 @@ void ScViewFunc::ModifyCellSize( ScDirection eDir, BOOL bOptimal )
ShowAllCursors();
}
+void ScViewFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
+{
+ if (nTab == TABLEID_DOC)
+ return;
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ bool bUndo(pDoc->IsUndoEnabled());
+
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ aFunc.ProtectSheet(i, rProtect);
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ UpdateLayerLocks(); //! broadcast to all views
+}
+
void ScViewFunc::Protect( SCTAB nTab, const String& rPassword )
{
ScMarkData& rMark = GetViewData()->GetMarkData();
diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk
index fe2bf6bc636d..3fc0712cd996 100644
--- a/sc/util/makefile.mk
+++ b/sc/util/makefile.mk
@@ -85,6 +85,7 @@ SHL1STDLIBS= \
$(SVXLIB) \
$(GOODIESLIB) \
$(BASEGFXLIB) \
+ $(DRAWINGLAYERLIB) \
$(VCLLIB) \
$(CPPULIB) \
$(CPPUHELPERLIB) \
@@ -189,6 +190,7 @@ SHL6STDLIBS= \
$(SVLLIB) \
$(SVXLIB) \
$(BASEGFXLIB) \
+ $(DRAWINGLAYERLIB) \
$(VCLLIB) \
$(CPPULIB) \
$(CPPUHELPERLIB) \
diff --git a/scaddins/prj/build.lst b/scaddins/prj/build.lst
index fd2fc4e80ccc..c2ade63c0b5d 100644
--- a/scaddins/prj/build.lst
+++ b/scaddins/prj/build.lst
@@ -1,4 +1,4 @@
-ca scaddins : vcl NULL
+ca scaddins : l10n vcl NULL
ca scaddins usr1 - all sc_mkout NULL
ca scaddins\source\datefunc nmake - all sc_dfunc NULL
ca scaddins\source\analysis nmake - all sc_analysis NULL
diff --git a/sccomp/prj/build.lst b/sccomp/prj/build.lst
index e2b7202ce7bf..8e1e0d0181cb 100644
--- a/sccomp/prj/build.lst
+++ b/sccomp/prj/build.lst
@@ -1,4 +1,4 @@
-scc sccomp : offuh comphelper LPSOLVE:lpsolve tools transex3 rsc NULL
+scc sccomp : l10n offuh comphelper LPSOLVE:lpsolve tools rsc NULL
scc sccomp usr1 - all scc_mkout NULL
scc sccomp\prj get - all scc_prj NULL
scc sccomp\source\solver nmake - all scc_solver NULL